aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/nfsclient/nfs_clvnops.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/nfsclient/nfs_clvnops.c')
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 714c37de271f..7ecd1619a0ad 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -1215,7 +1215,7 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred,
NFSUNLOCKNODE(np);
KDTRACE_NFS_ACCESSCACHE_FLUSH_DONE(vp);
}
- error = nfsrpc_setattr(vp, vap, NULL, cred, td, &nfsva, &attrflag);
+ error = nfsrpc_setattr(vp, vap, NULL, 0, cred, td, &nfsva, &attrflag);
if (attrflag) {
ret = nfscl_loadattrcache(&vp, &nfsva, NULL, 0, 1);
if (ret && !error)
@@ -1967,14 +1967,14 @@ again:
}
} else if (NFS_ISV34(dvp) && (fmode & O_EXCL)) {
if (nfscl_checksattr(vap, &nfsva)) {
- error = nfsrpc_setattr(newvp, vap, NULL, cnp->cn_cred,
- curthread, &nfsva, &attrflag);
+ error = nfsrpc_setattr(newvp, vap, NULL, 0,
+ cnp->cn_cred, curthread, &nfsva, &attrflag);
if (error && (vap->va_uid != (uid_t)VNOVAL ||
vap->va_gid != (gid_t)VNOVAL)) {
/* try again without setting uid/gid */
vap->va_uid = (uid_t)VNOVAL;
vap->va_gid = (uid_t)VNOVAL;
- error = nfsrpc_setattr(newvp, vap, NULL,
+ error = nfsrpc_setattr(newvp, vap, NULL, 0,
cnp->cn_cred, curthread, &nfsva, &attrflag);
}
if (attrflag)
@@ -3772,9 +3772,15 @@ nfs_getacl(struct vop_getacl_args *ap)
{
int error;
- if (ap->a_type != ACL_TYPE_NFS4)
+ if (ap->a_type != ACL_TYPE_NFS4 && ap->a_type != ACL_TYPE_ACCESS &&
+ ap->a_type != ACL_TYPE_DEFAULT)
+ return (EOPNOTSUPP);
+ if (ap->a_type == ACL_TYPE_DEFAULT && ap->a_vp->v_type != VDIR)
+ return (EINVAL);
+ error = nfsrpc_getacl(ap->a_vp, ap->a_type, ap->a_cred, ap->a_td,
+ ap->a_aclp);
+ if (error == 0 && ap->a_aclp->acl_cnt == 0)
return (EOPNOTSUPP);
- error = nfsrpc_getacl(ap->a_vp, ap->a_cred, ap->a_td, ap->a_aclp);
if (error > NFSERR_STALE) {
(void) nfscl_maperr(ap->a_td, error, (uid_t)0, (gid_t)0);
error = EPERM;
@@ -3787,9 +3793,17 @@ nfs_setacl(struct vop_setacl_args *ap)
{
int error;
- if (ap->a_type != ACL_TYPE_NFS4)
+ if (ap->a_type != ACL_TYPE_NFS4 && ap->a_type != ACL_TYPE_ACCESS &&
+ ap->a_type != ACL_TYPE_DEFAULT)
return (EOPNOTSUPP);
- error = nfsrpc_setacl(ap->a_vp, ap->a_cred, ap->a_td, ap->a_aclp);
+ if (ap->a_aclp == NULL) {
+ if (ap->a_type != ACL_TYPE_DEFAULT)
+ return (EINVAL);
+ if (ap->a_vp->v_type != VDIR)
+ return (ENOTDIR);
+ }
+ error = nfsrpc_setacl(ap->a_vp, ap->a_type, ap->a_cred, ap->a_td,
+ ap->a_aclp);
if (error > NFSERR_STALE) {
(void) nfscl_maperr(ap->a_td, error, (uid_t)0, (gid_t)0);
error = EPERM;
@@ -4188,8 +4202,8 @@ relock:
va.va_vaflags = VA_UTIMES_NULL;
inattrflag = 0;
error = nfsrpc_setattr(invp, &va, NULL,
- ap->a_incred, curthread, &innfsva,
- &inattrflag);
+ 0, ap->a_incred, curthread,
+ &innfsva, &inattrflag);
if (inattrflag != 0)
ret = nfscl_loadattrcache(&invp,
&innfsva, NULL, 0, 1);
@@ -4669,6 +4683,7 @@ nfs_pathconf(struct vop_pathconf_args *ap)
bool eof, has_namedattr, named_enabled;
int attrflag, error;
struct nfsnode *np;
+ uint32_t trueform;
nmp = VFSTONFS(vp->v_mount);
np = VTONFS(vp);
@@ -4681,16 +4696,18 @@ nfs_pathconf(struct vop_pathconf_args *ap)
ap->a_name == _PC_CASE_INSENSITIVE)) ||
(NFS_ISV4(vp) && (ap->a_name == _PC_ACL_NFS4 ||
ap->a_name == _PC_HAS_NAMEDATTR ||
- ap->a_name == _PC_CLONE_BLKSIZE))) {
+ ap->a_name == _PC_CLONE_BLKSIZE ||
+ ap->a_name == _PC_ACL_EXTENDED))) {
/*
* Since only the above 5 a_names are returned by the NFSv3
* Pathconf RPC, there is no point in doing it for others.
* For NFSv4, the Pathconf RPC (actually a Getattr Op.) can
- * be used for _PC_ACL_NFS4, _PC_HAS_NAMEDATTR and
- * _PC_CLONE_BLKSIZE as well.
+ * be used for _PC_ACL_NFS4, _PC_HAS_NAMEDATTR,
+ * and _PC_ACL_EXTENDED as well.
*/
+ trueform = UINT32_MAX;
error = nfsrpc_pathconf(vp, &pc, &has_namedattr, &clone_blksize,
- td->td_ucred, td, &nfsva, &attrflag);
+ td->td_ucred, td, &nfsva, &attrflag, &trueform);
if (attrflag != 0)
(void) nfscl_loadattrcache(&vp, &nfsva, NULL, 0, 1);
if (error != 0)
@@ -4750,7 +4767,20 @@ nfs_pathconf(struct vop_pathconf_args *ap)
break;
case _PC_ACL_NFS4:
if (NFS_ISV4(vp) && nfsrv_useacl != 0 && attrflag != 0 &&
- NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL))
+ NFSISSET_ATTRBIT(&nfsva.na_suppattr, NFSATTRBIT_ACL) &&
+ (trueform == NFSV4_ACL_MODEL_NFS4 ||
+ trueform == UINT32_MAX))
+ *ap->a_retval = 1;
+ else
+ *ap->a_retval = 0;
+ break;
+ case _PC_ACL_EXTENDED:
+ if (NFS_ISV4(vp) && nfsrv_useacl != 0 && attrflag != 0 &&
+ NFSISSET_ATTRBIT(&nfsva.na_suppattr,
+ NFSATTRBIT_POSIXACCESSACL) &&
+ NFSISSET_ATTRBIT(&nfsva.na_suppattr,
+ NFSATTRBIT_POSIXDEFAULTACL) &&
+ trueform == NFSV4_ACL_MODEL_POSIX_DRAFT)
*ap->a_retval = 1;
else
*ap->a_retval = 0;