NFSD: Return word2 bitmask if setting security label in OPEN/CREATE
authorKinglong Mee <kinglongmee@gmail.com>
Thu, 30 Jul 2015 13:55:30 +0000 (21:55 +0800)
committerJ. Bruce Fields <bfields@redhat.com>
Mon, 31 Aug 2015 20:16:40 +0000 (16:16 -0400)
Security label can be set in OPEN/CREATE request, nfsd should set
the bitmask in word2 if setting success.

Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4xdr.c

index 565b69ca04cd879e46cee8979da7d382619de665..51c9e9ca39a4d7c5e0537a2cafed4ec9caeb789d 100644 (file)
@@ -2226,6 +2226,39 @@ static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
        return err;
 }
 
+static __be32
+nfsd4_encode_bitmap(struct xdr_stream *xdr, u32 bmval0, u32 bmval1, u32 bmval2)
+{
+       __be32 *p;
+
+       if (bmval2) {
+               p = xdr_reserve_space(xdr, 16);
+               if (!p)
+                       goto out_resource;
+               *p++ = cpu_to_be32(3);
+               *p++ = cpu_to_be32(bmval0);
+               *p++ = cpu_to_be32(bmval1);
+               *p++ = cpu_to_be32(bmval2);
+       } else if (bmval1) {
+               p = xdr_reserve_space(xdr, 12);
+               if (!p)
+                       goto out_resource;
+               *p++ = cpu_to_be32(2);
+               *p++ = cpu_to_be32(bmval0);
+               *p++ = cpu_to_be32(bmval1);
+       } else {
+               p = xdr_reserve_space(xdr, 8);
+               if (!p)
+                       goto out_resource;
+               *p++ = cpu_to_be32(1);
+               *p++ = cpu_to_be32(bmval0);
+       }
+
+       return 0;
+out_resource:
+       return nfserr_resource;
+}
+
 /*
  * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
  * ourselves.
@@ -2322,28 +2355,9 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
        }
 #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
 
-       if (bmval2) {
-               p = xdr_reserve_space(xdr, 16);
-               if (!p)
-                       goto out_resource;
-               *p++ = cpu_to_be32(3);
-               *p++ = cpu_to_be32(bmval0);
-               *p++ = cpu_to_be32(bmval1);
-               *p++ = cpu_to_be32(bmval2);
-       } else if (bmval1) {
-               p = xdr_reserve_space(xdr, 12);
-               if (!p)
-                       goto out_resource;
-               *p++ = cpu_to_be32(2);
-               *p++ = cpu_to_be32(bmval0);
-               *p++ = cpu_to_be32(bmval1);
-       } else {
-               p = xdr_reserve_space(xdr, 8);
-               if (!p)
-                       goto out_resource;
-               *p++ = cpu_to_be32(1);
-               *p++ = cpu_to_be32(bmval0);
-       }
+       status = nfsd4_encode_bitmap(xdr, bmval0, bmval1, bmval2);
+       if (status)
+               goto out;
 
        attrlen_offset = xdr->buf->len;
        p = xdr_reserve_space(xdr, 4);
@@ -2736,13 +2750,11 @@ out_acl:
        }
 #endif /* CONFIG_NFSD_PNFS */
        if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
-               p = xdr_reserve_space(xdr, 16);
-               if (!p)
-                       goto out_resource;
-               *p++ = cpu_to_be32(3);
-               *p++ = cpu_to_be32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
-               *p++ = cpu_to_be32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
-               *p++ = cpu_to_be32(NFSD_SUPPATTR_EXCLCREAT_WORD2);
+               status = nfsd4_encode_bitmap(xdr, NFSD_SUPPATTR_EXCLCREAT_WORD0,
+                                                 NFSD_SUPPATTR_EXCLCREAT_WORD1,
+                                                 NFSD_SUPPATTR_EXCLCREAT_WORD2);
+               if (status)
+                       goto out;
        }
 
        if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
@@ -3069,13 +3081,12 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
        __be32 *p;
 
        if (!nfserr) {
-               p = xdr_reserve_space(xdr, 32);
+               p = xdr_reserve_space(xdr, 20);
                if (!p)
                        return nfserr_resource;
-               p = encode_cinfo(p, &create->cr_cinfo);
-               *p++ = cpu_to_be32(2);
-               *p++ = cpu_to_be32(create->cr_bmval[0]);
-               *p++ = cpu_to_be32(create->cr_bmval[1]);
+               encode_cinfo(p, &create->cr_cinfo);
+               nfserr = nfsd4_encode_bitmap(xdr, create->cr_bmval[0],
+                               create->cr_bmval[1], create->cr_bmval[2]);
        }
        return nfserr;
 }
@@ -3215,16 +3226,22 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
        nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid);
        if (nfserr)
                goto out;
-       p = xdr_reserve_space(xdr, 40);
+       p = xdr_reserve_space(xdr, 24);
        if (!p)
                return nfserr_resource;
        p = encode_cinfo(p, &open->op_cinfo);
        *p++ = cpu_to_be32(open->op_rflags);
-       *p++ = cpu_to_be32(2);
-       *p++ = cpu_to_be32(open->op_bmval[0]);
-       *p++ = cpu_to_be32(open->op_bmval[1]);
-       *p++ = cpu_to_be32(open->op_delegate_type);
 
+       nfserr = nfsd4_encode_bitmap(xdr, open->op_bmval[0], open->op_bmval[1],
+                                       open->op_bmval[2]);
+       if (nfserr)
+               goto out;
+
+       p = xdr_reserve_space(xdr, 4);
+       if (!p)
+               return nfserr_resource;
+
+       *p++ = cpu_to_be32(open->op_delegate_type);
        switch (open->op_delegate_type) {
        case NFS4_OPEN_DELEGATE_NONE:
                break;