Fix the experimental NFSv4 server so that it uses VOP_PATHCONF()

to determine if a file system supports NFSv4 ACLs. Since
VOP_PATHCONF() must be called with a locked vnode, the function
is called before nfsvno_fillattr() and the result is passed in
as an extra argument.

MFC after:	2 weeks
This commit is contained in:
rmacklem 2011-04-14 23:46:15 +00:00
parent 5e701afcf0
commit 42cdb57de6
10 changed files with 37 additions and 34 deletions

View File

@ -445,7 +445,7 @@ nfsrv_setacl(vnode_t vp, NFSACL_T *aclp, struct ucred *cred,
{
int error;
if (nfsrv_useacl == 0 || !NFSHASNFS4ACL(vnode_mount(vp)))
if (nfsrv_useacl == 0 || nfs_supportsnfsv4acls(vp) == 0)
return (NFSERR_ATTRNOTSUPP);
/*
* With NFSv4 ACLs, chmod(2) may need to add additional entries.

View File

@ -437,18 +437,18 @@ newnfs_portinit(void)
* Return 1 if it does, 0 otherwise.
*/
int
nfs_supportsnfsv4acls(struct mount *mp)
nfs_supportsnfsv4acls(struct vnode *vp)
{
int error;
register_t retval;
if (mp->mnt_stat.f_fstypename == NULL)
ASSERT_VOP_LOCKED(vp, "nfs supports nfsv4acls");
if (nfsrv_useacl == 0)
return (0);
if (strcmp(mp->mnt_stat.f_fstypename, "ufs") == 0) {
/* Not yet */
return (0);
} else if (strcmp(mp->mnt_stat.f_fstypename, "zfs") == 0) {
/* Always supports them */
error = VOP_PATHCONF(vp, _PC_ACL_NFS4, &retval);
if (error == 0 && retval != 0)
return (1);
}
return (0);
}

View File

@ -1919,7 +1919,7 @@ APPLESTATIC int
nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
NFSACL_T *saclp, struct vattr *vap, fhandle_t *fhp, int rderror,
nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram,
int reterr, int at_root, uint64_t mounted_on_fileno)
int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno)
{
int bitpos, retnum = 0;
u_int32_t *tl;
@ -1974,12 +1974,12 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
*/
if (NFSISSET_ATTRBIT(retbitp, NFSATTRBIT_ACLSUPPORT) &&
(nfsrv_useacl == 0 || ((cred != NULL || p != NULL) &&
!NFSHASNFS4ACL(mp)))) {
supports_nfsv4acls == 0))) {
NFSCLRBIT_ATTRBIT(retbitp, NFSATTRBIT_ACLSUPPORT);
}
if (NFSISSET_ATTRBIT(retbitp, NFSATTRBIT_ACL)) {
if (nfsrv_useacl == 0 || ((cred != NULL || p != NULL) &&
!NFSHASNFS4ACL(mp))) {
supports_nfsv4acls == 0)) {
NFSCLRBIT_ATTRBIT(retbitp, NFSATTRBIT_ACL);
} else if (naclp != NULL) {
if (vn_lock(vp, LK_SHARED) == 0) {
@ -2016,7 +2016,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
case NFSATTRBIT_SUPPORTEDATTRS:
NFSSETSUPP_ATTRBIT(&attrbits);
if (nfsrv_useacl == 0 || ((cred != NULL || p != NULL)
&& !NFSHASNFS4ACL(mp))) {
&& supports_nfsv4acls == 0)) {
NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACLSUPPORT);
NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACL);
}

View File

