NFSv4: Fix sillyrename to return the delegation when appropriate
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 30 May 2018 20:11:52 +0000 (16:11 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 31 May 2018 19:02:16 +0000 (15:02 -0400)
Ensure that we pass down the inode of the file being deleted so
that we can return any delegation being held.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/nfs3proc.c
fs/nfs/nfs4proc.c
fs/nfs/proc.c
fs/nfs/unlink.c
include/linux/nfs_xdr.h

index 6ed6a41..5645ef4 100644 (file)
@@ -414,7 +414,9 @@ out:
 }
 
 static void
-nfs3_proc_unlink_setup(struct rpc_message *msg, struct dentry *dentry)
+nfs3_proc_unlink_setup(struct rpc_message *msg,
+               struct dentry *dentry,
+               struct inode *inode)
 {
        msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
 }
index 844eafb..d21c5e4 100644 (file)
@@ -4260,11 +4260,12 @@ static int nfs4_proc_rmdir(struct inode *dir, const struct qstr *name)
        return err;
 }
 
-static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dentry)
+static void nfs4_proc_unlink_setup(struct rpc_message *msg,
+               struct dentry *dentry,
+               struct inode *inode)
 {
        struct nfs_removeargs *args = msg->rpc_argp;
        struct nfs_removeres *res = msg->rpc_resp;
-       struct inode *inode = d_inode(dentry);
 
        res->server = NFS_SB(dentry->d_sb);
        msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
index 80c350b..763f77e 100644 (file)
@@ -321,7 +321,9 @@ nfs_proc_remove(struct inode *dir, struct dentry *dentry)
 }
 
 static void
-nfs_proc_unlink_setup(struct rpc_message *msg, struct dentry *dentry)
+nfs_proc_unlink_setup(struct rpc_message *msg,
+               struct dentry *dentry,
+               struct inode *inode)
 {
        msg->rpc_proc = &nfs_procedures[NFSPROC_REMOVE];
 }
index bf54fc9..6a73b8c 100644 (file)
@@ -85,7 +85,7 @@ static const struct rpc_call_ops nfs_unlink_ops = {
        .rpc_call_prepare = nfs_unlink_prepare,
 };
 
-static void nfs_do_call_unlink(struct nfs_unlinkdata *data)
+static void nfs_do_call_unlink(struct inode *inode, struct nfs_unlinkdata *data)
 {
        struct rpc_message msg = {
                .rpc_argp = &data->args,
@@ -105,7 +105,7 @@ static void nfs_do_call_unlink(struct nfs_unlinkdata *data)
        data->args.fh = NFS_FH(dir);
        nfs_fattr_init(data->res.dir_attr);
 
-       NFS_PROTO(dir)->unlink_setup(&msg, data->dentry);
+       NFS_PROTO(dir)->unlink_setup(&msg, data->dentry, inode);
 
        task_setup_data.rpc_client = NFS_CLIENT(dir);
        task = rpc_run_task(&task_setup_data);
@@ -113,7 +113,7 @@ static void nfs_do_call_unlink(struct nfs_unlinkdata *data)
                rpc_put_task_async(task);
 }
 
-static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
+static int nfs_call_unlink(struct dentry *dentry, struct inode *inode, struct nfs_unlinkdata *data)
 {
        struct inode *dir = d_inode(dentry->d_parent);
        struct dentry *alias;
@@ -153,7 +153,7 @@ static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
                return ret;
        }
        data->dentry = alias;
-       nfs_do_call_unlink(data);
+       nfs_do_call_unlink(inode, data);
        return 1;
 }
 
@@ -231,7 +231,7 @@ nfs_complete_unlink(struct dentry *dentry, struct inode *inode)
        dentry->d_fsdata = NULL;
        spin_unlock(&dentry->d_lock);
 
-       if (NFS_STALE(inode) || !nfs_call_unlink(dentry, data))
+       if (NFS_STALE(inode) || !nfs_call_unlink(dentry, inode, data))
                nfs_free_unlinkdata(data);
 }
 
index 52b481d..d3cefe5 100644 (file)
@@ -1591,7 +1591,7 @@ struct nfs_rpc_ops {
        int     (*create)  (struct inode *, struct dentry *,
                            struct iattr *, int);
        int     (*remove)  (struct inode *, struct dentry *);
-       void    (*unlink_setup)  (struct rpc_message *, struct dentry *);
+       void    (*unlink_setup)  (struct rpc_message *, struct dentry *, struct inode *);
        void    (*unlink_rpc_prepare) (struct rpc_task *, struct nfs_unlinkdata *);
        int     (*unlink_done) (struct rpc_task *, struct inode *);
        void    (*rename_setup)  (struct rpc_message *msg,