NFSD: Pass the target nfsd_file to nfsd_commit()
authorChuck Lever <chuck.lever@oracle.com>
Fri, 28 Oct 2022 14:46:38 +0000 (10:46 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Jan 2023 10:58:25 +0000 (11:58 +0100)
[ Upstream commit c252849082ff525af18b4f253b3c9ece94e951ed ]

In a moment I'm going to introduce separate nfsd_file types, one of
which is garbage-collected; the other, not. The garbage-collected
variety is to be used by NFSv2 and v3, and the non-garbage-collected
variety is to be used by NFSv4.

nfsd_commit() is invoked by both NFSv3 and NFSv4 consumers. We want
nfsd_commit() to find and use the correct variety of cached
nfsd_file object for the NFS version that is in use.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Tested-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: NeilBrown <neilb@suse.de>
Stable-dep-of: 0b3a551fa58b ("nfsd: fix handling of cached open files in nfsd4_open codepath")
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfsd/nfs3proc.c
fs/nfsd/nfs4proc.c
fs/nfsd/vfs.c
fs/nfsd/vfs.h

index 923d9a8..ff29205 100644 (file)
@@ -13,6 +13,7 @@
 #include "cache.h"
 #include "xdr3.h"
 #include "vfs.h"
+#include "filecache.h"
 
 #define NFSDDBG_FACILITY               NFSDDBG_PROC
 
@@ -763,6 +764,7 @@ nfsd3_proc_commit(struct svc_rqst *rqstp)
 {
        struct nfsd3_commitargs *argp = rqstp->rq_argp;
        struct nfsd3_commitres *resp = rqstp->rq_resp;
+       struct nfsd_file *nf;
 
        dprintk("nfsd: COMMIT(3)   %s %u@%Lu\n",
                                SVCFH_fmt(&argp->fh),
@@ -770,8 +772,14 @@ nfsd3_proc_commit(struct svc_rqst *rqstp)
                                (unsigned long long) argp->offset);
 
        fh_copy(&resp->fh, &argp->fh);
-       resp->status = nfsd_commit(rqstp, &resp->fh, argp->offset,
+       resp->status = nfsd_file_acquire(rqstp, &resp->fh, NFSD_MAY_WRITE |
+                                        NFSD_MAY_NOT_BREAK_LEASE, &nf);
+       if (resp->status)
+               goto out;
+       resp->status = nfsd_commit(rqstp, &resp->fh, nf, argp->offset,
                                   argp->count, resp->verf);
+       nfsd_file_put(nf);
+out:
        return rpc_success;
 }
 
index c732952..30a08ec 100644 (file)
@@ -731,10 +731,19 @@ nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
             union nfsd4_op_u *u)
 {
        struct nfsd4_commit *commit = &u->commit;
+       struct nfsd_file *nf;
+       __be32 status;
 
-       return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
+       status = nfsd_file_acquire(rqstp, &cstate->current_fh, NFSD_MAY_WRITE |
+                                  NFSD_MAY_NOT_BREAK_LEASE, &nf);
+       if (status != nfs_ok)
+               return status;
+
+       status = nfsd_commit(rqstp, &cstate->current_fh, nf, commit->co_offset,
                             commit->co_count,
                             (__be32 *)commit->co_verf.data);
+       nfsd_file_put(nf);
+       return status;
 }
 
 static __be32
index 849a720..f191983 100644 (file)
@@ -1133,6 +1133,7 @@ out:
  * nfsd_commit - Commit pending writes to stable storage
  * @rqstp: RPC request being processed
  * @fhp: NFS filehandle
+ * @nf: target file
  * @offset: raw offset from beginning of file
  * @count: raw count of bytes to sync
  * @verf: filled in with the server's current write verifier
@@ -1149,19 +1150,13 @@ out:
  *   An nfsstat value in network byte order.
  */
 __be32
-nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, u64 offset,
-           u32 count, __be32 *verf)
+nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
+           u64 offset, u32 count, __be32 *verf)
 {
+       __be32                  err = nfs_ok;
        u64                     maxbytes;
        loff_t                  start, end;
        struct nfsd_net         *nn;
-       struct nfsd_file        *nf;
-       __be32                  err;
-
-       err = nfsd_file_acquire(rqstp, fhp,
-                       NFSD_MAY_WRITE|NFSD_MAY_NOT_BREAK_LEASE, &nf);
-       if (err)
-               goto out;
 
        /*
         * Convert the client-provided (offset, count) range to a
@@ -1202,8 +1197,6 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, u64 offset,
        } else
                nfsd_copy_write_verifier(verf, nn);
 
-       nfsd_file_put(nf);
-out:
        return err;
 }
 
index 120521b..9744b04 100644 (file)
@@ -88,7 +88,8 @@ __be32                nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
 __be32         nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
                                struct svc_fh *resfhp, struct nfsd_attrs *iap);
 __be32         nfsd_commit(struct svc_rqst *rqst, struct svc_fh *fhp,
-                               u64 offset, u32 count, __be32 *verf);
+                               struct nfsd_file *nf, u64 offset, u32 count,
+                               __be32 *verf);
 #ifdef CONFIG_NFSD_V4
 __be32         nfsd_getxattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
                            char *name, void **bufp, int *lenp);