^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* dir.c: AFS filesystem directory handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2002, 2018 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/swap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/task_io_accounting_ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "afs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xdr_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) unsigned int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static int afs_dir_open(struct inode *inode, struct file *file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static int afs_readdir(struct file *file, struct dir_context *ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static int afs_d_revalidate(struct dentry *dentry, unsigned int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static int afs_d_delete(const struct dentry *dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static void afs_d_iput(struct dentry *dentry, struct inode *inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name, int nlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) loff_t fpos, u64 ino, unsigned dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int afs_lookup_filldir(struct dir_context *ctx, const char *name, int nlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) loff_t fpos, u64 ino, unsigned dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) bool excl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static int afs_rmdir(struct inode *dir, struct dentry *dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static int afs_unlink(struct inode *dir, struct dentry *dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int afs_link(struct dentry *from, struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct dentry *dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int afs_symlink(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) const char *content);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct inode *new_dir, struct dentry *new_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) unsigned int flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static int afs_dir_releasepage(struct page *page, gfp_t gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static void afs_dir_invalidatepage(struct page *page, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned int length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int afs_dir_set_page_dirty(struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) BUG(); /* This should never happen. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) const struct file_operations afs_dir_file_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .open = afs_dir_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .release = afs_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .iterate_shared = afs_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .lock = afs_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) const struct inode_operations afs_dir_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .create = afs_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .lookup = afs_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .link = afs_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .unlink = afs_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .symlink = afs_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .mkdir = afs_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .rmdir = afs_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .rename = afs_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .permission = afs_permission,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .getattr = afs_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .setattr = afs_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) const struct address_space_operations afs_dir_aops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .set_page_dirty = afs_dir_set_page_dirty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .releasepage = afs_dir_releasepage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .invalidatepage = afs_dir_invalidatepage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) const struct dentry_operations afs_fs_dentry_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .d_revalidate = afs_d_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .d_delete = afs_d_delete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .d_release = afs_d_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .d_automount = afs_d_automount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .d_iput = afs_d_iput,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct afs_lookup_one_cookie {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct dir_context ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct qstr name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) bool found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct afs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct afs_lookup_cookie {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct dir_context ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct qstr name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) bool found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) bool one_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) unsigned short nr_fids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct afs_fid fids[50];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * check that a directory page is valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static bool afs_dir_check_page(struct afs_vnode *dvnode, struct page *page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) loff_t i_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct afs_xdr_dir_page *dbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) loff_t latter, off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) int tmp, qty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Determine how many magic numbers there should be in this page, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * we must take care because the directory may change size under us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) off = page_offset(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (i_size <= off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) goto checked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) latter = i_size - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (latter >= PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) qty = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) qty = latter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) qty /= sizeof(union afs_xdr_dir_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* check them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dbuf = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) for (tmp = 0; tmp < qty; tmp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (dbuf->blocks[tmp].hdr.magic != AFS_DIR_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) printk("kAFS: %s(%lx): bad magic %d/%d is %04hx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) __func__, dvnode->vfs_inode.i_ino, tmp, qty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ntohs(dbuf->blocks[tmp].hdr.magic));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) trace_afs_dir_check_failed(dvnode, off, i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) trace_afs_file_error(dvnode, -EIO, afs_file_error_dir_bad_magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* Make sure each block is NUL terminated so we can reasonably
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * use string functions on it. The filenames in the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * *should* be NUL-terminated anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ((u8 *)&dbuf->blocks[tmp])[AFS_DIR_BLOCK_SIZE - 1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) checked:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) afs_stat_v(dvnode, n_read_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * Check the contents of a directory that we've just read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static bool afs_dir_check_pages(struct afs_vnode *dvnode, struct afs_read *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct afs_xdr_dir_page *dbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned int i, j, qty = PAGE_SIZE / sizeof(union afs_xdr_dir_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) for (i = 0; i < req->nr_pages; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (!afs_dir_check_page(dvnode, req->pages[i], req->actual_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) pr_warn("DIR %llx:%llx f=%llx l=%llx al=%llx r=%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) dvnode->fid.vid, dvnode->fid.vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) req->file_size, req->len, req->actual_len, req->remain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pr_warn("DIR %llx %x %x %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) req->pos, req->index, req->nr_pages, req->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) for (i = 0; i < req->nr_pages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) dbuf = kmap(req->pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) for (j = 0; j < qty; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) union afs_xdr_dir_block *block = &dbuf->blocks[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) pr_warn("[%02x] %32phN\n", i * qty + j, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) kunmap(req->pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * open an AFS directory file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int afs_dir_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) _enter("{%lu}", inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) BUILD_BUG_ON(sizeof(union afs_xdr_dirent) != 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(inode)->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return afs_open(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Read the directory into the pagecache in one go, scrubbing the previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * contents. The list of pages is returned, pinning them so that they don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * get reclaimed during the iteration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static struct afs_read *afs_read_dir(struct afs_vnode *dvnode, struct key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) __acquires(&dvnode->validate_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct afs_read *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) loff_t i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int nr_pages, nr_inline, i, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) i_size = i_size_read(&dvnode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (i_size < 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return ERR_PTR(afs_bad(dvnode, afs_file_error_dir_small));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (i_size > 2048 * 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) trace_afs_file_error(dvnode, -EFBIG, afs_file_error_dir_big);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return ERR_PTR(-EFBIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) _enter("%llu", i_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* Get a request record to hold the page list. We want to hold it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * inline if we can, but we don't want to make an order 1 allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) nr_pages = (i_size + PAGE_SIZE - 1) / PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) nr_inline = nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (nr_inline > (PAGE_SIZE - sizeof(*req)) / sizeof(struct page *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) nr_inline = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) req = kzalloc(struct_size(req, array, nr_inline), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) refcount_set(&req->usage, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) req->nr_pages = nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) req->actual_len = i_size; /* May change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) req->len = nr_pages * PAGE_SIZE; /* We can ask for more than there is */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) req->data_version = dvnode->status.data_version; /* May change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (nr_inline > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) req->pages = req->array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) req->pages = kcalloc(nr_pages, sizeof(struct page *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (!req->pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* Get a list of all the pages that hold or will hold the directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * content. We need to fill in any gaps that we might find where the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * memory reclaimer has been at work. If there are any gaps, we will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * need to reread the entire directory contents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) n = find_get_pages_contig(dvnode->vfs_inode.i_mapping, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) req->nr_pages - i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) req->pages + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) _debug("find %u at %u/%u", n, i, req->nr_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (n == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) gfp_t gfp = dvnode->vfs_inode.i_mapping->gfp_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) afs_stat_v(dvnode, n_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) req->pages[i] = __page_cache_alloc(gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (!req->pages[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ret = add_to_page_cache_lru(req->pages[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) dvnode->vfs_inode.i_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) i, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) attach_page_private(req->pages[i], (void *)1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) unlock_page(req->pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) i += n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) } while (i < req->nr_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* If we're going to reload, we need to lock all the pages to prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * races.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) ret = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (down_read_killable(&dvnode->validate_lock) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) goto success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) up_read(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (down_write_killable(&dvnode->validate_lock) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) trace_afs_reload_dir(dvnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ret = afs_fetch_data(dvnode, key, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) goto error_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) task_io_account_read(PAGE_SIZE * req->nr_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (req->len < req->file_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) goto content_has_grown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* Validate the data we just read. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (!afs_dir_check_pages(dvnode, req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) goto error_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) // TODO: Trim excess pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) set_bit(AFS_VNODE_DIR_VALID, &dvnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) downgrade_write(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) success:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) error_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) up_write(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) afs_put_read(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) _leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) content_has_grown:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) up_write(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) afs_put_read(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * deal with one block in an AFS directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int afs_dir_iterate_block(struct afs_vnode *dvnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct dir_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) union afs_xdr_dir_block *block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) unsigned blkoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) union afs_xdr_dirent *dire;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) unsigned offset, next, curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) size_t nlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) _enter("%u,%x,%p,,",(unsigned)ctx->pos,blkoff,block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) curr = (ctx->pos - blkoff) / sizeof(union afs_xdr_dirent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* walk through the block, an entry at a time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) for (offset = (blkoff == 0 ? AFS_DIR_RESV_BLOCKS0 : AFS_DIR_RESV_BLOCKS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) offset < AFS_DIR_SLOTS_PER_BLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) offset = next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) next = offset + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* skip entries marked unused in the bitmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (!(block->hdr.bitmap[offset / 8] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) (1 << (offset % 8)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) _debug("ENT[%zu.%u]: unused",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) blkoff / sizeof(union afs_xdr_dir_block), offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (offset >= curr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ctx->pos = blkoff +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) next * sizeof(union afs_xdr_dirent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* got a valid entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) dire = &block->dirents[offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) nlen = strnlen(dire->u.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) sizeof(*block) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) offset * sizeof(union afs_xdr_dirent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) _debug("ENT[%zu.%u]: %s %zu \"%s\"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) blkoff / sizeof(union afs_xdr_dir_block), offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) (offset < curr ? "skip" : "fill"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) nlen, dire->u.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* work out where the next possible entry is */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) for (tmp = nlen; tmp > 15; tmp -= sizeof(union afs_xdr_dirent)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (next >= AFS_DIR_SLOTS_PER_BLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) _debug("ENT[%zu.%u]:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) " %u travelled beyond end dir block"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) " (len %u/%zu)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) blkoff / sizeof(union afs_xdr_dir_block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) offset, next, tmp, nlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return afs_bad(dvnode, afs_file_error_dir_over_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (!(block->hdr.bitmap[next / 8] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) (1 << (next % 8)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) _debug("ENT[%zu.%u]:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) " %u unmarked extension (len %u/%zu)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) blkoff / sizeof(union afs_xdr_dir_block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) offset, next, tmp, nlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return afs_bad(dvnode, afs_file_error_dir_unmarked_ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) _debug("ENT[%zu.%u]: ext %u/%zu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) blkoff / sizeof(union afs_xdr_dir_block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) next, tmp, nlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) next++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* skip if starts before the current position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (offset < curr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* found the next entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (!dir_emit(ctx, dire->u.name, nlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ntohl(dire->u.vnode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) (ctx->actor == afs_lookup_filldir ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ctx->actor == afs_lookup_one_filldir)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ntohl(dire->u.unique) : DT_UNKNOWN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) _leave(" = 0 [full]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ctx->pos = blkoff + next * sizeof(union afs_xdr_dirent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) _leave(" = 1 [more]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * iterate through the data blob that lists the contents of an AFS directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static int afs_dir_iterate(struct inode *dir, struct dir_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct key *key, afs_dataversion_t *_dir_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct afs_vnode *dvnode = AFS_FS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct afs_xdr_dir_page *dbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) union afs_xdr_dir_block *dblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct afs_read *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) unsigned blkoff, limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) _enter("{%lu},%u,,", dir->i_ino, (unsigned)ctx->pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dir)->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) _leave(" = -ESTALE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return -ESTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) req = afs_read_dir(dvnode, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (IS_ERR(req))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return PTR_ERR(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) *_dir_version = req->data_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /* round the file position up to the next entry boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ctx->pos += sizeof(union afs_xdr_dirent) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ctx->pos &= ~(sizeof(union afs_xdr_dirent) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /* walk through the blocks in sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) while (ctx->pos < req->actual_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) blkoff = ctx->pos & ~(sizeof(union afs_xdr_dir_block) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /* Fetch the appropriate page from the directory and re-add it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * to the LRU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) page = req->pages[blkoff / PAGE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (!page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = afs_bad(dvnode, afs_file_error_dir_missing_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) mark_page_accessed(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) limit = blkoff & ~(PAGE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) dbuf = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* deal with the individual blocks stashed on this page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) sizeof(union afs_xdr_dir_block)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ret = afs_dir_iterate_block(dvnode, ctx, dblock, blkoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (ret != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) blkoff += sizeof(union afs_xdr_dir_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) } while (ctx->pos < dir->i_size && blkoff < limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) up_read(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) afs_put_read(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) _leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * read an AFS directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int afs_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) afs_dataversion_t dir_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return afs_dir_iterate(file_inode(file), ctx, afs_file_key(file),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) &dir_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * Search the directory for a single name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * - if afs_dir_iterate_block() spots this function, it'll pass the FID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * uniquifier through dtype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static int afs_lookup_one_filldir(struct dir_context *ctx, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int nlen, loff_t fpos, u64 ino, unsigned dtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct afs_lookup_one_cookie *cookie =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) container_of(ctx, struct afs_lookup_one_cookie, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) _enter("{%s,%u},%s,%u,,%llu,%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) cookie->name.name, cookie->name.len, name, nlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) (unsigned long long) ino, dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* insanity checks first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) BUILD_BUG_ON(sizeof(union afs_xdr_dirent) != 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (cookie->name.len != nlen ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) memcmp(cookie->name.name, name, nlen) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) _leave(" = 0 [no]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) cookie->fid.vnode = ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) cookie->fid.unique = dtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) cookie->found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) _leave(" = -1 [found]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * Do a lookup of a single name in a directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * - just returns the FID the dentry name maps to if found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static int afs_do_lookup_one(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct afs_fid *fid, struct key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) afs_dataversion_t *_dir_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct afs_super_info *as = dir->i_sb->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct afs_lookup_one_cookie cookie = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .ctx.actor = afs_lookup_one_filldir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .name = dentry->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .fid.vid = as->volume->vid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /* search the directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ret = afs_dir_iterate(dir, &cookie.ctx, key, _dir_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) _leave(" = %d [iter]", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (!cookie.found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) _leave(" = -ENOENT [not found]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) *fid = cookie.fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) _leave(" = 0 { vn=%llu u=%u }", fid->vnode, fid->unique);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * search the directory for a name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * - if afs_dir_iterate_block() spots this function, it'll pass the FID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * uniquifier through dtype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static int afs_lookup_filldir(struct dir_context *ctx, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) int nlen, loff_t fpos, u64 ino, unsigned dtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct afs_lookup_cookie *cookie =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) container_of(ctx, struct afs_lookup_cookie, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) _enter("{%s,%u},%s,%u,,%llu,%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) cookie->name.name, cookie->name.len, name, nlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) (unsigned long long) ino, dtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* insanity checks first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) BUILD_BUG_ON(sizeof(union afs_xdr_dir_block) != 2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) BUILD_BUG_ON(sizeof(union afs_xdr_dirent) != 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (cookie->found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (cookie->nr_fids < 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) cookie->fids[cookie->nr_fids].vnode = ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) cookie->fids[cookie->nr_fids].unique = dtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) cookie->nr_fids++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) } else if (cookie->name.len == nlen &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) memcmp(cookie->name.name, name, nlen) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) cookie->fids[1].vnode = ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) cookie->fids[1].unique = dtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) cookie->found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (cookie->one_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) ret = cookie->nr_fids >= 50 ? -1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) _leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * Deal with the result of a successful lookup operation. Turn all the files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * into inodes and save the first one - which is the one we actually want.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static void afs_do_lookup_success(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct afs_vnode_param *vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct afs_vnode *vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) u32 abort_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) for (i = 0; i < op->nr_files; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) vp = &op->file[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) abort_code = vp->scb.status.abort_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (abort_code != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) op->ac.abort_code = abort_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) op->error = afs_abort_to_error(abort_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) vp = &op->file[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) vp = &op->more_files[i - 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (!vp->scb.have_status && !vp->scb.have_error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) _debug("do [%u]", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (vp->vnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (!test_bit(AFS_VNODE_UNSET, &vp->vnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) afs_vnode_commit_status(op, vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) } else if (vp->scb.status.abort_code == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) inode = afs_iget(op, vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (!IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) vnode = AFS_FS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) afs_cache_permit(vnode, op->key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 0 /* Assume vnode->cb_break is 0 */ +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) op->cb_v_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) &vp->scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) vp->vnode = vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) vp->put_vnode = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) _debug("- abort %d %llx:%llx.%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) vp->scb.status.abort_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) vp->fid.vid, vp->fid.vnode, vp->fid.unique);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static const struct afs_operation_ops afs_inline_bulk_status_operation = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) .issue_afs_rpc = afs_fs_inline_bulk_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) .issue_yfs_rpc = yfs_fs_inline_bulk_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) .success = afs_do_lookup_success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static const struct afs_operation_ops afs_lookup_fetch_status_operation = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) .issue_afs_rpc = afs_fs_fetch_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) .issue_yfs_rpc = yfs_fs_fetch_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) .success = afs_do_lookup_success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) .aborted = afs_check_for_remote_deletion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * See if we know that the server we expect to use doesn't support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * FS.InlineBulkStatus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static bool afs_server_supports_ibulk(struct afs_vnode *dvnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct afs_server_list *slist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct afs_volume *volume = dvnode->volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct afs_server *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) bool ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (!test_bit(AFS_VOLUME_MAYBE_NO_IBULK, &volume->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) slist = rcu_dereference(volume->servers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) for (i = 0; i < slist->nr_servers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) server = slist->servers[i].server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (server == dvnode->cb_server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (test_bit(AFS_SERVER_FL_NO_IBULK, &server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * Do a lookup in a directory. We make use of bulk lookup to query a slew of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * files in one go and create inodes for them. The inode of the file we were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * asked for is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct afs_lookup_cookie *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) struct afs_vnode_param *vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct afs_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct inode *inode = NULL, *ti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) afs_dataversion_t data_version = READ_ONCE(dvnode->status.data_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) cookie = kzalloc(sizeof(struct afs_lookup_cookie), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (!cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) for (i = 0; i < ARRAY_SIZE(cookie->fids); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) cookie->fids[i].vid = dvnode->fid.vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) cookie->ctx.actor = afs_lookup_filldir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) cookie->name = dentry->d_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) cookie->nr_fids = 2; /* slot 0 is saved for the fid we actually want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * and slot 1 for the directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (!afs_server_supports_ibulk(dvnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) cookie->one_only = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* search the directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ret = afs_dir_iterate(dir, &cookie->ctx, key, &data_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) dentry->d_fsdata = (void *)(unsigned long)data_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (!cookie->found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) /* Check to see if we already have an inode for the primary fid. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) inode = ilookup5(dir->i_sb, cookie->fids[1].vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) afs_ilookup5_test_by_fid, &cookie->fids[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) goto out; /* We do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /* Okay, we didn't find it. We need to query the server - and whilst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * we're doing that, we're going to attempt to look up a bunch of other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * vnodes also.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) op = afs_alloc_operation(NULL, dvnode->volume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (IS_ERR(op)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) ret = PTR_ERR(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) afs_op_set_vnode(op, 0, dvnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) afs_op_set_fid(op, 1, &cookie->fids[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) op->nr_files = cookie->nr_fids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) _debug("nr_files %u", op->nr_files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /* Need space for examining all the selected files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) op->error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (op->nr_files > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) op->more_files = kvcalloc(op->nr_files - 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) sizeof(struct afs_vnode_param),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (!op->more_files)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) goto out_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) for (i = 2; i < op->nr_files; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) vp = &op->more_files[i - 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) vp->fid = cookie->fids[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* Find any inodes that already exist and get their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * callback counters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) ti = ilookup5_nowait(dir->i_sb, vp->fid.vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) afs_ilookup5_test_by_fid, &vp->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (!IS_ERR_OR_NULL(ti)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) vnode = AFS_FS_I(ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) vp->dv_before = vnode->status.data_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) vp->cb_break_before = afs_calc_vnode_cb_break(vnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) vp->vnode = vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) vp->put_vnode = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) vp->speculative = true; /* vnode not locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /* Try FS.InlineBulkStatus first. Abort codes for the individual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * lookups contained therein are stored in the reply without aborting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * the whole operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) op->error = -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (!cookie->one_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) op->ops = &afs_inline_bulk_status_operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) afs_begin_vnode_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) afs_wait_for_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (op->error == -ENOTSUPP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) /* We could try FS.BulkStatus next, but this aborts the entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * op if any of the lookups fails - so, for the moment, revert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * to FS.FetchStatus for op->file[1].
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) op->fetch_status.which = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) op->ops = &afs_lookup_fetch_status_operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) afs_begin_vnode_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) afs_wait_for_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) inode = ERR_PTR(op->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) out_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (op->error == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) inode = &op->file[1].vnode->vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) op->file[1].vnode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (op->file[0].scb.have_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) dentry->d_fsdata = (void *)(unsigned long)op->file[0].scb.status.data_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) dentry->d_fsdata = (void *)(unsigned long)op->file[0].dv_before;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) ret = afs_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) kfree(cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return inode ?: ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * Look up an entry in a directory with @sys substitution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static struct dentry *afs_lookup_atsys(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct afs_sysnames *subs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct afs_net *net = afs_i2net(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct dentry *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) char *buf, *p, *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) int len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ret = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) p = buf = kmalloc(AFSNAMEMAX, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) goto out_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (dentry->d_name.len > 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) memcpy(p, dentry->d_name.name, dentry->d_name.len - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) p += dentry->d_name.len - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) /* There is an ordered list of substitutes that we have to try. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) read_lock(&net->sysnames_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) subs = net->sysnames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) refcount_inc(&subs->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) read_unlock(&net->sysnames_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) for (i = 0; i < subs->nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) name = subs->subs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) len = dentry->d_name.len - 4 + strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (len >= AFSNAMEMAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) ret = ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) goto out_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) strcpy(p, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) ret = lookup_one_len(buf, dentry->d_parent, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (IS_ERR(ret) || d_is_positive(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) goto out_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) dput(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /* We don't want to d_add() the @sys dentry here as we don't want to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * the cached dentry to hide changes to the sysnames list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) out_s:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) afs_put_sysnames(subs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) out_p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) key_put(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * look up an entry in a directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct afs_vnode *dvnode = AFS_FS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) struct afs_fid fid = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct dentry *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) struct key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) _enter("{%llx:%llu},%p{%pd},",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) dvnode->fid.vid, dvnode->fid.vnode, dentry, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) ASSERTCMP(d_inode(dentry), ==, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (dentry->d_name.len >= AFSNAMEMAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) _leave(" = -ENAMETOOLONG");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (test_bit(AFS_VNODE_DELETED, &dvnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) _leave(" = -ESTALE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return ERR_PTR(-ESTALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) key = afs_request_key(dvnode->volume->cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (IS_ERR(key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) _leave(" = %ld [key]", PTR_ERR(key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return ERR_CAST(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ret = afs_validate(dvnode, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) key_put(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) _leave(" = %d [val]", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (dentry->d_name.len >= 4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) dentry->d_name.name[dentry->d_name.len - 4] == '@' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) dentry->d_name.name[dentry->d_name.len - 3] == 's' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) dentry->d_name.name[dentry->d_name.len - 2] == 'y' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) dentry->d_name.name[dentry->d_name.len - 1] == 's')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return afs_lookup_atsys(dir, dentry, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) afs_stat_v(dvnode, n_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) inode = afs_do_lookup(dir, dentry, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) key_put(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (inode == ERR_PTR(-ENOENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) inode = afs_try_auto_mntpt(dentry, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (!IS_ERR_OR_NULL(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) fid = AFS_FS_I(inode)->fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) _debug("splice %p", dentry->d_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) d = d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (!IS_ERR_OR_NULL(d)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) d->d_fsdata = dentry->d_fsdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) trace_afs_lookup(dvnode, &d->d_name, &fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) trace_afs_lookup(dvnode, &dentry->d_name, &fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) _leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * Check the validity of a dentry under RCU conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static int afs_d_revalidate_rcu(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct afs_vnode *dvnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct dentry *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct inode *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) long dir_version, de_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) _enter("%p", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /* Check the parent directory is still valid first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) parent = READ_ONCE(dentry->d_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) dir = d_inode_rcu(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (!dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) dvnode = AFS_FS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (test_bit(AFS_VNODE_DELETED, &dvnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (!afs_check_validity(dvnode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* We only need to invalidate a dentry if the server's copy changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * behind our back. If we made the change, it's no problem. Note that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * on a 32-bit system, we only have 32 bits in the dentry to store the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) dir_version = (long)READ_ONCE(dvnode->status.data_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) de_version = (long)READ_ONCE(dentry->d_fsdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (de_version != dir_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) dir_version = (long)READ_ONCE(dvnode->invalid_before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (de_version - dir_version < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return 1; /* Still valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * check that a dentry lookup hit has found a valid entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * - NOTE! the hit can be a negative hit too, so we can't assume we have an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static int afs_d_revalidate(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct afs_vnode *vnode, *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct afs_fid fid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct dentry *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) struct key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) afs_dataversion_t dir_version, invalid_before;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) long de_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return afs_d_revalidate_rcu(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (d_really_is_positive(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) vnode = AFS_FS_I(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) _enter("{v={%llx:%llu} n=%pd fl=%lx},",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) vnode->fid.vid, vnode->fid.vnode, dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) _enter("{neg n=%pd}", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) key = afs_request_key(AFS_FS_S(dentry->d_sb)->volume->cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (IS_ERR(key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) /* Hold the parent dentry so we can peer at it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) parent = dget_parent(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) dir = AFS_FS_I(d_inode(parent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) /* validate the parent directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) afs_validate(dir, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (test_bit(AFS_VNODE_DELETED, &dir->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) _debug("%pd: parent dir deleted", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /* We only need to invalidate a dentry if the server's copy changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * behind our back. If we made the change, it's no problem. Note that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * on a 32-bit system, we only have 32 bits in the dentry to store the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) dir_version = dir->status.data_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) de_version = (long)dentry->d_fsdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) if (de_version == (long)dir_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) goto out_valid_noupdate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) invalid_before = dir->invalid_before;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (de_version - (long)invalid_before >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) goto out_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) _debug("dir modified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) afs_stat_v(dir, n_reval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /* search the directory for this vnode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) ret = afs_do_lookup_one(&dir->vfs_inode, dentry, &fid, key, &dir_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) /* the filename maps to something */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (d_really_is_negative(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (is_bad_inode(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) printk("kAFS: afs_d_revalidate: %pd2 has bad inode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) vnode = AFS_FS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* if the vnode ID has changed, then the dirent points to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * different file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (fid.vnode != vnode->fid.vnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) _debug("%pd: dirent changed [%llu != %llu]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) dentry, fid.vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) vnode->fid.vnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) /* if the vnode ID uniqifier has changed, then the file has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * been deleted and replaced, and the original vnode ID has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * been reused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (fid.unique != vnode->fid.unique) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) _debug("%pd: file deleted (uq %u -> %u I:%u)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) dentry, fid.unique,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) vnode->fid.unique,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) vnode->vfs_inode.i_generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) goto out_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /* the filename is unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) _debug("%pd: dirent not found", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (d_really_is_positive(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) goto out_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) _debug("failed to iterate dir %pd: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) parent, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) goto not_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) out_valid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) dentry->d_fsdata = (void *)(unsigned long)dir_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) out_valid_noupdate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) dput(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) key_put(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) _leave(" = 1 [valid]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) not_found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) _debug("dropping dentry %pd2", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) dput(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) key_put(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) _leave(" = 0 [bad]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) * allow the VFS to enquire as to whether a dentry should be unhashed (mustn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) * sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) * - called from dput() when d_count is going to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) * - return 1 to request dentry be unhashed, 0 otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) static int afs_d_delete(const struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) _enter("%pd", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) goto zap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (d_really_is_positive(dentry) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(d_inode(dentry))->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) test_bit(AFS_VNODE_PSEUDODIR, &AFS_FS_I(d_inode(dentry))->flags)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) goto zap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) _leave(" = 0 [keep]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) zap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) _leave(" = 1 [zap]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) * Clean up sillyrename files on dentry removal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) static void afs_d_iput(struct dentry *dentry, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) afs_silly_iput(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * handle dentry release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) void afs_d_release(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) _enter("%pd", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) void afs_check_for_remote_deletion(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) struct afs_vnode *vnode = op->file[0].vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) switch (op->ac.abort_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) case VNOVNODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) set_bit(AFS_VNODE_DELETED, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) afs_break_callback(vnode, afs_cb_break_for_deleted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) * Create a new inode for create/mkdir/symlink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static void afs_vnode_new_inode(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct afs_vnode_param *vp = &op->file[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) struct afs_vnode *vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) _enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) ASSERTCMP(op->error, ==, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) inode = afs_iget(op, vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) /* ENOMEM or EINTR at a really inconvenient time - just abandon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) * the new directory on the server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) op->error = PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) vnode = AFS_FS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (!op->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) afs_cache_permit(vnode, op->key, vnode->cb_break, &vp->scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) d_instantiate(op->dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static void afs_create_success(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) op->ctime = op->file[0].scb.status.mtime_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) afs_vnode_commit_status(op, &op->file[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) afs_update_dentry_version(op, &op->file[0], op->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) afs_vnode_new_inode(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) static void afs_create_edit_dir(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) struct afs_vnode_param *dvp = &op->file[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) struct afs_vnode_param *vp = &op->file[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) struct afs_vnode *dvnode = dvp->vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) down_write(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) dvnode->status.data_version == dvp->dv_before + dvp->dv_delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) afs_edit_dir_add(dvnode, &op->dentry->d_name, &vp->fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) op->create.reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) up_write(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) static void afs_create_put(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (op->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) d_drop(op->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static const struct afs_operation_ops afs_mkdir_operation = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) .issue_afs_rpc = afs_fs_make_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) .issue_yfs_rpc = yfs_fs_make_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) .success = afs_create_success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) .aborted = afs_check_for_remote_deletion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) .edit_dir = afs_create_edit_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) .put = afs_create_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) * create a directory on an AFS filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) struct afs_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) struct afs_vnode *dvnode = AFS_FS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) _enter("{%llx:%llu},{%pd},%ho",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) dvnode->fid.vid, dvnode->fid.vnode, dentry, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) op = afs_alloc_operation(NULL, dvnode->volume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (IS_ERR(op)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return PTR_ERR(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) afs_op_set_vnode(op, 0, dvnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) op->file[0].dv_delta = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) op->file[0].modification = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) op->file[0].update_ctime = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) op->dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) op->create.mode = S_IFDIR | mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) op->create.reason = afs_edit_dir_for_mkdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) op->ops = &afs_mkdir_operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return afs_do_sync_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) * Remove a subdir from a directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) static void afs_dir_remove_subdir(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (d_really_is_positive(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) clear_nlink(&vnode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) set_bit(AFS_VNODE_DELETED, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) static void afs_rmdir_success(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) op->ctime = op->file[0].scb.status.mtime_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) afs_vnode_commit_status(op, &op->file[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) afs_update_dentry_version(op, &op->file[0], op->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) static void afs_rmdir_edit_dir(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) struct afs_vnode_param *dvp = &op->file[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) struct afs_vnode *dvnode = dvp->vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) afs_dir_remove_subdir(op->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) down_write(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) dvnode->status.data_version == dvp->dv_before + dvp->dv_delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) afs_edit_dir_remove(dvnode, &op->dentry->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) afs_edit_dir_for_rmdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) up_write(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static void afs_rmdir_put(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) if (op->file[1].vnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) up_write(&op->file[1].vnode->rmdir_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static const struct afs_operation_ops afs_rmdir_operation = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) .issue_afs_rpc = afs_fs_remove_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) .issue_yfs_rpc = yfs_fs_remove_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) .success = afs_rmdir_success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) .aborted = afs_check_for_remote_deletion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) .edit_dir = afs_rmdir_edit_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) .put = afs_rmdir_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) * remove a directory from an AFS filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) static int afs_rmdir(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) struct afs_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) struct afs_vnode *dvnode = AFS_FS_I(dir), *vnode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) _enter("{%llx:%llu},{%pd}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) dvnode->fid.vid, dvnode->fid.vnode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) op = afs_alloc_operation(NULL, dvnode->volume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) if (IS_ERR(op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) return PTR_ERR(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) afs_op_set_vnode(op, 0, dvnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) op->file[0].dv_delta = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) op->file[0].modification = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) op->file[0].update_ctime = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) op->dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) op->ops = &afs_rmdir_operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) /* Try to make sure we have a callback promise on the victim. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (d_really_is_positive(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) vnode = AFS_FS_I(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) ret = afs_validate(vnode, op->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (vnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) ret = down_write_killable(&vnode->rmdir_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) op->file[1].vnode = vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return afs_do_sync_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) return afs_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) * Remove a link to a file or symlink from a directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) * If the file was not deleted due to excess hard links, the fileserver will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) * break the callback promise on the file - if it had one - before it returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) * to us, and if it was deleted, it won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) * However, if we didn't have a callback promise outstanding, or it was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) * outstanding on a different server, then it won't break it either...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) static void afs_dir_remove_link(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) struct afs_vnode *dvnode = op->file[0].vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) struct afs_vnode *vnode = op->file[1].vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) struct dentry *dentry = op->dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (op->error != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) (op->file[1].scb.have_status && op->file[1].scb.have_error))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) if (d_really_is_positive(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) /* Already done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) } else if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) write_seqlock(&vnode->cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) drop_nlink(&vnode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (vnode->vfs_inode.i_nlink == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) set_bit(AFS_VNODE_DELETED, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) __afs_break_callback(vnode, afs_cb_break_for_unlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) write_sequnlock(&vnode->cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) afs_break_callback(vnode, afs_cb_break_for_unlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) _debug("AFS_VNODE_DELETED");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) ret = afs_validate(vnode, op->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (ret != -ESTALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) op->error = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) _debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, op->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) static void afs_unlink_success(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) op->ctime = op->file[0].scb.status.mtime_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) afs_check_dir_conflict(op, &op->file[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) afs_vnode_commit_status(op, &op->file[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) afs_vnode_commit_status(op, &op->file[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) afs_update_dentry_version(op, &op->file[0], op->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) afs_dir_remove_link(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) static void afs_unlink_edit_dir(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) struct afs_vnode_param *dvp = &op->file[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) struct afs_vnode *dvnode = dvp->vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) down_write(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (test_bit(AFS_VNODE_DIR_VALID, &dvnode->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) dvnode->status.data_version == dvp->dv_before + dvp->dv_delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) afs_edit_dir_remove(dvnode, &op->dentry->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) afs_edit_dir_for_unlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) up_write(&dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) static void afs_unlink_put(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (op->unlink.need_rehash && op->error < 0 && op->error != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) d_rehash(op->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) static const struct afs_operation_ops afs_unlink_operation = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) .issue_afs_rpc = afs_fs_remove_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) .issue_yfs_rpc = yfs_fs_remove_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) .success = afs_unlink_success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) .aborted = afs_check_for_remote_deletion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) .edit_dir = afs_unlink_edit_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) .put = afs_unlink_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * Remove a file or symlink from an AFS filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) static int afs_unlink(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) struct afs_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) struct afs_vnode *dvnode = AFS_FS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) _enter("{%llx:%llu},{%pd}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) dvnode->fid.vid, dvnode->fid.vnode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (dentry->d_name.len >= AFSNAMEMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) op = afs_alloc_operation(NULL, dvnode->volume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (IS_ERR(op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return PTR_ERR(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) afs_op_set_vnode(op, 0, dvnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) op->file[0].dv_delta = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) op->file[0].modification = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) op->file[0].update_ctime = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) /* Try to make sure we have a callback promise on the victim. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) ret = afs_validate(vnode, op->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) op->error = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) if (d_count(dentry) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) /* Start asynchronous writeout of the inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) write_inode_now(d_inode(dentry), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) op->error = afs_sillyrename(dvnode, vnode, dentry, op->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) if (!d_unhashed(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) /* Prevent a race with RCU lookup. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) __d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) op->unlink.need_rehash = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) op->file[1].vnode = vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) op->file[1].update_ctime = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) op->file[1].op_unlinked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) op->dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) op->ops = &afs_unlink_operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) afs_begin_vnode_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) afs_wait_for_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) /* If there was a conflict with a third party, check the status of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) * unlinked vnode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) if (op->error == 0 && (op->flags & AFS_OPERATION_DIR_CONFLICT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) op->file[1].update_ctime = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) op->fetch_status.which = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) op->ops = &afs_fetch_status_operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) afs_begin_vnode_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) afs_wait_for_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) return afs_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) return afs_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static const struct afs_operation_ops afs_create_operation = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) .issue_afs_rpc = afs_fs_create_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) .issue_yfs_rpc = yfs_fs_create_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) .success = afs_create_success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) .aborted = afs_check_for_remote_deletion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) .edit_dir = afs_create_edit_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) .put = afs_create_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) * create a regular file on an AFS filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) bool excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) struct afs_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) struct afs_vnode *dvnode = AFS_FS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) int ret = -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) _enter("{%llx:%llu},{%pd},%ho",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) dvnode->fid.vid, dvnode->fid.vnode, dentry, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (dentry->d_name.len >= AFSNAMEMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) op = afs_alloc_operation(NULL, dvnode->volume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) if (IS_ERR(op)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) ret = PTR_ERR(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) afs_op_set_vnode(op, 0, dvnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) op->file[0].dv_delta = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) op->file[0].modification = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) op->file[0].update_ctime = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) op->dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) op->create.mode = S_IFREG | mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) op->create.reason = afs_edit_dir_for_create;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) op->ops = &afs_create_operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) return afs_do_sync_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) _leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) static void afs_link_success(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) struct afs_vnode_param *dvp = &op->file[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) struct afs_vnode_param *vp = &op->file[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) op->ctime = dvp->scb.status.mtime_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) afs_vnode_commit_status(op, dvp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) afs_vnode_commit_status(op, vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) afs_update_dentry_version(op, dvp, op->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (op->dentry_2->d_parent == op->dentry->d_parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) afs_update_dentry_version(op, dvp, op->dentry_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) ihold(&vp->vnode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) d_instantiate(op->dentry, &vp->vnode->vfs_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) static void afs_link_put(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (op->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) d_drop(op->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) static const struct afs_operation_ops afs_link_operation = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) .issue_afs_rpc = afs_fs_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) .issue_yfs_rpc = yfs_fs_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) .success = afs_link_success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) .aborted = afs_check_for_remote_deletion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) .edit_dir = afs_create_edit_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) .put = afs_link_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) * create a hard link between files in an AFS filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) static int afs_link(struct dentry *from, struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) struct afs_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) struct afs_vnode *dvnode = AFS_FS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) struct afs_vnode *vnode = AFS_FS_I(d_inode(from));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) int ret = -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) _enter("{%llx:%llu},{%llx:%llu},{%pd}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) vnode->fid.vid, vnode->fid.vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) dvnode->fid.vid, dvnode->fid.vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (dentry->d_name.len >= AFSNAMEMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) op = afs_alloc_operation(NULL, dvnode->volume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (IS_ERR(op)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) ret = PTR_ERR(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) afs_op_set_vnode(op, 0, dvnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) afs_op_set_vnode(op, 1, vnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) op->file[0].dv_delta = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) op->file[0].modification = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) op->file[0].update_ctime = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) op->file[1].update_ctime = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) op->dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) op->dentry_2 = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) op->ops = &afs_link_operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) op->create.reason = afs_edit_dir_for_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) return afs_do_sync_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) _leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) static const struct afs_operation_ops afs_symlink_operation = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) .issue_afs_rpc = afs_fs_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) .issue_yfs_rpc = yfs_fs_symlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) .success = afs_create_success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) .aborted = afs_check_for_remote_deletion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) .edit_dir = afs_create_edit_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) .put = afs_create_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) * create a symlink in an AFS filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) static int afs_symlink(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) const char *content)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) struct afs_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) struct afs_vnode *dvnode = AFS_FS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) _enter("{%llx:%llu},{%pd},%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) dvnode->fid.vid, dvnode->fid.vnode, dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) content);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) ret = -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) if (dentry->d_name.len >= AFSNAMEMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) if (strlen(content) >= AFSPATHMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) op = afs_alloc_operation(NULL, dvnode->volume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (IS_ERR(op)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) ret = PTR_ERR(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) afs_op_set_vnode(op, 0, dvnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) op->file[0].dv_delta = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) op->dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) op->ops = &afs_symlink_operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) op->create.reason = afs_edit_dir_for_symlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) op->create.symlink = content;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) return afs_do_sync_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) _leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) static void afs_rename_success(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) op->ctime = op->file[0].scb.status.mtime_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) afs_check_dir_conflict(op, &op->file[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) afs_vnode_commit_status(op, &op->file[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) if (op->file[1].vnode != op->file[0].vnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) op->ctime = op->file[1].scb.status.mtime_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) afs_vnode_commit_status(op, &op->file[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) static void afs_rename_edit_dir(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) struct afs_vnode_param *orig_dvp = &op->file[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) struct afs_vnode_param *new_dvp = &op->file[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) struct afs_vnode *orig_dvnode = orig_dvp->vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) struct afs_vnode *new_dvnode = new_dvp->vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) struct afs_vnode *vnode = AFS_FS_I(d_inode(op->dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) struct dentry *old_dentry = op->dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) struct dentry *new_dentry = op->dentry_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) struct inode *new_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) if (op->rename.rehash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) d_rehash(op->rename.rehash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) op->rename.rehash = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) down_write(&orig_dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (test_bit(AFS_VNODE_DIR_VALID, &orig_dvnode->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) orig_dvnode->status.data_version == orig_dvp->dv_before + orig_dvp->dv_delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) afs_edit_dir_remove(orig_dvnode, &old_dentry->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) afs_edit_dir_for_rename_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if (new_dvnode != orig_dvnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) up_write(&orig_dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) down_write(&new_dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if (test_bit(AFS_VNODE_DIR_VALID, &new_dvnode->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) new_dvnode->status.data_version == new_dvp->dv_before + new_dvp->dv_delta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (!op->rename.new_negative)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) afs_edit_dir_remove(new_dvnode, &new_dentry->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) afs_edit_dir_for_rename_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) afs_edit_dir_add(new_dvnode, &new_dentry->d_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) &vnode->fid, afs_edit_dir_for_rename_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) new_inode = d_inode(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (new_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) spin_lock(&new_inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) if (S_ISDIR(new_inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) clear_nlink(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) else if (new_inode->i_nlink > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) drop_nlink(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) spin_unlock(&new_inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) /* Now we can update d_fsdata on the dentries to reflect their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) * new parent's data_version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) * Note that if we ever implement RENAME_EXCHANGE, we'll have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) * to update both dentries with opposing dir versions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) afs_update_dentry_version(op, new_dvp, op->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) afs_update_dentry_version(op, new_dvp, op->dentry_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) d_move(old_dentry, new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) up_write(&new_dvnode->validate_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) static void afs_rename_put(struct afs_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) _enter("op=%08x", op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) if (op->rename.rehash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) d_rehash(op->rename.rehash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) dput(op->rename.tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if (op->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) d_rehash(op->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) static const struct afs_operation_ops afs_rename_operation = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) .issue_afs_rpc = afs_fs_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) .issue_yfs_rpc = yfs_fs_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) .success = afs_rename_success,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) .edit_dir = afs_rename_edit_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) .put = afs_rename_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) * rename a file in an AFS filesystem and/or move it between directories
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) struct inode *new_dir, struct dentry *new_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) struct afs_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) struct afs_vnode *orig_dvnode, *new_dvnode, *vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) /* Don't allow silly-rename files be moved around. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (old_dentry->d_flags & DCACHE_NFSFS_RENAMED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) vnode = AFS_FS_I(d_inode(old_dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) orig_dvnode = AFS_FS_I(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) new_dvnode = AFS_FS_I(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) _enter("{%llx:%llu},{%llx:%llu},{%llx:%llu},{%pd}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) orig_dvnode->fid.vid, orig_dvnode->fid.vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) vnode->fid.vid, vnode->fid.vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) new_dvnode->fid.vid, new_dvnode->fid.vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) op = afs_alloc_operation(NULL, orig_dvnode->volume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) if (IS_ERR(op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) return PTR_ERR(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) afs_op_set_vnode(op, 0, orig_dvnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) afs_op_set_vnode(op, 1, new_dvnode); /* May be same as orig_dvnode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) op->file[0].dv_delta = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) op->file[1].dv_delta = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) op->file[0].modification = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) op->file[1].modification = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) op->file[0].update_ctime = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) op->file[1].update_ctime = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) op->dentry = old_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) op->dentry_2 = new_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) op->rename.new_negative = d_is_negative(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) op->ops = &afs_rename_operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) /* For non-directories, check whether the target is busy and if so,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) * make a copy of the dentry and then do a silly-rename. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) * silly-rename succeeds, the copied dentry is hashed and becomes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) * new target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) if (d_is_positive(new_dentry) && !d_is_dir(new_dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) /* To prevent any new references to the target during the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) * rename, we unhash the dentry in advance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) if (!d_unhashed(new_dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) d_drop(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) op->rename.rehash = new_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (d_count(new_dentry) > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) /* copy the target dentry's name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) op->rename.tmp = d_alloc(new_dentry->d_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) &new_dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) if (!op->rename.tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) ret = afs_sillyrename(new_dvnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) AFS_FS_I(d_inode(new_dentry)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) new_dentry, op->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) op->dentry_2 = op->rename.tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) op->rename.rehash = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) op->rename.new_negative = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) /* This bit is potentially nasty as there's a potential race with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) * afs_d_revalidate{,_rcu}(). We have to change d_fsdata on the dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) * to reflect it's new parent's new data_version after the op, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) * d_revalidate may see old_dentry between the op having taken place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) * and the version being updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) * So drop the old_dentry for now to make other threads go through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) * lookup instead - which we hold a lock against.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) d_drop(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) return afs_do_sync_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) return afs_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) * Release a directory page and clean up its private state if it's not busy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) * - return true if the page can now be released, false if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) static int afs_dir_releasepage(struct page *page, gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) struct afs_vnode *dvnode = AFS_FS_I(page->mapping->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) _enter("{{%llx:%llu}[%lu]}", dvnode->fid.vid, dvnode->fid.vnode, page->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) detach_page_private(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) /* The directory will need reloading. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) afs_stat_v(dvnode, n_relpg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) * invalidate part or all of a page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) * - release a page and clean up its private data if offset is 0 (indicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) * the entire page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) static void afs_dir_invalidatepage(struct page *page, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) struct afs_vnode *dvnode = AFS_FS_I(page->mapping->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) _enter("{%lu},%u,%u", page->index, offset, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) BUG_ON(!PageLocked(page));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) /* The directory will need reloading. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &dvnode->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) afs_stat_v(dvnode, n_inval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) /* we clean up only if the entire page is being invalidated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) if (offset == 0 && length == PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) detach_page_private(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }