Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 916d2d84 authored by J. Bruce Fields's avatar J. Bruce Fields
Browse files

nfsd: clean up supported attribute handling



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: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 851238a2
Loading
Loading
Loading
Loading
+11 −32
Original line number Diff line number Diff line
@@ -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)))
	if ((bmval[0] & FATTR4_WORD0_ACL) && !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]))
	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)))
+24 −14
Original line number Diff line number Diff line
@@ -57,6 +57,20 @@

#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) {
+7 −14
Original line number Diff line number Diff line
@@ -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. */