NFSD: Add helper to decode OPEN's open_claim4 argument
authorChuck Lever <chuck.lever@oracle.com>
Mon, 16 Nov 2020 22:45:04 +0000 (17:45 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 30 Nov 2020 19:46:39 +0000 (14:46 -0500)
Refactor for clarity.

Note that op_fname is the only instance of an NFSv4 filename stored
in a struct xdr_netobj. Convert it to a u32/char * pair so that the
new nfsd4_decode_filename() helper can be used.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4xdr.c
fs/nfsd/xdr4.h

index df2d6f7..56d074a 100644 (file)
@@ -257,8 +257,8 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
                 * in NFSv4 as in v3 except EXCLUSIVE4_1.
                 */
                current->fs->umask = open->op_umask;
-               status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
-                                       open->op_fname.len, &open->op_iattr,
+               status = do_nfsd_create(rqstp, current_fh, open->op_fname,
+                                       open->op_fnamelen, &open->op_iattr,
                                        *resfh, open->op_createmode,
                                        (u32 *)open->op_verf.data,
                                        &open->op_truncate, &open->op_created);
@@ -283,7 +283,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
                 * a chance to an acquire a delegation if appropriate.
                 */
                status = nfsd_lookup(rqstp, current_fh,
-                                    open->op_fname.data, open->op_fname.len, *resfh);
+                                    open->op_fname, open->op_fnamelen, *resfh);
        if (status)
                goto out;
        status = nfsd_check_obj_isreg(*resfh);
@@ -360,7 +360,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        bool reclaim = false;
 
        dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
-               (int)open->op_fname.len, open->op_fname.data,
+               (int)open->op_fnamelen, open->op_fname,
                open->op_openowner);
 
        /* This check required by spec. */
index fe2c71a..c15d5f8 100644 (file)
@@ -1073,6 +1073,55 @@ static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
 }
 
 static __be32
+nfsd4_decode_open_claim4(struct nfsd4_compoundargs *argp,
+                        struct nfsd4_open *open)
+{
+       __be32 status;
+
+       if (xdr_stream_decode_u32(argp->xdr, &open->op_claim_type) < 0)
+               return nfserr_bad_xdr;
+       switch (open->op_claim_type) {
+       case NFS4_OPEN_CLAIM_NULL:
+       case NFS4_OPEN_CLAIM_DELEGATE_PREV:
+               status = nfsd4_decode_component4(argp, &open->op_fname,
+                                                &open->op_fnamelen);
+               if (status)
+                       return status;
+               break;
+       case NFS4_OPEN_CLAIM_PREVIOUS:
+               if (xdr_stream_decode_u32(argp->xdr, &open->op_delegate_type) < 0)
+                       return nfserr_bad_xdr;
+               break;
+       case NFS4_OPEN_CLAIM_DELEGATE_CUR:
+               status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
+               if (status)
+                       return status;
+               status = nfsd4_decode_component4(argp, &open->op_fname,
+                                                &open->op_fnamelen);
+               if (status)
+                       return status;
+               break;
+       case NFS4_OPEN_CLAIM_FH:
+       case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
+               if (argp->minorversion < 1)
+                       return nfserr_bad_xdr;
+               /* void */
+               break;
+       case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
+               if (argp->minorversion < 1)
+                       return nfserr_bad_xdr;
+               status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
+               if (status)
+                       return status;
+               break;
+       default:
+               return nfserr_bad_xdr;
+       }
+
+       return nfs_ok;
+}
+
+static __be32
 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 {
        DECODE_HEAD;
@@ -1102,51 +1151,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
        status = nfsd4_decode_openflag4(argp, open);
        if (status)
                return status;
-
-       /* open_claim */
-       READ_BUF(4);
-       open->op_claim_type = be32_to_cpup(p++);
-       switch (open->op_claim_type) {
-       case NFS4_OPEN_CLAIM_NULL:
-       case NFS4_OPEN_CLAIM_DELEGATE_PREV:
-               READ_BUF(4);
-               open->op_fname.len = be32_to_cpup(p++);
-               READ_BUF(open->op_fname.len);
-               SAVEMEM(open->op_fname.data, open->op_fname.len);
-               if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
-                       return status;
-               break;
-       case NFS4_OPEN_CLAIM_PREVIOUS:
-               READ_BUF(4);
-               open->op_delegate_type = be32_to_cpup(p++);
-               break;
-       case NFS4_OPEN_CLAIM_DELEGATE_CUR:
-               status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
-               if (status)
-                       return status;
-               READ_BUF(4);
-               open->op_fname.len = be32_to_cpup(p++);
-               READ_BUF(open->op_fname.len);
-               SAVEMEM(open->op_fname.data, open->op_fname.len);
-               if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
-                       return status;
-               break;
-       case NFS4_OPEN_CLAIM_FH:
-       case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
-               if (argp->minorversion < 1)
-                       goto xdr_error;
-               /* void */
-               break;
-       case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
-               if (argp->minorversion < 1)
-                       goto xdr_error;
-               status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
-               if (status)
-                       return status;
-               break;
-       default:
-               goto xdr_error;
-       }
+       status = nfsd4_decode_open_claim4(argp, open);
 
        DECODE_TAIL;
 }
index 0eb13bd..6245004 100644 (file)
@@ -252,7 +252,8 @@ struct nfsd4_listxattrs {
 
 struct nfsd4_open {
        u32             op_claim_type;      /* request */
-       struct xdr_netobj op_fname;         /* request - everything but CLAIM_PREV */
+       u32             op_fnamelen;
+       char *          op_fname;           /* request - everything but CLAIM_PREV */
        u32             op_delegate_type;   /* request - CLAIM_PREV only */
        stateid_t       op_delegate_stateid; /* request - response */
        u32             op_why_no_deleg;    /* response - DELEG_NONE_EXT only */