^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/nfs/dir.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1992 Rick Sladkey
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * nfs directory handling functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 10 Apr 1996 Added silly rename for unlink --okir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * 28 Sep 1996 Improved directory cache --okir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * 23 Aug 1997 Claus Heine claus@momo.math.rwth-aachen.de
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Re-implemented silly rename for unlink, newly implemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * silly rename for nfs_rename() following the suggestions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * of Olaf Kirch (okir) found in this file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Following Linus comments on my original hack, this version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * depends only on the dcache stuff and doesn't touch the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * layer (iput() and friends).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * 6 Jun 1999 Cache readdir lookups in the page cache. -DaveM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/sunrpc/clnt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/nfs_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/nfs_mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/pagevec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/swap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/kmemleak.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/xattr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "delegation.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "iostat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "fscache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "nfstrace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* #define NFS_DEBUG_VERBOSE 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int nfs_opendir(struct inode *, struct file *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static int nfs_closedir(struct inode *, struct file *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static int nfs_readdir(struct file *, struct dir_context *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int nfs_fsync_dir(struct file *, loff_t, loff_t, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static loff_t nfs_llseek_dir(struct file *, loff_t, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static void nfs_readdir_clear_array(struct page*);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) const struct file_operations nfs_dir_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .llseek = nfs_llseek_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .read = generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .iterate_shared = nfs_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .open = nfs_opendir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .release = nfs_closedir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .fsync = nfs_fsync_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) const struct address_space_operations nfs_dir_aops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .freepage = nfs_readdir_clear_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct nfs_inode *nfsi = NFS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct nfs_open_dir_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (ctx != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ctx->duped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ctx->attr_gencount = nfsi->attr_gencount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ctx->dir_cookie = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ctx->dup_cookie = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ctx->cred = get_cred(cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) spin_lock(&dir->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (list_empty(&nfsi->open_files) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) (nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) nfsi->cache_validity |= NFS_INO_INVALID_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) NFS_INO_REVAL_FORCED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) list_add(&ctx->list, &nfsi->open_files);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) spin_unlock(&dir->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static void put_nfs_open_dir_context(struct inode *dir, struct nfs_open_dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) spin_lock(&dir->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) list_del(&ctx->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) spin_unlock(&dir->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) put_cred(ctx->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) kfree(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^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) * Open file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) nfs_opendir(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct nfs_open_dir_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) dfprintk(FILE, "NFS: open dir(%pD2)\n", filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) nfs_inc_stats(inode, NFSIOS_VFSOPEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ctx = alloc_nfs_open_dir_context(inode, current_cred());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (IS_ERR(ctx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) res = PTR_ERR(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) filp->private_data = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) nfs_closedir(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) put_nfs_open_dir_context(file_inode(filp), filp->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct nfs_cache_array_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u64 cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u64 ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct qstr string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned char d_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct nfs_cache_array {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int eof_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u64 last_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct nfs_cache_array_entry array[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct dir_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned long page_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u64 *dir_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u64 last_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) loff_t current_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) loff_t prev_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned long dir_verifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) unsigned long timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned long gencount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned int cache_entry_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) bool plus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) bool eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) } nfs_readdir_descriptor_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) void nfs_readdir_init_array(struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct nfs_cache_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) array = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) memset(array, 0, sizeof(struct nfs_cache_array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) array->eof_index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) kunmap_atomic(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * we are freeing strings created by nfs_add_to_readdir_array()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) void nfs_readdir_clear_array(struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct nfs_cache_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) array = kmap_atomic(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) for (i = 0; i < array->size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) kfree(array->array[i].string.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) array->size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) kunmap_atomic(array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * the caller is responsible for freeing qstr.name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * when called by nfs_readdir_add_to_array, the strings will be freed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * nfs_clear_readdir_array()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) string->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) string->name = kmemdup_nul(name, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (string->name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * Avoid a kmemleak false positive. The pointer to the name is stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * in a page cache page which kmemleak does not scan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) kmemleak_not_leak(string->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) string->hash = full_name_hash(NULL, name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct nfs_cache_array *array = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct nfs_cache_array_entry *cache_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) cache_entry = &array->array[array->size];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* Check that this entry lies within the page bounds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ret = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if ((char *)&cache_entry[1] - (char *)page_address(page) > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) cache_entry->cookie = entry->prev_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) cache_entry->ino = entry->ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) cache_entry->d_type = entry->d_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) array->last_cookie = entry->cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) array->size++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (entry->eof != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) array->eof_index = array->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) int is_32bit_api(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return in_compat_syscall();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return (BITS_PER_LONG == 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) bool nfs_readdir_use_cookie(const struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if ((filp->f_mode & FMODE_32BITHASH) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api()))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descriptor_t *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) loff_t diff = desc->ctx->pos - desc->current_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (diff < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto out_eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (diff >= array->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (array->eof_index >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) goto out_eof;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) index = (unsigned int)diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *desc->dir_cookie = array->array[index].cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) desc->cache_entry_index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) out_eof:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) desc->eof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return -EBADCOOKIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) nfs_readdir_inode_mapping_valid(struct nfs_inode *nfsi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return !test_bit(NFS_INO_INVALIDATING, &nfsi->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_descriptor_t *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) loff_t new_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int status = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) for (i = 0; i < array->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (array->array[i].cookie == *desc->dir_cookie) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct nfs_inode *nfsi = NFS_I(file_inode(desc->file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct nfs_open_dir_context *ctx = desc->file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) new_pos = desc->current_index + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (ctx->attr_gencount != nfsi->attr_gencount ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) !nfs_readdir_inode_mapping_valid(nfsi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ctx->duped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ctx->attr_gencount = nfsi->attr_gencount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) } else if (new_pos < desc->prev_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (ctx->duped > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) && ctx->dup_cookie == *desc->dir_cookie) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (printk_ratelimit()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) pr_notice("NFS: directory %pD2 contains a readdir loop."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) "Please contact your server vendor. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) "The file: %.*s has duplicate cookie %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) desc->file, array->array[i].string.len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) array->array[i].string.name, *desc->dir_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) status = -ELOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ctx->dup_cookie = *desc->dir_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ctx->duped = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (nfs_readdir_use_cookie(desc->file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) desc->ctx->pos = *desc->dir_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) desc->ctx->pos = new_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) desc->prev_index = new_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) desc->cache_entry_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (array->eof_index >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) status = -EBADCOOKIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (*desc->dir_cookie == array->last_cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) desc->eof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return status;
^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) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct nfs_cache_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) array = kmap(desc->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (*desc->dir_cookie == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) status = nfs_readdir_search_for_pos(array, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) status = nfs_readdir_search_for_cookie(array, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (status == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) desc->last_cookie = array->last_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) desc->current_index += array->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) desc->page_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) kunmap(desc->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Fill a page with xdr information before transferring to the cache page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int nfs_readdir_xdr_filler(struct page **pages, nfs_readdir_descriptor_t *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct nfs_entry *entry, struct file *file, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct nfs_open_dir_context *ctx = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) const struct cred *cred = ctx->cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) unsigned long timestamp, gencount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) timestamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) gencount = nfs_inc_attr_generation_counter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) desc->dir_verifier = nfs_save_change_attribute(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) error = NFS_PROTO(inode)->readdir(file_dentry(file), cred, entry->cookie, pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) NFS_SERVER(inode)->dtsize, desc->plus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* We requested READDIRPLUS, but the server doesn't grok it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (error == -ENOTSUPP && desc->plus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) desc->plus = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) desc->timestamp = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) desc->gencount = gencount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int xdr_decode(nfs_readdir_descriptor_t *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct nfs_entry *entry, struct xdr_stream *xdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct inode *inode = file_inode(desc->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) error = NFS_PROTO(inode)->decode_dirent(xdr, entry, desc->plus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) entry->fattr->time_start = desc->timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) entry->fattr->gencount = desc->gencount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* Match file and dirent using either filehandle or fileid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * Note: caller is responsible for checking the fsid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct nfs_inode *nfsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (d_really_is_negative(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (is_bad_inode(inode) || NFS_STALE(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (entry->fattr->fileid != nfsi->fileid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (entry->fh->size && nfs_compare_fh(entry->fh, &nfsi->fh) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return 1;
^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) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) bool nfs_use_readdirplus(struct inode *dir, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (!nfs_server_capable(dir, NFS_CAP_READDIRPLUS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (test_and_clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(dir)->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (ctx->pos == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * This function is called by the lookup and getattr code to request the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * use of readdirplus to accelerate any future lookups in the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) void nfs_advise_use_readdirplus(struct inode *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct nfs_inode *nfsi = NFS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (nfs_server_capable(dir, NFS_CAP_READDIRPLUS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) !list_empty(&nfsi->open_files))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) set_bit(NFS_INO_ADVISE_RDPLUS, &nfsi->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * This function is mainly for use by nfs_getattr().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * If this is an 'ls -l', we want to force use of readdirplus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * Do this by checking if there is an active file descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * and calling nfs_advise_use_readdirplus, then forcing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * cache flush.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) void nfs_force_use_readdirplus(struct inode *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct nfs_inode *nfsi = NFS_I(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (nfs_server_capable(dir, NFS_CAP_READDIRPLUS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) !list_empty(&nfsi->open_files)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) set_bit(NFS_INO_ADVISE_RDPLUS, &nfsi->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) invalidate_mapping_pages(dir->i_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) nfsi->page_index + 1, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) unsigned long dir_verifier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct qstr filename = QSTR_INIT(entry->name, entry->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct dentry *dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct dentry *alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!(entry->fattr->valid & NFS_ATTR_FATTR_FILEID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (!(entry->fattr->valid & NFS_ATTR_FATTR_FSID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (filename.len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* Validate that the name doesn't contain any illegal '\0' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (strnlen(filename.name, filename.len) != filename.len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /* ...or '/' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (strnchr(filename.name, filename.len, '/'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (filename.name[0] == '.') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (filename.len == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (filename.len == 2 && filename.name[1] == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) filename.hash = full_name_hash(parent, filename.name, filename.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) dentry = d_lookup(parent, &filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (!dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) dentry = d_alloc_parallel(parent, &filename, &wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (IS_ERR(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (!d_in_lookup(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* Is there a mountpoint here? If so, just exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (!nfs_fsid_equal(&NFS_SB(dentry->d_sb)->fsid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) &entry->fattr->fsid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (nfs_same_file(dentry, entry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (!entry->fh->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) nfs_set_verifier(dentry, dir_verifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) status = nfs_refresh_inode(d_inode(dentry), entry->fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (!status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) nfs_setsecurity(d_inode(dentry), entry->fattr, entry->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) d_invalidate(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (!entry->fh->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) d_lookup_done(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) goto out;
^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) inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr, entry->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) alias = d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) d_lookup_done(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (alias) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (IS_ERR(alias))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) dentry = alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) nfs_set_verifier(dentry, dir_verifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* Perform conversion from xdr to cache array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct page **xdr_pages, struct page *page, unsigned int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct xdr_stream stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct xdr_buf buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct page *scratch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct nfs_cache_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) unsigned int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) scratch = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (scratch == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (buflen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) goto out_nopages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) xdr_init_decode_pages(&stream, &buf, xdr_pages, buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (entry->label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) entry->label->len = NFS4_MAXLABELLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) status = xdr_decode(desc, entry, &stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (status == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (desc->plus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) nfs_prime_dcache(file_dentry(desc->file), entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) desc->dir_verifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) status = nfs_readdir_add_to_array(entry, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) } while (!entry->eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) out_nopages:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) array = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) array->eof_index = array->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) put_page(scratch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) void nfs_readdir_free_pages(struct page **pages, unsigned int npages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) for (i = 0; i < npages; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) put_page(pages[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^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) * nfs_readdir_alloc_pages() will allocate pages that must be freed with a call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * to nfs_readdir_free_pages()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int nfs_readdir_alloc_pages(struct page **pages, unsigned int npages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) for (i = 0; i < npages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct page *page = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (page == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) goto out_freepages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) pages[i] = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) out_freepages:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) nfs_readdir_free_pages(pages, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct page *pages[NFS_MAX_READDIR_PAGES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct nfs_entry entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) struct file *file = desc->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct nfs_cache_array *array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) int status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) unsigned int array_size = ARRAY_SIZE(pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) nfs_readdir_init_array(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) entry.prev_cookie = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) entry.cookie = desc->last_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) entry.eof = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) entry.fh = nfs_alloc_fhandle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) entry.fattr = nfs_alloc_fattr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) entry.server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (entry.fh == NULL || entry.fattr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) entry.label = nfs4_label_alloc(NFS_SERVER(inode), GFP_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (IS_ERR(entry.label)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) status = PTR_ERR(entry.label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) array = kmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) status = nfs_readdir_alloc_pages(pages, array_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) goto out_release_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) unsigned int pglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) pglen = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) status = nfs_readdir_page_filler(desc, &entry, pages, page, pglen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (status == -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) } while (array->eof_index < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) nfs_readdir_free_pages(pages, array_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) out_release_array:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) kunmap(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) nfs4_label_free(entry.label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) nfs_free_fattr(entry.fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) nfs_free_fhandle(entry.fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * Now we cache directories properly, by converting xdr information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * to an array that can be used for lookups later. This results in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) * fewer cache pages, since we can store more information on each page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * We only need to convert from xdr once so future lookups are much simpler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) int nfs_readdir_filler(void *data, struct page* page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) nfs_readdir_descriptor_t *desc = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct inode *inode = file_inode(desc->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ret = nfs_readdir_xdr_to_array(desc, page, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (invalidate_inode_pages2_range(inode->i_mapping, page->index + 1, -1) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /* Should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) nfs_zap_mapping(inode, inode->i_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) nfs_readdir_clear_array(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) void cache_page_release(nfs_readdir_descriptor_t *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) put_page(desc->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) desc->page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct page *get_cache_page(nfs_readdir_descriptor_t *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return read_cache_page(desc->file->f_mapping, desc->page_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) nfs_readdir_filler, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * Returns 0 if desc->dir_cookie was found on page desc->page_index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * and locks the page to prevent removal from the page cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) int find_and_lock_cache_page(nfs_readdir_descriptor_t *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct inode *inode = file_inode(desc->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) desc->page = get_cache_page(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (IS_ERR(desc->page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return PTR_ERR(desc->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) res = lock_page_killable(desc->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (res != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) res = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (desc->page->mapping != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) res = nfs_readdir_search_array(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (res == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) nfsi->page_index = desc->page_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) unlock_page(desc->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) cache_page_release(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) /* Search for desc->dir_cookie from the beginning of the page cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (desc->page_index == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) desc->current_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) desc->prev_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) desc->last_cookie = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) res = find_and_lock_cache_page(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) } while (res == -EAGAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^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) * Once we've found the start of the dirent within a page: fill 'er up...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) int nfs_do_filldir(nfs_readdir_descriptor_t *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct file *file = desc->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct nfs_cache_array *array = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) struct nfs_open_dir_context *ctx = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) array = kmap(desc->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) for (i = desc->cache_entry_index; i < array->size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct nfs_cache_array_entry *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) ent = &array->array[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (!dir_emit(desc->ctx, ent->string.name, ent->string.len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) nfs_compat_user_ino64(ent->ino), ent->d_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) desc->eof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (i < (array->size-1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) *desc->dir_cookie = array->array[i+1].cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) *desc->dir_cookie = array->last_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (nfs_readdir_use_cookie(file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) desc->ctx->pos = *desc->dir_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) desc->ctx->pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (ctx->duped != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) ctx->duped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (array->eof_index >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) desc->eof = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) kunmap(desc->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) (unsigned long long)*desc->dir_cookie, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * If we cannot find a cookie in our cache, we suspect that this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * because it points to a deleted file, so we ask the server to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * whatever it thinks is the next entry. We then feed this to filldir.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * If all goes well, we should then be able to find our way round the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * cache on the next call to readdir_search_pagecache();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * NOTE: we cannot add the anonymous page to the pagecache because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * the data it contains might not be page aligned. Besides,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * we should already have a complete representation of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * directory in the page cache by the time we get here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) int uncached_readdir(nfs_readdir_descriptor_t *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct page *page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct inode *inode = file_inode(desc->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct nfs_open_dir_context *ctx = desc->file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) (unsigned long long)*desc->dir_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) page = alloc_page(GFP_HIGHUSER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) desc->page_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) desc->last_cookie = *desc->dir_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) desc->page = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) ctx->duped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) status = nfs_readdir_xdr_to_array(desc, page, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) status = nfs_do_filldir(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) out_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) nfs_readdir_clear_array(desc->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) cache_page_release(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dfprintk(DIRCACHE, "NFS: %s: returns %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /* The file offset position represents the dirent entry number. A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) last cookie cache takes care of the common case of reading the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) whole directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) static int nfs_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) struct dentry *dentry = file_dentry(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct nfs_open_dir_context *dir_ctx = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) nfs_readdir_descriptor_t my_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .file = file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .ctx = ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .dir_cookie = &dir_ctx->dir_cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .plus = nfs_use_readdirplus(inode, ctx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) *desc = &my_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) dfprintk(FILE, "NFS: readdir(%pD2) starting at cookie %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) file, (long long)ctx->pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) nfs_inc_stats(inode, NFSIOS_VFSGETDENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * ctx->pos points to the dirent entry number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * *desc->dir_cookie has the cookie for the next entry. We have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) * to either find the entry with the appropriate number or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * revalidate the cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (ctx->pos == 0 || nfs_attribute_cache_expired(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) res = nfs_revalidate_mapping(inode, file->f_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) res = readdir_search_pagecache(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (res == -EBADCOOKIE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /* This means either end of directory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (*desc->dir_cookie && !desc->eof) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /* Or that the server has 'lost' a cookie */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) res = uncached_readdir(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (res == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (res == -ETOOSMALL && desc->plus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) nfs_zap_caches(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) desc->page_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) desc->plus = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) desc->eof = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) res = nfs_do_filldir(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) unlock_page(desc->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) cache_page_release(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) } while (!desc->eof);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (res > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) dfprintk(FILE, "NFS: readdir(%pD2) returns %d\n", file, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct nfs_open_dir_context *dir_ctx = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dfprintk(FILE, "NFS: llseek dir(%pD2, %lld, %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) filp, offset, whence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) switch (whence) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) case SEEK_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (offset < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) spin_lock(&filp->f_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) case SEEK_CUR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (offset == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return filp->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) spin_lock(&filp->f_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) offset += filp->f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (offset < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) spin_unlock(&filp->f_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (offset != filp->f_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) filp->f_pos = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (nfs_readdir_use_cookie(filp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) dir_ctx->dir_cookie = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) dir_ctx->dir_cookie = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) dir_ctx->duped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) spin_unlock(&filp->f_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * All directory operations under NFS are synchronous, so fsync()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * is a dummy operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static int nfs_fsync_dir(struct file *filp, loff_t start, loff_t end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) int datasync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) dfprintk(FILE, "NFS: fsync dir(%pD2) datasync %d\n", filp, datasync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) nfs_inc_stats(file_inode(filp), NFSIOS_VFSFSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * nfs_force_lookup_revalidate - Mark the directory as having changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * @dir: pointer to directory inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * This forces the revalidation code in nfs_lookup_revalidate() to do a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * full lookup on all child dentries of 'dir' whenever a change occurs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * on the server that might have invalidated our dcache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) * Note that we reserve bit '0' as a tag to let us know when a dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) * was revalidated while holding a delegation on its inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * The caller should be holding dir->i_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) void nfs_force_lookup_revalidate(struct inode *dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) NFS_I(dir)->cache_change_attribute += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) EXPORT_SYMBOL_GPL(nfs_force_lookup_revalidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) * nfs_verify_change_attribute - Detects NFS remote directory changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) * @dir: pointer to parent directory inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) * @verf: previously saved change attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * Return "false" if the verifiers doesn't match the change attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * This would usually indicate that the directory contents have changed on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * the server, and that any dentries need revalidating.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) static bool nfs_verify_change_attribute(struct inode *dir, unsigned long verf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return (verf & ~1UL) == nfs_save_change_attribute(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static void nfs_set_verifier_delegated(unsigned long *verf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) *verf |= 1UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) #if IS_ENABLED(CONFIG_NFS_V4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static void nfs_unset_verifier_delegated(unsigned long *verf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) *verf &= ~1UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) #endif /* IS_ENABLED(CONFIG_NFS_V4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static bool nfs_test_verifier_delegated(unsigned long verf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return verf & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static bool nfs_verifier_is_delegated(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return nfs_test_verifier_delegated(dentry->d_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static void nfs_set_verifier_locked(struct dentry *dentry, unsigned long verf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) struct inode *dir = d_inode(dentry->d_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (!nfs_verify_change_attribute(dir, verf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (inode && NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) nfs_set_verifier_delegated(&verf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) dentry->d_time = verf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) * nfs_set_verifier - save a parent directory verifier in the dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) * @dentry: pointer to dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * @verf: verifier to save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) * Saves the parent directory verifier in @dentry. If the inode has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * a delegation, we also tag the dentry as having been revalidated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * while holding a delegation so that we know we don't have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * look it up again after a directory change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) void nfs_set_verifier(struct dentry *dentry, unsigned long verf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) nfs_set_verifier_locked(dentry, verf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) EXPORT_SYMBOL_GPL(nfs_set_verifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) #if IS_ENABLED(CONFIG_NFS_V4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * nfs_clear_verifier_delegated - clear the dir verifier delegation tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * @inode: pointer to inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * Iterates through the dentries in the inode alias list and clears
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * the tag used to indicate that the dentry has been revalidated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * while holding a delegation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * This function is intended for use when the delegation is being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * returned or revoked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) void nfs_clear_verifier_delegated(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct dentry *alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) spin_lock(&alias->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) nfs_unset_verifier_delegated(&alias->d_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) spin_unlock(&alias->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) EXPORT_SYMBOL_GPL(nfs_clear_verifier_delegated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) #endif /* IS_ENABLED(CONFIG_NFS_V4) */
^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) * A check for whether or not the parent directory has changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * In the case it has, we assume that the dentries are untrustworthy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * and may need to be looked up again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * If rcu_walk prevents us from performing a full check, return 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) static int nfs_check_verifier(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) int rcu_walk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (IS_ROOT(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (!nfs_verify_change_attribute(dir, dentry->d_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) /* Revalidate nfsi->cache_change_attribute before we declare a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (nfs_mapping_need_revalidate_inode(dir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (rcu_walk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (__nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (!nfs_verify_change_attribute(dir, dentry->d_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) * Use intent information to check whether or not we're going to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) * an O_EXCL create using this path component.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static int nfs_is_exclusive_create(struct inode *dir, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (NFS_PROTO(dir)->version == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return flags & LOOKUP_EXCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) * Inode and filehandle revalidation for lookups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) * We force revalidation in the cases where the VFS sets LOOKUP_REVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) * or if the intent information indicates that we're about to open this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) * particular file and the "nocto" mount flag is not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (IS_AUTOMOUNT(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (flags & LOOKUP_OPEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) switch (inode->i_mode & S_IFMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) case S_IFREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) /* A NFSv4 OPEN will revalidate later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (server->caps & NFS_CAP_ATOMIC_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) case S_IFDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if (server->flags & NFS_MOUNT_NOCTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* NFS close-to-open cache consistency validation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) goto out_force;
^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) /* VFS wants an on-the-wire revalidation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (flags & LOOKUP_REVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) goto out_force;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return (inode->i_nlink == 0) ? -ESTALE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) out_force:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ret = __nfs_revalidate_inode(server, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) static void nfs_mark_dir_for_revalidate(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) * We judge how long we want to trust negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) * dentries by looking at the parent inode mtime.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * If parent mtime has changed, we revalidate, else we wait for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * period corresponding to the parent's attribute cache timeout value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * If LOOKUP_RCU prevents us from performing a full check, return 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * suggesting a reval is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * Note that when creating a new file, or looking up a rename target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * then it shouldn't be necessary to revalidate a negative dentry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return !nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) nfs_lookup_revalidate_done(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) struct inode *inode, int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) switch (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) dfprintk(LOOKUPCACHE, "NFS: %s(%pd2) is valid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) __func__, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) * We can't d_drop the root of a disconnected tree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) * its d_hash is on the s_anon list and d_drop() would hide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) * it from shrink_dcache_for_unmount(), leading to busy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) * inodes on unmount and further oopses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (inode && IS_ROOT(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) dfprintk(LOOKUPCACHE, "NFS: %s(%pd2) is invalid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) __func__, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) dfprintk(LOOKUPCACHE, "NFS: %s(%pd2) lookup returned error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) __func__, dentry, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) nfs_lookup_revalidate_negative(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) int ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (nfs_neg_need_reval(dir, dentry, flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) return nfs_lookup_revalidate_done(dir, dentry, NULL, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) nfs_lookup_revalidate_delegated(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return nfs_lookup_revalidate_done(dir, dentry, inode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) nfs_lookup_revalidate_dentry(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) struct nfs_fh *fhandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) struct nfs_fattr *fattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) struct nfs4_label *label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) unsigned long dir_verifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) fhandle = nfs_alloc_fhandle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) fattr = nfs_alloc_fattr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) label = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (fhandle == NULL || fattr == NULL || IS_ERR(label))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) dir_verifier = nfs_save_change_attribute(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) ret = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) case -ESTALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) case -ETIMEDOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (NFS_SERVER(inode)->flags & NFS_MOUNT_SOFTREVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (nfs_compare_fh(NFS_FH(inode), fhandle))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (nfs_refresh_inode(inode, fattr) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) nfs_setsecurity(inode, fattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) nfs_set_verifier(dentry, dir_verifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) /* set a readdirplus hint that we had a cache miss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) nfs_force_use_readdirplus(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) nfs_free_fattr(fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) nfs_free_fhandle(fhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) nfs4_label_free(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) * If the lookup failed despite the dentry change attribute being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) * a match, then we should revalidate the directory cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) if (!ret && nfs_verify_change_attribute(dir, dentry->d_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) nfs_mark_dir_for_revalidate(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return nfs_lookup_revalidate_done(dir, dentry, inode, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) * This is called every time the dcache has a lookup hit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) * and we should check whether we can really trust that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) * lookup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) * NOTE! The hit can be a negative hit too, don't assume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) * we have an inode!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) * If the parent directory is seen to have changed, we throw out the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) * cached dentry and do a new lookup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) nfs_do_lookup_revalidate(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) return nfs_lookup_revalidate_negative(dir, dentry, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if (is_bad_inode(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) dfprintk(LOOKUPCACHE, "%s: %pd2 has dud inode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) __func__, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) goto out_bad;
^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) if (nfs_verifier_is_delegated(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) return nfs_lookup_revalidate_delegated(dir, dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) /* Force a full look up iff the parent directory has changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (!(flags & (LOOKUP_EXCL | LOOKUP_REVAL)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) error = nfs_lookup_verify_inode(inode, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (error == -ESTALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) nfs_mark_dir_for_revalidate(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) goto out_bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) nfs_advise_use_readdirplus(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) goto out_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) if (NFS_STALE(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) goto out_bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) trace_nfs_lookup_revalidate_enter(dir, dentry, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) error = nfs_lookup_revalidate_dentry(dir, dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) trace_nfs_lookup_revalidate_exit(dir, dentry, flags, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) out_valid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) return nfs_lookup_revalidate_done(dir, dentry, inode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) out_bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) return nfs_lookup_revalidate_done(dir, dentry, inode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) __nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) int (*reval)(struct inode *, struct dentry *, unsigned int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) struct dentry *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) struct inode *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (flags & LOOKUP_RCU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) parent = READ_ONCE(dentry->d_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) dir = d_inode_rcu(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) if (!dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) ret = reval(dir, dentry, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (parent != READ_ONCE(dentry->d_parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) parent = dget_parent(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) ret = reval(d_inode(parent), dentry, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) dput(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) static int nfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) return __nfs_lookup_revalidate(dentry, flags, nfs_do_lookup_revalidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) * A weaker form of d_revalidate for revalidating just the d_inode(dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) * when we don't really care about the dentry name. This is called when a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) * pathwalk ends on a dentry that was not found via a normal lookup in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) * parent dir (e.g.: ".", "..", procfs symlinks or mountpoint traversals).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) * In this situation, we just want to verify that the inode itself is OK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) * since the dentry might have changed on the server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) static int nfs_weak_revalidate(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) * I believe we can only get a negative dentry here in the case of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) * procfs-style symlink. Just assume it's correct for now, but we may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) * eventually need to do something more here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (!inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) dfprintk(LOOKUPCACHE, "%s: %pd2 has negative inode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) __func__, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (is_bad_inode(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) dfprintk(LOOKUPCACHE, "%s: %pd2 has dud inode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) __func__, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) error = nfs_lookup_verify_inode(inode, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) dfprintk(LOOKUPCACHE, "NFS: %s: inode %lu is %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) __func__, inode->i_ino, error ? "invalid" : "valid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) return !error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) * This is called from dput() when d_count is going to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) static int nfs_dentry_delete(const struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) dfprintk(VFS, "NFS: dentry_delete(%pd2, %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) dentry, dentry->d_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) /* Unhash any dentry with a stale inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (d_really_is_positive(dentry) && NFS_STALE(d_inode(dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) /* Unhash it, so that ->d_iput() would be called */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) if (!(dentry->d_sb->s_flags & SB_ACTIVE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) /* Unhash it, so that ancestors of killed async unlink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) * files will be cleaned up during umount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) return 0;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) /* Ensure that we revalidate inode->i_nlink */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) static void nfs_drop_nlink(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) /* drop the inode if we're reasonably sure this is the last link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (inode->i_nlink > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) drop_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) NFS_I(inode)->cache_validity |= NFS_INO_INVALID_CHANGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) | NFS_INO_INVALID_CTIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) | NFS_INO_INVALID_OTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) | NFS_INO_REVAL_FORCED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * Called when the dentry loses inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) * We use it to clean up silly-renamed files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) /* drop any readdir cache as it could easily be old */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) nfs_complete_unlink(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) nfs_drop_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) static void nfs_d_release(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) /* free cached devname value, if it survived that far */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) if (unlikely(dentry->d_fsdata)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) kfree(dentry->d_fsdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) const struct dentry_operations nfs_dentry_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) .d_revalidate = nfs_lookup_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) .d_weak_revalidate = nfs_weak_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) .d_delete = nfs_dentry_delete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) .d_iput = nfs_dentry_iput,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) .d_automount = nfs_d_automount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) .d_release = nfs_d_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) EXPORT_SYMBOL_GPL(nfs_dentry_operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) struct dentry *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) struct inode *inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) struct nfs_fh *fhandle = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) struct nfs_fattr *fattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) struct nfs4_label *label = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) unsigned long dir_verifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) dfprintk(VFS, "NFS: lookup(%pd2)\n", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) nfs_inc_stats(dir, NFSIOS_VFSLOOKUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) if (unlikely(dentry->d_name.len > NFS_SERVER(dir)->namelen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) * If we're doing an exclusive create, optimize away the lookup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) * but don't hash the dentry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (nfs_is_exclusive_create(dir, flags) || flags & LOOKUP_RENAME_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) res = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) fhandle = nfs_alloc_fhandle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) fattr = nfs_alloc_fattr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (fhandle == NULL || fattr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) label = nfs4_label_alloc(NFS_SERVER(dir), GFP_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) if (IS_ERR(label))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) dir_verifier = nfs_save_change_attribute(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) trace_nfs_lookup_enter(dir, dentry, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) if (error == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) goto no_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) res = ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) goto out_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) res = ERR_CAST(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (IS_ERR(res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) goto out_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) /* Notify readdir to use READDIRPLUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) nfs_force_use_readdirplus(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) no_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) res = d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) if (res != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) if (IS_ERR(res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) goto out_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) dentry = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) nfs_set_verifier(dentry, dir_verifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) out_label:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) trace_nfs_lookup_exit(dir, dentry, flags, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) nfs4_label_free(label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) nfs_free_fattr(fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) nfs_free_fhandle(fhandle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) EXPORT_SYMBOL_GPL(nfs_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) #if IS_ENABLED(CONFIG_NFS_V4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) static int nfs4_lookup_revalidate(struct dentry *, unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) const struct dentry_operations nfs4_dentry_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) .d_revalidate = nfs4_lookup_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) .d_weak_revalidate = nfs_weak_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) .d_delete = nfs_dentry_delete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) .d_iput = nfs_dentry_iput,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) .d_automount = nfs_d_automount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) .d_release = nfs_d_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) EXPORT_SYMBOL_GPL(nfs4_dentry_operations);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) static fmode_t flags_to_mode(int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) fmode_t res = (__force fmode_t)flags & FMODE_EXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if ((flags & O_ACCMODE) != O_WRONLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) res |= FMODE_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) if ((flags & O_ACCMODE) != O_RDONLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) res |= FMODE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) return res;
^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 struct nfs_open_context *create_nfs_open_context(struct dentry *dentry, int open_flags, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) return alloc_nfs_open_context(dentry, flags_to_mode(open_flags), filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) static int do_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) nfs_fscache_open_file(inode, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) static int nfs_finish_open(struct nfs_open_context *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) struct file *file, unsigned open_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) err = finish_open(file, dentry, do_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (S_ISREG(file->f_path.dentry->d_inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) nfs_file_set_open_context(file, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) err = -EOPENSTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) struct file *file, unsigned open_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) struct nfs_open_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) struct dentry *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) struct iattr attr = { .ia_valid = ATTR_OPEN };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) unsigned int lookup_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) bool switched = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) int created = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) /* Expect a negative dentry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) BUG_ON(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) dfprintk(VFS, "NFS: atomic_open(%s/%lu), %pd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) dir->i_sb->s_id, dir->i_ino, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) err = nfs_check_flags(open_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) /* NFS only supports OPEN on regular files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) if ((open_flags & O_DIRECTORY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if (!d_in_lookup(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) * Hashed negative dentry with O_DIRECTORY: dentry was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) * revalidated and is fine, no need to perform lookup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) * again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) lookup_flags = LOOKUP_OPEN|LOOKUP_DIRECTORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) goto no_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) if (open_flags & O_CREAT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) struct nfs_server *server = NFS_SERVER(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) if (!(server->attr_bitmask[2] & FATTR4_WORD2_MODE_UMASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) mode &= ~current_umask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) attr.ia_valid |= ATTR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) attr.ia_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) if (open_flags & O_TRUNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) attr.ia_valid |= ATTR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) attr.ia_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (!(open_flags & O_CREAT) && !d_in_lookup(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) switched = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) dentry = d_alloc_parallel(dentry->d_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) &dentry->d_name, &wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) if (IS_ERR(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) return PTR_ERR(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (unlikely(!d_in_lookup(dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) return finish_no_open(file, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) ctx = create_nfs_open_context(dentry, open_flags, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) err = PTR_ERR(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (IS_ERR(ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) trace_nfs_atomic_open_enter(dir, ctx, open_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr, &created);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (created)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) file->f_mode |= FMODE_CREATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) err = PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) put_nfs_open_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) switch (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) d_splice_alias(NULL, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) case -EISDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) case -ENOTDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) goto no_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) case -ELOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if (!(open_flags & O_NOFOLLOW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) goto no_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) /* case -EINVAL: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) err = nfs_finish_open(ctx, ctx->dentry, file, open_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) put_nfs_open_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) if (unlikely(switched)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) d_lookup_done(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) no_open:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) res = nfs_lookup(dir, dentry, lookup_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) if ((lookup_flags & LOOKUP_DIRECTORY) && inode &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) !(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) res = ERR_PTR(-ENOTDIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) else if (inode && S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) res = ERR_PTR(-EOPENSTALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) } else if (!IS_ERR(res)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) inode = d_inode(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) if ((lookup_flags & LOOKUP_DIRECTORY) && inode &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) !(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) dput(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) res = ERR_PTR(-ENOTDIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) } else if (inode && S_ISREG(inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) dput(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) res = ERR_PTR(-EOPENSTALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) if (switched) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) d_lookup_done(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) if (!res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) res = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (IS_ERR(res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) return PTR_ERR(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) return finish_no_open(file, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) EXPORT_SYMBOL_GPL(nfs_atomic_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) nfs4_do_lookup_revalidate(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (!(flags & LOOKUP_OPEN) || (flags & LOOKUP_DIRECTORY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) goto full_reval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) if (d_mountpoint(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) goto full_reval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) /* We can't create new files in nfs_open_revalidate(), so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) * optimize away revalidation of negative dentries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) if (inode == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) goto full_reval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) if (nfs_verifier_is_delegated(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) return nfs_lookup_revalidate_delegated(dir, dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) /* NFS only supports OPEN on regular files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (!S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) goto full_reval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) /* We cannot do exclusive creation on a positive dentry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (flags & (LOOKUP_EXCL | LOOKUP_REVAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) goto reval_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) /* Check if the directory changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) if (!nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) goto reval_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) /* Let f_op->open() actually open (and revalidate) the file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) reval_dentry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) return nfs_lookup_revalidate_dentry(dir, dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) full_reval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) return nfs_do_lookup_revalidate(dir, dentry, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) return __nfs_lookup_revalidate(dentry, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) nfs4_do_lookup_revalidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) #endif /* CONFIG_NFSV4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) struct dentry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) struct nfs_fattr *fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) struct dentry *parent = dget_parent(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) struct inode *dir = d_inode(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) struct dentry *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) if (fhandle->size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) if (!(fattr->valid & NFS_ATTR_FATTR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) struct nfs_server *server = NFS_SB(dentry->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) error = server->nfs_client->rpc_ops->getattr(server, fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) fattr, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) goto out_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) inode = nfs_fhget(dentry->d_sb, fhandle, fattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) d = d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) dput(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) return d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) out_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) d = ERR_PTR(error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) EXPORT_SYMBOL_GPL(nfs_add_or_obtain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) * Code common to create, mkdir, and mknod.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) struct nfs_fattr *fattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) struct nfs4_label *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) struct dentry *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) d = nfs_add_or_obtain(dentry, fhandle, fattr, label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) if (IS_ERR(d))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) return PTR_ERR(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) /* Callers don't care */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) dput(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) EXPORT_SYMBOL_GPL(nfs_instantiate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) * Following a failed create operation, we drop the dentry rather
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) * than retain a negative dentry. This avoids a problem in the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) * that the operation succeeded on the server, but an error in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) * reply path made it appear to have failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) int nfs_create(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) umode_t mode, bool excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) struct iattr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) int open_flags = excl ? O_CREAT | O_EXCL : O_CREAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) dfprintk(VFS, "NFS: create(%s/%lu), %pd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) dir->i_sb->s_id, dir->i_ino, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) attr.ia_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) attr.ia_valid = ATTR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) trace_nfs_create_enter(dir, dentry, open_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) trace_nfs_create_exit(dir, dentry, open_flags, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) if (error != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) EXPORT_SYMBOL_GPL(nfs_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) * See comments for nfs_proc_create regarding failed operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) nfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) struct iattr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) dfprintk(VFS, "NFS: mknod(%s/%lu), %pd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) dir->i_sb->s_id, dir->i_ino, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) attr.ia_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) attr.ia_valid = ATTR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) trace_nfs_mknod_enter(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) status = NFS_PROTO(dir)->mknod(dir, dentry, &attr, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) trace_nfs_mknod_exit(dir, dentry, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) EXPORT_SYMBOL_GPL(nfs_mknod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) * See comments for nfs_proc_create regarding failed operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) int nfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) struct iattr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) dfprintk(VFS, "NFS: mkdir(%s/%lu), %pd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) dir->i_sb->s_id, dir->i_ino, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) attr.ia_valid = ATTR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) attr.ia_mode = mode | S_IFDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) trace_nfs_mkdir_enter(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) error = NFS_PROTO(dir)->mkdir(dir, dentry, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) trace_nfs_mkdir_exit(dir, dentry, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (error != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) EXPORT_SYMBOL_GPL(nfs_mkdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) static void nfs_dentry_handle_enoent(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) if (simple_positive(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) d_delete(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) int nfs_rmdir(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) dfprintk(VFS, "NFS: rmdir(%s/%lu), %pd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) dir->i_sb->s_id, dir->i_ino, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) trace_nfs_rmdir_enter(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) if (d_really_is_positive(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) down_write(&NFS_I(d_inode(dentry))->rmdir_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) /* Ensure the VFS deletes this inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) switch (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) clear_nlink(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) nfs_dentry_handle_enoent(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) up_write(&NFS_I(d_inode(dentry))->rmdir_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) trace_nfs_rmdir_exit(dir, dentry, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) EXPORT_SYMBOL_GPL(nfs_rmdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) * Remove a file after making sure there are no pending writes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) * and after checking that the file has only one user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) * We invalidate the attribute cache and free the inode prior to the operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) * to avoid possible races if the server reuses the inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) static int nfs_safe_remove(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) struct inode *dir = d_inode(dentry->d_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) int error = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) dfprintk(VFS, "NFS: safe_remove(%pd2)\n", dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) /* If the dentry was sillyrenamed, we simply call d_delete() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) trace_nfs_remove_enter(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) if (inode != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) error = NFS_PROTO(dir)->remove(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) if (error == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) nfs_drop_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) error = NFS_PROTO(dir)->remove(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if (error == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) nfs_dentry_handle_enoent(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) trace_nfs_remove_exit(dir, dentry, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) /* We do silly rename. In case sillyrename() returns -EBUSY, the inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) * belongs to an active ".nfs..." file and we return -EBUSY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) * If sillyrename() returns 0, we do nothing, otherwise we unlink.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) int nfs_unlink(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) int need_rehash = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) dfprintk(VFS, "NFS: unlink(%s/%lu, %pd)\n", dir->i_sb->s_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) dir->i_ino, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) trace_nfs_unlink_enter(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) if (d_count(dentry) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) /* Start asynchronous writeout of the inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) write_inode_now(d_inode(dentry), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) error = nfs_sillyrename(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) if (!d_unhashed(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) __d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) need_rehash = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) error = nfs_safe_remove(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) if (!error || error == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) } else if (need_rehash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) d_rehash(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) trace_nfs_unlink_exit(dir, dentry, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) EXPORT_SYMBOL_GPL(nfs_unlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) * To create a symbolic link, most file systems instantiate a new inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) * add a page to it containing the path, then write it out to the disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) * using prepare_write/commit_write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) * Unfortunately the NFS client can't create the in-core inode first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) * because it needs a file handle to create an in-core inode (see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) * fs/nfs/inode.c:nfs_fhget). We only have a file handle *after* the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) * symlink request has completed on the server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) * So instead we allocate a raw page, copy the symname into it, then do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) * the SYMLINK request with the page as the buffer. If it succeeds, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) * now have a new file handle and can instantiate an in-core NFS inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) * and move the raw page into its mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) char *kaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) struct iattr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) unsigned int pathlen = strlen(symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) dfprintk(VFS, "NFS: symlink(%s/%lu, %pd, %s)\n", dir->i_sb->s_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) dir->i_ino, dentry, symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) if (pathlen > PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) attr.ia_mode = S_IFLNK | S_IRWXUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) attr.ia_valid = ATTR_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) page = alloc_page(GFP_USER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) kaddr = page_address(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) memcpy(kaddr, symname, pathlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (pathlen < PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) trace_nfs_symlink_enter(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) trace_nfs_symlink_exit(dir, dentry, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) if (error != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) dfprintk(VFS, "NFS: symlink(%s/%lu, %pd, %s) error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) dir->i_sb->s_id, dir->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) dentry, symname, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) __free_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) * No big deal if we can't add this page to the page cache here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) * READLINK will get the missing page from the server if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) if (!add_to_page_cache_lru(page, d_inode(dentry)->i_mapping, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) GFP_KERNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) SetPageUptodate(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) unlock_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) * add_to_page_cache_lru() grabs an extra page refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) * Drop it here to avoid leaking this page later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) put_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) __free_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) EXPORT_SYMBOL_GPL(nfs_symlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) struct inode *inode = d_inode(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) dfprintk(VFS, "NFS: link(%pd2 -> %pd2)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) old_dentry, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) trace_nfs_link_enter(inode, dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) d_drop(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (S_ISREG(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) nfs_sync_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) if (error == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) ihold(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) d_add(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) trace_nfs_link_exit(inode, dir, dentry, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) EXPORT_SYMBOL_GPL(nfs_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) * RENAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) * FIXME: Some nfsds, like the Linux user space nfsd, may generate a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) * different file handle for the same inode after a rename (e.g. when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) * moving to a different directory). A fail-safe method to do so would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) * be to look up old_dir/old_name, create a link to new_dir/new_name and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) * rename the old file using the sillyrename stuff. This way, the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) * file in old_dir will go away when the last process iput()s the inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) * FIXED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) * It actually works quite well. One needs to have the possibility for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) * at least one ".nfs..." file in each directory the file ever gets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) * moved or linked to which happens automagically with the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) * implementation that only depends on the dcache stuff instead of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) * using the inode layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) * Unfortunately, things are a little more complicated than indicated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) * above. For a cross-directory move, we want to make sure we can get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) * rid of the old inode after the operation. This means there must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) * no pending writes (if it's a file), and the use count must be 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) * If these conditions are met, we can drop the dentries before doing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) * the rename.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) struct inode *new_dir, struct dentry *new_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) struct inode *old_inode = d_inode(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) struct inode *new_inode = d_inode(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) struct dentry *dentry = NULL, *rehash = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) struct rpc_task *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) int error = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) dfprintk(VFS, "NFS: rename(%pd2 -> %pd2, ct=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) old_dentry, new_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) d_count(new_dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) trace_nfs_rename_enter(old_dir, old_dentry, new_dir, new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) * For non-directories, check whether the target is busy and if so,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) * make a copy of the dentry and then do a silly-rename. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) * silly-rename succeeds, the copied dentry is hashed and becomes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) * the new target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) if (new_inode && !S_ISDIR(new_inode->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) * To prevent any new references to the target during the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) * rename, we unhash the dentry in advance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) if (!d_unhashed(new_dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) d_drop(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) rehash = new_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) if (d_count(new_dentry) > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) /* copy the target dentry's name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) dentry = d_alloc(new_dentry->d_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) &new_dentry->d_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) if (!dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) /* silly-rename the existing target ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) err = nfs_sillyrename(new_dir, new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) new_dentry = dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) rehash = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) new_inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) if (S_ISREG(old_inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) nfs_sync_inode(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) if (IS_ERR(task)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) error = PTR_ERR(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) error = rpc_wait_for_completion_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) if (error != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) ((struct nfs_renamedata *)task->tk_calldata)->cancelled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) /* Paired with the atomic_dec_and_test() barrier in rpc_do_put_task() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) error = task->tk_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) rpc_put_task(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) /* Ensure the inode attributes are revalidated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) if (error == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) spin_lock(&old_inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) NFS_I(old_inode)->attr_gencount = nfs_inc_attr_generation_counter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) NFS_I(old_inode)->cache_validity |= NFS_INO_INVALID_CHANGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) | NFS_INO_INVALID_CTIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) | NFS_INO_REVAL_FORCED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) spin_unlock(&old_inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) if (rehash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) d_rehash(rehash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) trace_nfs_rename_exit(old_dir, old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) new_dir, new_dentry, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) if (new_inode != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) nfs_drop_nlink(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) * The d_move() should be here instead of in an async RPC completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) * handler because we need the proper locks to move the dentry. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) * we're interrupted by a signal, the async RPC completion handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) * should mark the directories for revalidation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) d_move(old_dentry, new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) nfs_set_verifier(old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) nfs_save_change_attribute(new_dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) } else if (error == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) nfs_dentry_handle_enoent(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) /* new dentry created? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) if (dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) dput(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) EXPORT_SYMBOL_GPL(nfs_rename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) static DEFINE_SPINLOCK(nfs_access_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) static LIST_HEAD(nfs_access_lru_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) static atomic_long_t nfs_access_nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) static unsigned long nfs_access_max_cachesize = 4*1024*1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) module_param(nfs_access_max_cachesize, ulong, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access maximum total cache length");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) static void nfs_access_free_entry(struct nfs_access_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) put_cred(entry->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) kfree_rcu(entry, rcu_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) smp_mb__before_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) atomic_long_dec(&nfs_access_nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) smp_mb__after_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) static void nfs_access_free_list(struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) struct nfs_access_entry *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) while (!list_empty(head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) cache = list_entry(head->next, struct nfs_access_entry, lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) list_del(&cache->lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) nfs_access_free_entry(cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) nfs_do_access_cache_scan(unsigned int nr_to_scan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) struct nfs_inode *nfsi, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) struct nfs_access_entry *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) long freed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) spin_lock(&nfs_access_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) list_for_each_entry_safe(nfsi, next, &nfs_access_lru_list, access_cache_inode_lru) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) if (nr_to_scan-- == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) inode = &nfsi->vfs_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) if (list_empty(&nfsi->access_cache_entry_lru))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) goto remove_lru_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) cache = list_entry(nfsi->access_cache_entry_lru.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) struct nfs_access_entry, lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) list_move(&cache->lru, &head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) rb_erase(&cache->rb_node, &nfsi->access_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) freed++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) if (!list_empty(&nfsi->access_cache_entry_lru))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) list_move_tail(&nfsi->access_cache_inode_lru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) &nfs_access_lru_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) remove_lru_entry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) list_del_init(&nfsi->access_cache_inode_lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) smp_mb__before_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) clear_bit(NFS_INO_ACL_LRU_SET, &nfsi->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) smp_mb__after_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) spin_unlock(&nfs_access_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) nfs_access_free_list(&head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) return freed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) nfs_access_cache_scan(struct shrinker *shrink, struct shrink_control *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) int nr_to_scan = sc->nr_to_scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) gfp_t gfp_mask = sc->gfp_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) return SHRINK_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) return nfs_do_access_cache_scan(nr_to_scan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) nfs_access_cache_count(struct shrinker *shrink, struct shrink_control *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) return vfs_pressure_ratio(atomic_long_read(&nfs_access_nr_entries));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) nfs_access_cache_enforce_limit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) long nr_entries = atomic_long_read(&nfs_access_nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) unsigned long diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) unsigned int nr_to_scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) if (nr_entries < 0 || nr_entries <= nfs_access_max_cachesize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) nr_to_scan = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) diff = nr_entries - nfs_access_max_cachesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) if (diff < nr_to_scan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) nr_to_scan = diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) nfs_do_access_cache_scan(nr_to_scan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) static void __nfs_access_zap_cache(struct nfs_inode *nfsi, struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) struct rb_root *root_node = &nfsi->access_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) struct nfs_access_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) /* Unhook entries from the cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) while ((n = rb_first(root_node)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) entry = rb_entry(n, struct nfs_access_entry, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) rb_erase(n, root_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) list_move(&entry->lru, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) void nfs_access_zap_cache(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) LIST_HEAD(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) if (test_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) /* Remove from global LRU init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) spin_lock(&nfs_access_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) list_del_init(&NFS_I(inode)->access_cache_inode_lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) __nfs_access_zap_cache(NFS_I(inode), &head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) spin_unlock(&nfs_access_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) nfs_access_free_list(&head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) EXPORT_SYMBOL_GPL(nfs_access_zap_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, const struct cred *cred)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) struct rb_node *n = NFS_I(inode)->access_cache.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) while (n != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) struct nfs_access_entry *entry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) rb_entry(n, struct nfs_access_entry, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) int cmp = cred_fscmp(cred, entry->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) if (cmp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) n = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) else if (cmp > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) n = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) static int nfs_access_get_cached_locked(struct inode *inode, const struct cred *cred, u32 *mask, bool may_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) struct nfs_access_entry *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) bool retry = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) if (nfsi->cache_validity & NFS_INO_INVALID_ACCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) goto out_zap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) cache = nfs_access_search_rbtree(inode, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) if (cache == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) /* Found an entry, is our attribute cache valid? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) if (!nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) if (!retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) err = -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) if (!may_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) retry = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) *mask = cache->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) list_move_tail(&cache->lru, &nfsi->access_cache_entry_lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) out_zap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) nfs_access_zap_cache(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cred, u32 *mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) /* Only check the most recently returned cache entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) * but do it without locking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) struct nfs_access_entry *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) int err = -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) struct list_head *lh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) if (nfsi->cache_validity & NFS_INO_INVALID_ACCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) lh = rcu_dereference(list_tail_rcu(&nfsi->access_cache_entry_lru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) cache = list_entry(lh, struct nfs_access_entry, lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) if (lh == &nfsi->access_cache_entry_lru ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) cred_fscmp(cred, cache->cred) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) if (cache == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) *mask = cache->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) int nfs_access_get_cached(struct inode *inode, const struct cred *cred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) u32 *mask, bool may_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) status = nfs_access_get_cached_rcu(inode, cred, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) if (status != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) status = nfs_access_get_cached_locked(inode, cred, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) may_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) EXPORT_SYMBOL_GPL(nfs_access_get_cached);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) struct nfs_inode *nfsi = NFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) struct rb_root *root_node = &nfsi->access_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) struct rb_node **p = &root_node->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) struct rb_node *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) struct nfs_access_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) int cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) spin_lock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) while (*p != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) entry = rb_entry(parent, struct nfs_access_entry, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) cmp = cred_fscmp(set->cred, entry->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) if (cmp < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) p = &parent->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) else if (cmp > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) p = &parent->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) rb_link_node(&set->rb_node, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) rb_insert_color(&set->rb_node, root_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) list_add_tail(&set->lru, &nfsi->access_cache_entry_lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) rb_replace_node(parent, &set->rb_node, root_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) list_add_tail(&set->lru, &nfsi->access_cache_entry_lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) list_del(&entry->lru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) spin_unlock(&inode->i_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) nfs_access_free_entry(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) if (cache == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) RB_CLEAR_NODE(&cache->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) cache->cred = get_cred(set->cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) cache->mask = set->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) /* The above field assignments must be visible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) * before this item appears on the lru. We cannot easily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) * use rcu_assign_pointer, so just force the memory barrier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) nfs_access_add_rbtree(inode, cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) /* Update accounting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) smp_mb__before_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) atomic_long_inc(&nfs_access_nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) smp_mb__after_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) /* Add inode to global LRU list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) if (!test_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) spin_lock(&nfs_access_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) list_add_tail(&NFS_I(inode)->access_cache_inode_lru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) &nfs_access_lru_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) spin_unlock(&nfs_access_lru_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) nfs_access_cache_enforce_limit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) EXPORT_SYMBOL_GPL(nfs_access_add_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) #define NFS_MAY_READ (NFS_ACCESS_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) #define NFS_MAY_WRITE (NFS_ACCESS_MODIFY | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) NFS_ACCESS_EXTEND | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) NFS_ACCESS_DELETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) #define NFS_FILE_MAY_WRITE (NFS_ACCESS_MODIFY | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) NFS_ACCESS_EXTEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) #define NFS_DIR_MAY_WRITE NFS_MAY_WRITE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) #define NFS_MAY_LOOKUP (NFS_ACCESS_LOOKUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) #define NFS_MAY_EXECUTE (NFS_ACCESS_EXECUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) nfs_access_calc_mask(u32 access_result, umode_t umode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) int mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) if (access_result & NFS_MAY_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) mask |= MAY_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) if (S_ISDIR(umode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) if ((access_result & NFS_DIR_MAY_WRITE) == NFS_DIR_MAY_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) mask |= MAY_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) if ((access_result & NFS_MAY_LOOKUP) == NFS_MAY_LOOKUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) mask |= MAY_EXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) } else if (S_ISREG(umode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) if ((access_result & NFS_FILE_MAY_WRITE) == NFS_FILE_MAY_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) mask |= MAY_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) if ((access_result & NFS_MAY_EXECUTE) == NFS_MAY_EXECUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) mask |= MAY_EXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) } else if (access_result & NFS_MAY_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) mask |= MAY_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) entry->mask = access_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) EXPORT_SYMBOL_GPL(nfs_access_set_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) struct nfs_access_entry cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) bool may_block = (mask & MAY_NOT_BLOCK) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) int cache_mask = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) trace_nfs_access_enter(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) status = nfs_access_get_cached(inode, cred, &cache.mask, may_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) goto out_cached;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) status = -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) if (!may_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) * Determine which access bits we want to ask for...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) cache.mask = NFS_ACCESS_READ | NFS_ACCESS_MODIFY | NFS_ACCESS_EXTEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) if (nfs_server_capable(inode, NFS_CAP_XATTR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) cache.mask |= NFS_ACCESS_XAREAD | NFS_ACCESS_XAWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) NFS_ACCESS_XALIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) if (S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) cache.mask |= NFS_ACCESS_DELETE | NFS_ACCESS_LOOKUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) cache.mask |= NFS_ACCESS_EXECUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) cache.cred = cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) status = NFS_PROTO(inode)->access(inode, &cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) if (status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) if (status == -ESTALE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) if (!S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) nfs_set_inode_stale(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) nfs_zap_caches(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) nfs_access_add_cache(inode, &cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) out_cached:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) cache_mask = nfs_access_calc_mask(cache.mask, inode->i_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) status = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) trace_nfs_access_exit(inode, mask, cache_mask, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) static int nfs_open_permission_mask(int openflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) int mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) if (openflags & __FMODE_EXEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) /* ONLY check exec rights */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) mask = MAY_EXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) if ((openflags & O_ACCMODE) != O_WRONLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) mask |= MAY_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) if ((openflags & O_ACCMODE) != O_RDONLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) mask |= MAY_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) return mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) EXPORT_SYMBOL_GPL(nfs_may_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) static int nfs_execute_ok(struct inode *inode, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) struct nfs_server *server = NFS_SERVER(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) if (S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_OTHER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) if (mask & MAY_NOT_BLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) ret = __nfs_revalidate_inode(server, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) if (ret == 0 && !execute_ok(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) ret = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) int nfs_permission(struct inode *inode, int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) const struct cred *cred = current_cred();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) nfs_inc_stats(inode, NFSIOS_VFSACCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) /* Is this sys_access() ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) if (mask & (MAY_ACCESS | MAY_CHDIR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) goto force_lookup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) switch (inode->i_mode & S_IFMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) case S_IFLNK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) case S_IFREG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) if ((mask & MAY_OPEN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) case S_IFDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) * Optimize away all write operations, since the server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) * will check permissions when we perform the op.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) if ((mask & MAY_WRITE) && !(mask & MAY_READ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) force_lookup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) if (!NFS_PROTO(inode)->access)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) goto out_notsup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) res = nfs_do_access(inode, cred, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) if (!res && (mask & MAY_EXEC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) res = nfs_execute_ok(inode, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) dfprintk(VFS, "NFS: permission(%s/%lu), mask=0x%x, res=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) inode->i_sb->s_id, inode->i_ino, mask, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) out_notsup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) if (mask & MAY_NOT_BLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) res = nfs_revalidate_inode(NFS_SERVER(inode), inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) if (res == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) res = generic_permission(inode, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) EXPORT_SYMBOL_GPL(nfs_permission);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) * Local variables:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) * version-control: t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) * kept-new-versions: 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) * End:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) */