@ -290,7 +290,7 @@ void nfsrv_wcc(struct nfsrv_descript *, int, struct nfsvattr *, int,
struct nfsvattr *);
int nfsv4_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, NFSACL_T *,
struct vattr *, fhandle_t *, int, nfsattrbit_t *,
struct ucred *, NFSPROC_T *, int, int, int, uint64_t);
struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t);
void nfsrv_fillattr(struct nfsrv_descript *, struct nfsvattr *);
void nfsrv_adj(mbuf_t, int, int);
void nfsrv_postopattr(struct nfsrv_descript *, int, struct nfsvattr *);
@ -328,6 +328,7 @@ int nfs_catnap(int, int, const char *);
struct nfsreferral *nfsv4root_getreferral(vnode_t, vnode_t, u_int32_t);
int nfsrv_atroot(vnode_t, long *);
void newnfs_timer(void *);
int nfs_supportsnfsv4acls(vnode_t);
/* nfs_commonacl.c */
int nfsrv_dissectace(struct nfsrv_descript *, struct acl_entry *,
@ -558,7 +559,7 @@ void nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct ucred *,
NFSPROC_T *);
int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t,
struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *,
struct ucred *, NFSPROC_T *, int, int, int, uint64_t);
struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t);
int nfsrv_sattr(struct nfsrv_descript *, struct nfsvattr *, nfsattrbit_t *,
NFSACL_T *, NFSPROC_T *);
int nfsv4_sattr(struct nfsrv_descript *, struct nfsvattr *, nfsattrbit_t *,

View File

@ -778,12 +778,6 @@ void newnfs_realign(struct mbuf **);
#define NFSHASPRIVACY(n) ((n)->nm_flag & NFSMNT_PRIVACY)
#define NFSSETWRITEVERF(n) ((n)->nm_state |= NFSSTA_HASWRITEVERF)
#define NFSSETHASSETFSID(n) ((n)->nm_state |= NFSSTA_HASSETFSID)
#ifdef NFS4_ACL_EXTATTR_NAME
#define NFSHASNFS4ACL(m) nfs_supportsnfsv4acls(m)
int nfs_supportsnfsv4acls(struct mount *);
#else
#define NFSHASNFS4ACL(m) 0
#endif
/*
* Gets the stats field out of the mount structure.

View File

@ -804,7 +804,7 @@ nfscl_fillsattr(struct nfsrv_descript *nd, struct vattr *vap,
if (vap->va_mtime.tv_sec != VNOVAL)
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEMODIFYSET);
(void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0,
&attrbits, NULL, NULL, 0, 0, 0, (uint64_t)0);
&attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0);
break;
};
}

View File

@ -4177,7 +4177,7 @@ nfsrpc_setaclrpc(vnode_t vp, struct ucred *cred, NFSPROC_T *p,
NFSZERO_ATTRBIT(&attrbits);
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_ACL);
(void) nfsv4_fillattr(nd, vnode_mount(vp), vp, aclp, NULL, NULL, 0,
&attrbits, NULL, NULL, 0, 0, 0, (uint64_t)0);
&attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0);
error = nfscl_request(nd, vp, p, cred, stuff);
if (error)
return (error);

View File

@ -3062,7 +3062,7 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
NFSATTRBIT_CHANGE);
}
(void) nfsv4_fillattr(nd, NULL, NULL, NULL, &va,
NULL, 0, &rattrbits, NULL, NULL, 0, 0, 0,
NULL, 0, &rattrbits, NULL, NULL, 0, 0, 0, 0,
(uint64_t)0);
if (!ret)
vrele(vp);

View File

@ -1396,13 +1396,14 @@ nfsvno_updfilerev(struct vnode *vp, struct nfsvattr *nvap,
int
nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp,
struct nfsvattr *nvap, fhandle_t *fhp, int rderror, nfsattrbit_t *attrbitp,
struct ucred *cred, struct thread *p, int isdgram, int reterr, int at_root,
uint64_t mounted_on_fileno)
struct ucred *cred, struct thread *p, int isdgram, int reterr,
int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno)
{
int error;
error = nfsv4_fillattr(nd, mp, vp, NULL, &nvap->na_vattr, fhp, rderror,
attrbitp, cred, p, isdgram, reterr, at_root, mounted_on_fileno);
attrbitp, cred, p, isdgram, reterr, supports_nfsv4acls, at_root,
mounted_on_fileno);
return (error);
}
@ -1692,7 +1693,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
struct uio io;
struct iovec iv;
struct componentname cn;
int at_root, needs_unbusy, not_zfs;
int at_root, needs_unbusy, not_zfs, supports_nfsv4acls;
struct mount *mp, *new_mp;
uint64_t mounted_on_fileno;
@ -2061,8 +2062,12 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
*tl++ = 0;
*tl = txdr_unsigned(*cookiep);
dirlen += nfsm_strtom(nd, dp->d_name, nlen);
if (nvp != NULL)
if (nvp != NULL) {
supports_nfsv4acls =
nfs_supportsnfsv4acls(nvp);
VOP_UNLOCK(nvp, 0);
} else
supports_nfsv4acls = 0;
if (refp != NULL) {
dirlen += nfsrv_putreferralattr(nd,
&savbits, refp, 0,
@ -2077,12 +2082,14 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
} else if (r) {
dirlen += nfsvno_fillattr(nd, new_mp,
nvp, nvap, &nfh, r, &rderrbits,
nd->nd_cred, p, isdgram, 0, at_root,
nd->nd_cred, p, isdgram, 0,
supports_nfsv4acls, at_root,
mounted_on_fileno);
} else {
dirlen += nfsvno_fillattr(nd, new_mp,
nvp, nvap, &nfh, r, &attrbits,
nd->nd_cred, p, isdgram, 0, at_root,
nd->nd_cred, p, isdgram, 0,
supports_nfsv4acls, at_root,
mounted_on_fileno);
}
if (nvp != NULL)

View File

@ -170,7 +170,7 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
{
struct nfsvattr nva;
fhandle_t fh;
int at_root = 0, error = 0;
int at_root = 0, error = 0, supports_nfsv4acls;
struct nfsreferral *refp;
nfsattrbit_t attrbits;
struct mount *mp;
@ -213,6 +213,7 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
nd->nd_repstat = nfsrv_checkgetattr(nd, vp,
&nva, &attrbits, nd->nd_cred, p);
if (nd->nd_repstat == 0) {
supports_nfsv4acls = nfs_supportsnfsv4acls(vp);
mp = vp->v_mount;
if (nfsrv_enable_crossmntpt != 0 &&
vp->v_type == VDIR &&
@ -245,8 +246,8 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
if (nd->nd_repstat == 0) {
(void)nfsvno_fillattr(nd, mp, vp, &nva,
&fh, 0, &attrbits, nd->nd_cred, p,
isdgram, 1, at_root,
mounted_on_fileno);
isdgram, 1, supports_nfsv4acls,
at_root, mounted_on_fileno);
vfs_unbusy(mp);
}
vrele(vp);