Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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)  */