NFS: Move the delegation return down into nfs4_proc_remove()
authorTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 20 Mar 2018 20:43:15 +0000 (16:43 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Tue, 10 Apr 2018 20:06:22 +0000 (16:06 -0400)
Move the delegation return out of generic code and down into the
NFSv4 specific unlink code.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/dir.c
fs/nfs/nfs3proc.c
fs/nfs/nfs4proc.c
fs/nfs/proc.c
include/linux/nfs_xdr.h

index b4549e5..eb9d782 100644 (file)
@@ -1798,12 +1798,11 @@ static int nfs_safe_remove(struct dentry *dentry)
 
        trace_nfs_remove_enter(dir, dentry);
        if (inode != NULL) {
-               NFS_PROTO(inode)->return_delegation(inode);
-               error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
+               error = NFS_PROTO(dir)->remove(dir, dentry);
                if (error == 0)
                        nfs_drop_nlink(inode);
        } else
-               error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
+               error = NFS_PROTO(dir)->remove(dir, dentry);
        if (error == -ENOENT)
                nfs_dentry_handle_enoent(dentry);
        trace_nfs_remove_exit(dir, dentry, error);
index 7327930..f4ead71 100644 (file)
@@ -383,11 +383,11 @@ out:
 }
 
 static int
-nfs3_proc_remove(struct inode *dir, const struct qstr *name)
+nfs3_proc_remove(struct inode *dir, struct dentry *dentry)
 {
        struct nfs_removeargs arg = {
                .fh = NFS_FH(dir),
-               .name = *name,
+               .name = dentry->d_name,
        };
        struct nfs_removeres res;
        struct rpc_message msg = {
@@ -397,7 +397,7 @@ nfs3_proc_remove(struct inode *dir, const struct qstr *name)
        };
        int status = -ENOMEM;
 
-       dprintk("NFS call  remove %s\n", name->name);
+       dprintk("NFS call  remove %pd2\n", dentry);
        res.dir_attr = nfs_alloc_fattr();
        if (res.dir_attr == NULL)
                goto out;
index f4216b6..810ebd2 100644 (file)
@@ -4200,10 +4200,28 @@ static int _nfs4_proc_remove(struct inode *dir, const struct qstr *name)
        return status;
 }
 
-static int nfs4_proc_remove(struct inode *dir, const struct qstr *name)
+static int nfs4_proc_remove(struct inode *dir, struct dentry *dentry)
 {
        struct nfs4_exception exception = { };
+       struct inode *inode = d_inode(dentry);
        int err;
+
+       if (inode)
+               nfs4_inode_return_delegation(inode);
+       do {
+               err = _nfs4_proc_remove(dir, &dentry->d_name);
+               trace_nfs4_remove(dir, &dentry->d_name, err);
+               err = nfs4_handle_exception(NFS_SERVER(dir), err,
+                               &exception);
+       } while (exception.retry);
+       return err;
+}
+
+static int nfs4_proc_rmdir(struct inode *dir, const struct qstr *name)
+{
+       struct nfs4_exception exception = { };
+       int err;
+
        do {
                err = _nfs4_proc_remove(dir, name);
                trace_nfs4_remove(dir, name, err);
@@ -9601,7 +9619,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
        .link           = nfs4_proc_link,
        .symlink        = nfs4_proc_symlink,
        .mkdir          = nfs4_proc_mkdir,
-       .rmdir          = nfs4_proc_remove,
+       .rmdir          = nfs4_proc_rmdir,
        .readdir        = nfs4_proc_readdir,
        .mknod          = nfs4_proc_mknod,
        .statfs         = nfs4_proc_statfs,
index f7fd919..b2e81a1 100644 (file)
@@ -300,11 +300,11 @@ out:
 }
   
 static int
-nfs_proc_remove(struct inode *dir, const struct qstr *name)
+nfs_proc_remove(struct inode *dir, struct dentry *dentry)
 {
        struct nfs_removeargs arg = {
                .fh = NFS_FH(dir),
-               .name = *name,
+               .name = dentry->d_name,
        };
        struct rpc_message msg = { 
                .rpc_proc = &nfs_procedures[NFSPROC_REMOVE],
@@ -312,7 +312,7 @@ nfs_proc_remove(struct inode *dir, const struct qstr *name)
        };
        int                     status;
 
-       dprintk("NFS call  remove %s\n", name->name);
+       dprintk("NFS call  remove %pd2\n",dentry);
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        nfs_mark_for_revalidate(dir);
 
index 6959968..3ebf14b 100644 (file)
@@ -1590,7 +1590,7 @@ struct nfs_rpc_ops {
                            unsigned int);
        int     (*create)  (struct inode *, struct dentry *,
                            struct iattr *, int);
-       int     (*remove)  (struct inode *, const struct qstr *);
+       int     (*remove)  (struct inode *, struct dentry *);
        void    (*unlink_setup)  (struct rpc_message *, struct inode *dir);
        void    (*unlink_rpc_prepare) (struct rpc_task *, struct nfs_unlinkdata *);
        int     (*unlink_done) (struct rpc_task *, struct inode *);