Merge "These changes are a raw update to a vanilla kernel 4.1.10, with the recently...
[kvmfornfv.git] / kernel / fs / nfsd / nfs4xdr.c
index 158badf..3dd1b61 100644 (file)
@@ -2139,9 +2139,31 @@ nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp,
                return nfsd4_encode_user(xdr, rqstp, ace->who_uid);
 }
 
+static inline __be32
+nfsd4_encode_layout_type(struct xdr_stream *xdr, enum pnfs_layouttype layout_type)
+{
+       __be32 *p;
+
+       if (layout_type) {
+               p = xdr_reserve_space(xdr, 8);
+               if (!p)
+                       return nfserr_resource;
+               *p++ = cpu_to_be32(1);
+               *p++ = cpu_to_be32(layout_type);
+       } else {
+               p = xdr_reserve_space(xdr, 4);
+               if (!p)
+                       return nfserr_resource;
+               *p++ = cpu_to_be32(0);
+       }
+
+       return 0;
+}
+
 #define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
                              FATTR4_WORD0_RDATTR_ERROR)
 #define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
+#define WORD2_ABSENT_FS_ATTRS 0
 
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
 static inline __be32
@@ -2170,7 +2192,7 @@ nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
 { return 0; }
 #endif
 
-static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
+static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *bmval2, u32 *rdattr_err)
 {
        /* As per referral draft:  */
        if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
@@ -2183,6 +2205,7 @@ static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
        }
        *bmval0 &= WORD0_ABSENT_FS_ATTRS;
        *bmval1 &= WORD1_ABSENT_FS_ATTRS;
+       *bmval2 &= WORD2_ABSENT_FS_ATTRS;
        return 0;
 }
 
@@ -2246,8 +2269,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
        BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
 
        if (exp->ex_fslocs.migrated) {
-               BUG_ON(bmval[2]);
-               status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
+               status = fattr_handle_absent_fs(&bmval0, &bmval1, &bmval2, &rdattr_err);
                if (status)
                        goto out;
        }
@@ -2290,8 +2312,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
        }
 
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
-       if ((bmval[2] & FATTR4_WORD2_SECURITY_LABEL) ||
-                       bmval[0] & FATTR4_WORD0_SUPPORTED_ATTRS) {
+       if ((bmval2 & FATTR4_WORD2_SECURITY_LABEL) ||
+            bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
                err = security_inode_getsecctx(d_inode(dentry),
                                                &context, &contextlen);
                contextsupport = (err == 0);
@@ -2691,20 +2713,16 @@ out_acl:
                p = xdr_encode_hyper(p, stat.ino);
        }
 #ifdef CONFIG_NFSD_PNFS
-       if ((bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) ||
-           (bmval2 & FATTR4_WORD2_LAYOUT_TYPES)) {
-               if (exp->ex_layout_type) {
-                       p = xdr_reserve_space(xdr, 8);
-                       if (!p)
-                               goto out_resource;
-                       *p++ = cpu_to_be32(1);
-                       *p++ = cpu_to_be32(exp->ex_layout_type);
-               } else {
-                       p = xdr_reserve_space(xdr, 4);
-                       if (!p)
-                               goto out_resource;
-                       *p++ = cpu_to_be32(0);
-               }
+       if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) {
+               status = nfsd4_encode_layout_type(xdr, exp->ex_layout_type);
+               if (status)
+                       goto out;
+       }
+
+       if (bmval2 & FATTR4_WORD2_LAYOUT_TYPES) {
+               status = nfsd4_encode_layout_type(xdr, exp->ex_layout_type);
+               if (status)
+                       goto out;
        }
 
        if (bmval2 & FATTR4_WORD2_LAYOUT_BLKSIZE) {