Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 153688
b: refs/heads/master
c: 3c8e031
h: refs/heads/master
v: v3
  • Loading branch information
Yu Zhiguo authored and J. Bruce Fields committed Jun 1, 2009
1 parent c2842f3 commit b75a7b8
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 39 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1dbd0d53f394cd9a86fc801dd68fdbcbcdb45718
refs/heads/master: 3c8e03166ae234d16e7871f8009638e0946d303c
95 changes: 91 additions & 4 deletions trunk/fs/nfsd/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,78 @@

#define NFSDDBG_FACILITY NFSDDBG_PROC

static u32 nfsd_attrmask[] = {
NFSD_WRITEABLE_ATTRS_WORD0,
NFSD_WRITEABLE_ATTRS_WORD1,
NFSD_WRITEABLE_ATTRS_WORD2
};

static u32 nfsd41_ex_attrmask[] = {
NFSD_SUPPATTR_EXCLCREAT_WORD0,
NFSD_SUPPATTR_EXCLCREAT_WORD1,
NFSD_SUPPATTR_EXCLCREAT_WORD2
};

static __be32
check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
u32 *bmval, u32 *writable)
{
struct dentry *dentry = cstate->current_fh.fh_dentry;
struct svc_export *exp = cstate->current_fh.fh_export;

/*
* 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)))
return nfserr_attrnotsupp;

/*
* Check FATTR4_WORD0_ACL & FATTR4_WORD0_FS_LOCATIONS can be supported
* in current environment or not.
*/
if (bmval[0] & FATTR4_WORD0_ACL) {
if (!IS_POSIXACL(dentry->d_inode))
return nfserr_attrnotsupp;
}
if (bmval[0] & FATTR4_WORD0_FS_LOCATIONS) {
if (exp->ex_fslocs.locations == NULL)
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;
}

return nfs_ok;
}

static __be32
nfsd4_check_open_attributes(struct svc_rqst *rqstp,
struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
{
__be32 status = nfs_ok;

if (open->op_create == NFS4_OPEN_CREATE) {
if (open->op_createmode == NFS4_CREATE_UNCHECKED
|| open->op_createmode == NFS4_CREATE_GUARDED)
status = check_attr_support(rqstp, cstate,
open->op_bmval, nfsd_attrmask);
else if (open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1)
status = check_attr_support(rqstp, cstate,
open->op_bmval, nfsd41_ex_attrmask);
}

return status;
}

static inline void
fh_dup2(struct svc_fh *dst, struct svc_fh *src)
{
Expand Down Expand Up @@ -225,6 +297,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status)
goto out;

status = nfsd4_check_open_attributes(rqstp, cstate, open);
if (status)
goto out;

/* Openowner is now set, so sequence id will get bumped. Now we need
* these checks before we do any creates: */
status = nfserr_grace;
Expand Down Expand Up @@ -395,6 +471,11 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status)
return status;

status = check_attr_support(rqstp, cstate, create->cr_bmval,
nfsd_attrmask);
if (status)
return status;

switch (create->cr_type) {
case NF4LNK:
/* ugh! we have to null-terminate the linktext, or
Expand Down Expand Up @@ -689,6 +770,12 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status)
return status;
status = nfs_ok;

status = check_attr_support(rqstp, cstate, setattr->sa_bmval,
nfsd_attrmask);
if (status)
goto out;

if (setattr->sa_acl != NULL)
status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh,
setattr->sa_acl);
Expand Down Expand Up @@ -763,10 +850,10 @@ _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status)
return status;

if ((verify->ve_bmval[0] & ~nfsd_suppattrs0(cstate->minorversion))
|| (verify->ve_bmval[1] & ~nfsd_suppattrs1(cstate->minorversion))
|| (verify->ve_bmval[2] & ~nfsd_suppattrs2(cstate->minorversion)))
return nfserr_attrnotsupp;
status = check_attr_support(rqstp, cstate, verify->ve_bmval, NULL);
if (status)
return status;

if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR)
|| (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1))
return nfserr_inval;
Expand Down
46 changes: 12 additions & 34 deletions trunk/fs/nfsd/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,20 +244,8 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
DECODE_TAIL;
}

static u32 nfsd_attrmask[] = {
NFSD_WRITEABLE_ATTRS_WORD0,
NFSD_WRITEABLE_ATTRS_WORD1,
NFSD_WRITEABLE_ATTRS_WORD2
};

static u32 nfsd41_ex_attrmask[] = {
NFSD_SUPPATTR_EXCLCREAT_WORD0,
NFSD_SUPPATTR_EXCLCREAT_WORD1,
NFSD_SUPPATTR_EXCLCREAT_WORD2
};

static __be32
nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable,
nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
struct iattr *iattr, struct nfs4_acl **acl)
{
int expected_len, len = 0;
Expand All @@ -270,18 +258,6 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable,
if ((status = nfsd4_decode_bitmap(argp, bmval)))
return status;

/*
* According to spec, unsupported attributes return ERR_ATTRNOTSUPP;
* read-only attributes return ERR_INVAL.
*/
if ((bmval[0] & ~nfsd_suppattrs0(argp->minorversion)) ||
(bmval[1] & ~nfsd_suppattrs1(argp->minorversion)) ||
(bmval[2] & ~nfsd_suppattrs2(argp->minorversion)))
return nfserr_attrnotsupp;
if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) ||
(bmval[2] & ~writable[2]))
return nfserr_inval;

READ_BUF(4);
READ32(expected_len);

Expand Down Expand Up @@ -414,8 +390,11 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable,
goto xdr_error;
}
}
BUG_ON(bmval[2]); /* no such writeable attr supported yet */
if (len != expected_len)
if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
|| bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
|| bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2)
READ_BUF(expected_len - len);
else if (len != expected_len)
goto xdr_error;

DECODE_TAIL;
Expand Down Expand Up @@ -508,8 +487,8 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval)))
return status;

status = nfsd4_decode_fattr(argp, create->cr_bmval, nfsd_attrmask,
&create->cr_iattr, &create->cr_acl);
status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
&create->cr_acl);
if (status)
goto out;

Expand Down Expand Up @@ -672,7 +651,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
case NFS4_CREATE_UNCHECKED:
case NFS4_CREATE_GUARDED:
status = nfsd4_decode_fattr(argp, open->op_bmval,
nfsd_attrmask, &open->op_iattr, &open->op_acl);
&open->op_iattr, &open->op_acl);
if (status)
goto out;
break;
Expand All @@ -686,8 +665,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
READ_BUF(8);
COPYMEM(open->op_verf.data, 8);
status = nfsd4_decode_fattr(argp, open->op_bmval,
nfsd41_ex_attrmask, &open->op_iattr,
&open->op_acl);
&open->op_iattr, &open->op_acl);
if (status)
goto out;
break;
Expand Down Expand Up @@ -883,8 +861,8 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
if (status)
return status;
return nfsd4_decode_fattr(argp, setattr->sa_bmval, nfsd_attrmask,
&setattr->sa_iattr, &setattr->sa_acl);
return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
&setattr->sa_acl);
}

static __be32
Expand Down

0 comments on commit b75a7b8

Please sign in to comment.