nfsd: clean up supported attribute handling
authorJ. Bruce Fields <bfields@redhat.com>
Tue, 18 Oct 2016 18:18:40 +0000 (14:18 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Tue, 1 Nov 2016 19:47:52 +0000 (15:47 -0400)
Minor cleanup, no change in behavior.

Provide helpers for some common attribute bitmap operations.  Drop some
comments that just echo the code.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsd.h

index abb09b5..e901cf1 100644 (file)
@@ -96,33 +96,12 @@ check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 {
        struct dentry *dentry = cstate->current_fh.fh_dentry;
 
-       /*
-        * Check about attributes are supported by the NFSv4 server or not.
-        * According to spec, unsupported attributes return ERR_ATTRNOTSUPP.
-        */
-       if ((bmval[0] & ~nfsd_suppattrs0(cstate->minorversion)) ||
-           (bmval[1] & ~nfsd_suppattrs1(cstate->minorversion)) ||
-           (bmval[2] & ~nfsd_suppattrs2(cstate->minorversion)))
+       if (!nfsd_attrs_supported(cstate->minorversion, bmval))
                return nfserr_attrnotsupp;
-
-       /*
-        * Check FATTR4_WORD0_ACL can be supported
-        * in current environment or not.
-        */
-       if (bmval[0] & FATTR4_WORD0_ACL) {
-               if (!IS_POSIXACL(d_inode(dentry)))
-                       return nfserr_attrnotsupp;
-       }
-
-       /*
-        * According to spec, read-only attributes return ERR_INVAL.
-        */
-       if (writable) {
-               if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) ||
-                   (bmval[2] & ~writable[2]))
-                       return nfserr_inval;
-       }
-
+       if ((bmval[0] & FATTR4_WORD0_ACL) && !IS_POSIXACL(d_inode(dentry)))
+               return nfserr_attrnotsupp;
+       if (writable && !bmval_is_subset(bmval, writable))
+               return nfserr_inval;
        return nfs_ok;
 }
 
@@ -695,9 +674,9 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (getattr->ga_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
                return nfserr_inval;
 
-       getattr->ga_bmval[0] &= nfsd_suppattrs0(cstate->minorversion);
-       getattr->ga_bmval[1] &= nfsd_suppattrs1(cstate->minorversion);
-       getattr->ga_bmval[2] &= nfsd_suppattrs2(cstate->minorversion);
+       getattr->ga_bmval[0] &= nfsd_suppattrs[cstate->minorversion][0];
+       getattr->ga_bmval[1] &= nfsd_suppattrs[cstate->minorversion][1];
+       getattr->ga_bmval[2] &= nfsd_suppattrs[cstate->minorversion][2];
 
        getattr->ga_fhp = &cstate->current_fh;
        return nfs_ok;
@@ -799,9 +778,9 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
                return nfserr_inval;
 
-       readdir->rd_bmval[0] &= nfsd_suppattrs0(cstate->minorversion);
-       readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion);
-       readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion);
+       readdir->rd_bmval[0] &= nfsd_suppattrs[cstate->minorversion][0];
+       readdir->rd_bmval[1] &= nfsd_suppattrs[cstate->minorversion][1];
+       readdir->rd_bmval[2] &= nfsd_suppattrs[cstate->minorversion][2];
 
        if ((cookie == 1) || (cookie == 2) ||
            (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE)))
index c2d2895..a99bbb8 100644 (file)
 
 #define NFSDDBG_FACILITY               NFSDDBG_XDR
 
