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: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
Родитель
851238a22f
Коммит
916d2d844a
|
@ -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)))
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
extern u32 nfsd_suppattrs[3][3];
|
||||
|
||||
static inline bool bmval_is_subset(u32 *bm1, u32 *bm2)
|
||||
{
|
||||
return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0
|
||||
: NFSD4_SUPPORTED_ATTRS_WORD0;
|
||||
return !((bm1[0] & ~bm2[0]) ||
|
||||
(bm1[1] & ~bm2[1]) ||
|
||||
(bm1[2] & ~bm2[2]));
|
||||
}
|
||||
|
||||
static inline u32 nfsd_suppattrs1(u32 minorversion)
|
||||
static inline bool nfsd_attrs_supported(u32 minorversion, u32 *bmval)
|
||||
{
|
||||
return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD1
|
||||
: NFSD4_SUPPORTED_ATTRS_WORD1;
|
||||
}
|
||||
|
||||
static inline u32 nfsd_suppattrs2(u32 minorversion)
|
||||
{
|
||||
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. */
|
||||
|
|
Загрузка…
Ссылка в новой задаче