Commit 2da21167 authored by Anna Schumaker's avatar Anna Schumaker Committed by Trond Myklebust
Browse files

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: default avatarAnna Schumaker <anna.schumaker@oracle.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 156b0948
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -483,7 +483,8 @@ nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir)
static void
nfs3_proc_rename_setup(struct rpc_message *msg,
		struct dentry *old_dentry,
		struct dentry *new_dentry)
		struct dentry *new_dentry,
		struct inode *same_parent)
{
	msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME];
}
+4 −1
Original line number Diff line number Diff line
@@ -5060,7 +5060,8 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)

static void nfs4_proc_rename_setup(struct rpc_message *msg,
		struct dentry *old_dentry,
		struct dentry *new_dentry)
		struct dentry *new_dentry,
		struct inode *same_parent)
{
	struct nfs_renameargs *arg = msg->rpc_argp;
	struct nfs_renameres *res = msg->rpc_resp;
@@ -5071,6 +5072,8 @@ static void nfs4_proc_rename_setup(struct rpc_message *msg,
		nfs4_inode_make_writeable(old_inode);
	if (new_inode)
		nfs4_inode_return_delegation(new_inode);
	if (same_parent)
		nfs_request_directory_delegation(same_parent);
	msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME];
	res->server = NFS_SB(old_dentry->d_sb);
	nfs4_init_sequence(&arg->seq_args, &res->seq_res, 1, 0);
+2 −1
Original line number Diff line number Diff line
@@ -353,7 +353,8 @@ static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir)
static void
nfs_proc_rename_setup(struct rpc_message *msg,
		struct dentry *old_dentry,
		struct dentry *new_dentry)
		struct dentry *new_dentry,
		struct inode *same_parent)
{
	msg->rpc_proc = &nfs_procedures[NFSPROC_RENAME];
}
+2 −1
Original line number Diff line number Diff line
@@ -390,7 +390,8 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,

	nfs_sb_active(old_dir->i_sb);

	NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry);
	NFS_PROTO(data->old_dir)->rename_setup(&msg, old_dentry, new_dentry,
					old_dir == new_dir ? old_dir : NULL);

	return rpc_run_task(&task_setup_data);
}
+2 −1
Original line number Diff line number Diff line
@@ -1808,7 +1808,8 @@ struct nfs_rpc_ops {
	int	(*unlink_done) (struct rpc_task *, struct inode *);
	void	(*rename_setup)  (struct rpc_message *msg,
			struct dentry *old_dentry,
			struct dentry *new_dentry);
			struct dentry *new_dentry,
			struct inode *same_parent);
	void	(*rename_rpc_prepare)(struct rpc_task *task, struct nfs_renamedata *);
	int	(*rename_done) (struct rpc_task *task, struct inode *old_dir, struct inode *new_dir);
	int	(*link)    (struct inode *, struct inode *, const struct qstr *);