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:
parent
5e701afcf0
commit
42cdb57de6
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 *,
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user