aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index c2d2895a1ec1..a99bbb88c6e1 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -57,6 +57,20 @@
57 57
58#define NFSDDBG_FACILITY NFSDDBG_XDR 58#define NFSDDBG_FACILITY NFSDDBG_XDR
59 59
60u32 nfsd_suppattrs[3][3] = {
61 {NFSD4_SUPPORTED_ATTRS_WORD0,
62 NFSD4_SUPPORTED_ATTRS_WORD1,
63 NFSD4_SUPPORTED_ATTRS_WORD2},
64
65 {NFSD4_1_SUPPORTED_ATTRS_WORD0,
66 NFSD4_1_SUPPORTED_ATTRS_WORD1,
67 NFSD4_1_SUPPORTED_ATTRS_WORD2},
68
69 {NFSD4_1_SUPPORTED_ATTRS_WORD0,
70 NFSD4_1_SUPPORTED_ATTRS_WORD1,
71 NFSD4_2_SUPPORTED_ATTRS_WORD2},
72};
73
60/* 74/*
61 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing 75 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
62 * directory in order to indicate to the client that a filesystem boundary is present 76 * 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,
2340 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 2354 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2341 2355
2342 BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1); 2356 BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
2343 BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion)); 2357 BUG_ON(!nfsd_attrs_supported(minorversion, bmval));
2344 BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion));
2345 BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
2346 2358
2347 if (exp->ex_fslocs.migrated) { 2359 if (exp->ex_fslocs.migrated) {
2348 status = fattr_handle_absent_fs(&bmval0, &bmval1, &bmval2, &rdattr_err); 2360 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,
2409 p++; /* to be backfilled later */ 2421 p++; /* to be backfilled later */
2410 2422
2411 if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { 2423 if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2412 u32 word0 = nfsd_suppattrs0(minorversion); 2424 u32 *supp = nfsd_suppattrs[minorversion];
2413 u32 word1 = nfsd_suppattrs1(minorversion);
2414 u32 word2 = nfsd_suppattrs2(minorversion);
2415 2425
2416 if (!IS_POSIXACL(dentry->d_inode)) 2426 if (!IS_POSIXACL(dentry->d_inode))
2417 word0 &= ~FATTR4_WORD0_ACL; 2427 supp[0] &= ~FATTR4_WORD0_ACL;
2418 if (!contextsupport) 2428 if (!contextsupport)
2419 word2 &= ~FATTR4_WORD2_SECURITY_LABEL; 2429 supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
2420 if (!word2) { 2430 if (!supp[2]) {
2421 p = xdr_reserve_space(xdr, 12); 2431 p = xdr_reserve_space(xdr, 12);
2422 if (!p) 2432 if (!p)
2423 goto out_resource; 2433 goto out_resource;
2424 *p++ = cpu_to_be32(2); 2434 *p++ = cpu_to_be32(2);
2425 *p++ = cpu_to_be32(word0); 2435 *p++ = cpu_to_be32(supp[0]);
2426 *p++ = cpu_to_be32(word1); 2436 *p++ = cpu_to_be32(supp[1]);
2427 } else { 2437 } else {
2428 p = xdr_reserve_space(xdr, 16); 2438 p = xdr_reserve_space(xdr, 16);
2429 if (!p) 2439 if (!p)
2430 goto out_resource; 2440 goto out_resource;
2431 *p++ = cpu_to_be32(3); 2441 *p++ = cpu_to_be32(3);
2432 *p++ = cpu_to_be32(word0); 2442 *p++ = cpu_to_be32(supp[0]);
2433 *p++ = cpu_to_be32(word1); 2443 *p++ = cpu_to_be32(supp[1]);
2434 *p++ = cpu_to_be32(word2); 2444 *p++ = cpu_to_be32(supp[2]);
2435 } 2445 }
2436 } 2446 }
2437 if (bmval0 & FATTR4_WORD0_TYPE) { 2447 if (bmval0 & FATTR4_WORD0_TYPE) {