+u32 nfsd_suppattrs[3][3] = {
+       {NFSD4_SUPPORTED_ATTRS_WORD0,
+        NFSD4_SUPPORTED_ATTRS_WORD1,
+        NFSD4_SUPPORTED_ATTRS_WORD2},
+
+       {NFSD4_1_SUPPORTED_ATTRS_WORD0,
+        NFSD4_1_SUPPORTED_ATTRS_WORD1,
+        NFSD4_1_SUPPORTED_ATTRS_WORD2},
+
+       {NFSD4_1_SUPPORTED_ATTRS_WORD0,
+        NFSD4_1_SUPPORTED_ATTRS_WORD1,
+        NFSD4_2_SUPPORTED_ATTRS_WORD2},
+};
+
 /*
  * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
  * directory in order to indicate to the client that a filesystem boundary is present
@@ -2340,9 +2354,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
        struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 
        BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
-       BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
-       BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion));
-       BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
+       BUG_ON(!nfsd_attrs_supported(minorversion, bmval));
 
        if (exp->ex_fslocs.migrated) {
                status = fattr_handle_absent_fs(&bmval0, &bmval1, &bmval2, &rdattr_err);
@@ -2409,29 +2421,27 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
        p++;                /* to be backfilled later */
 
        if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
-               u32 word0 = nfsd_suppattrs0(minorversion);
-               u32 word1 = nfsd_suppattrs1(minorversion);
-               u32 word2 = nfsd_suppattrs2(minorversion);
+               u32 *supp = nfsd_suppattrs[minorversion];
 
                if (!IS_POSIXACL(dentry->d_inode))
-                       word0 &= ~FATTR4_WORD0_ACL;
+                       supp[0] &= ~FATTR4_WORD0_ACL;
                if (!contextsupport)
-                       word2 &= ~FATTR4_WORD2_SECURITY_LABEL;
-               if (!word2) {
+                       supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
+               if (!supp[2]) {
                        p = xdr_reserve_space(xdr, 12);
                        if (!p)
                                goto out_resource;
                        *p++ = cpu_to_be32(2);
-                       *p++ = cpu_to_be32(word0);
-                       *p++ = cpu_to_be32(word1);
+                       *p++ = cpu_to_be32(supp[0]);
+                       *p++ = cpu_to_be32(supp[1]);
                } else {
                        p = xdr_reserve_space(xdr, 16);
                        if (!p)
                                goto out_resource;
                        *p++ = cpu_to_be32(3);
-                       *p++ = cpu_to_be32(word0);
-                       *p++ = cpu_to_be32(word1);
-                       *p++ = cpu_to_be32(word2);
+                       *p++ = cpu_to_be32(supp[0]);
+                       *p++ = cpu_to_be32(supp[1]);
+                       *p++ = cpu_to_be32(supp[2]);
                }
        }
        if (bmval0 & FATTR4_WORD0_TYPE) {
index 9446849..a72d416 100644 (file)
@@ -361,25 +361,18 @@ void              nfsd_lockd_shutdown(void);
        (NFSD4_1_SUPPORTED_ATTRS_WORD2 | \
        NFSD4_2_SECURITY_ATTRS)
 
-static inline u32 nfsd_suppattrs0(u32 minorversion)
-{
-       return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0
-                           : NFSD4_SUPPORTED_ATTRS_WORD0;
-}
+extern u32 nfsd_suppattrs[3][3];
 
-static inline u32 nfsd_suppattrs1(u32 minorversion)
+static inline bool bmval_is_subset(u32 *bm1, u32 *bm2)
 {
-       return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD1
-                           : NFSD4_SUPPORTED_ATTRS_WORD1;
+       return !((bm1[0] & ~bm2[0]) ||
+                (bm1[1] & ~bm2[1]) ||
+                (bm1[2] & ~bm2[2]));
 }
 
-static inline u32 nfsd_suppattrs2(u32 minorversion)
+static inline bool nfsd_attrs_supported(u32 minorversion, u32 *bmval)
 {
-       switch (minorversion) {
-       default: return NFSD4_2_SUPPORTED_ATTRS_WORD2;
-       case 1:  return NFSD4_1_SUPPORTED_ATTRS_WORD2;
-       case 0:  return NFSD4_SUPPORTED_ATTRS_WORD2;
-       }
+       return bmval_is_subset(bmval, nfsd_suppattrs[minorversion]);
 }
 
 /* These will return ERR_INVAL if specified in GETATTR or READDIR. */