Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFS: Request a directory delegation during RENAME

If we notice that we're renaming a file within a directory then we take
that as a sign that the user is working with the current directory and
may want a delegation to avoid extra revalidations when possible.

The nfs_request_directory_delegation() function exists within the NFS v4
module, so I add an extra flag to rename_setup() to indicate if a dentry
is being renamed within the same parent directory.

Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>

authored by

Anna Schumaker and committed by
Trond Myklebust
2da21167 156b0948

+12 -5
+2 -1
fs/nfs/nfs3proc.c
··· 483 483 static void 484 484 nfs3_proc_rename_setup(struct rpc_message *msg, 485 485 struct dentry *old_dentry, 486 - struct dentry *new_dentry) 486 + struct dentry *new_dentry, 487 + struct inode *same_parent) 487 488 { 488 489 msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME]; 489 490 }
+4 -1
fs/nfs/nfs4proc.c
··· 5060 5060 5061 5061 static void nfs4_proc_rename_setup(struct rpc_message *msg, 5062 5062 struct dentry *old_dentry, 5063 - struct dentry *new_dentry) 5063 + struct dentry *new_dentry, 5064 + struct inode *same_parent) 5064 5065 { 5065 5066 struct nfs_renameargs *arg = msg->rpc_argp; 5066 5067 struct nfs_renameres *res = msg->rpc_resp; ··· 5072 5071 nfs4_inode_make_writeable(old_inode); 5073 5072 if (new_inode) 5074 5073 nfs4_inode_return_delegation(new_inode); 5074 + if (same_parent) 5075 + nfs_request_directory_delegation(same_parent); 5075 5076 msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME]; 5076 5077 res->server = NFS_SB(old_dentry->d_sb); 5077 5078 nfs4_init_sequence(&arg->seq_args, &res->seq_res, 1, 0);
+2 -1
fs/nfs/proc.c
··· 353 353 static void 354 354 nfs_proc_rename_setup(struct rpc_message *msg, 355 355 struct dentry *old_dentry, 356 - struct dentry *new_dentry) 356 + struct dentry *new_dentry, 357 + struct inode *same_parent) 357 358 { 358 359 msg->rpc_proc = &nfs_procedures[NFSPROC_RENAME]; 359 360 }
+2 -1
fs/nfs/unlink.c
··· 390 390 391 391 nfs_sb_active(old_dir->i_sb); 392 392 393 - NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry); 393 + NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry, 394 + old_dir == new_dir ? old_dir : NULL); 394 395 395 396 return rpc_run_task(&task_setup_data); 396 397 }
+2 -1
include/linux/nfs_xdr.h
··· 1808 1808 int (*unlink_done) (struct rpc_task *, struct inode *); 1809 1809 void (*rename_setup) (struct rpc_message *msg, 1810 1810 struct dentry *old_dentry, 1811 - struct dentry *new_dentry); 1811 + struct dentry *new_dentry, 1812 + struct inode *same_parent); 1812 1813 void (*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *); 1813 1814 int (*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir); 1814 1815 int (*link) (struct inode *, struct inode *, const struct qstr *);