svn commit: r346424 - in head/sys/fs: nfs nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Tue Sep 3 14:08:04 UTC 2019
Author: rmacklem
Date: Fri Apr 19 23:35:08 2019
New Revision: 346424
URL: https://svnweb.freebsd.org/changeset/base/346424
Log:
Add support for the ModeSetMasked attribute to the NFSv4.1 server.
I do not know of an extant NFSv4.1 client that currently does a Setattr
operation for the ModeSetMasked, but it has been discussed on the linux-nfs
mailing list.
This patch adds support for doing a Setattr of ModeSetMasked, so that it
will work for any future NFSv4.1 client that chooses to do so.
Tested via a hacked FreeBSD NFSv4.1 client.
MFC after: 2 weeks
Modified:
head/sys/fs/nfs/nfsproto.h
head/sys/fs/nfsserver/nfs_nfsdport.c
head/sys/fs/nfsserver/nfs_nfsdserv.c
Modified: head/sys/fs/nfs/nfsproto.h
==============================================================================
--- head/sys/fs/nfs/nfsproto.h Fri Apr 19 23:27:23 2019 (r346423)
+++ head/sys/fs/nfs/nfsproto.h Fri Apr 19 23:35:08 2019 (r346424)
@@ -1090,7 +1090,7 @@ struct nfsv3_sattr {
*/
#define NFSATTRBIT_SUPPSETONLY1 (NFSATTRBM_TIMEACCESSSET | \
NFSATTRBM_TIMEMODIFYSET)
-#define NFSATTRBIT_SUPPSETONLY2 0
+#define NFSATTRBIT_SUPPSETONLY2 (NFSATTRBM_MODESETMASKED)
/*
* NFSATTRBIT_SETABLE - SETABLE0 - bits 0<->31
@@ -1106,7 +1106,8 @@ struct nfsv3_sattr {
NFSATTRBM_OWNERGROUP | \
NFSATTRBM_TIMEACCESSSET | \
NFSATTRBM_TIMEMODIFYSET)
-#define NFSATTRBIT_SETABLE2 0
+#define NFSATTRBIT_SETABLE2 \
+ (NFSATTRBM_MODESETMASKED)
/*
* NFSATTRBIT_NFSV41 - Attributes only supported by NFSv4.1.
Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c Fri Apr 19 23:27:23 2019 (r346423)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c Fri Apr 19 23:35:08 2019 (r346424)
@@ -2699,10 +2699,12 @@ nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, str
int attrsum = 0;
int i, j;
int error, attrsize, bitpos, aclsize, aceerr, retnotsup = 0;
- int toclient = 0;
+ int moderet, toclient = 0;
u_char *cp, namestr[NFSV4_SMALLSTR + 1];
uid_t uid;
gid_t gid;
+ u_short mode, mask; /* Same type as va_mode. */
+ struct vattr va;
error = nfsrv_getattrbits(nd, attrbitp, NULL, &retnotsup);
if (error)
@@ -2720,6 +2722,7 @@ nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, str
} else {
bitpos = 0;
}
+ moderet = 0;
for (; bitpos < NFSATTRBIT_MAX; bitpos++) {
if (attrsum > attrsize) {
error = NFSERR_BADXDR;
@@ -2769,6 +2772,7 @@ nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, str
attrsum += (NFSX_UNSIGNED + NFSM_RNDUP(i));
break;
case NFSATTRBIT_MODE:
+ moderet = NFSERR_INVAL; /* Can't do MODESETMASKED. */
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
nvap->na_mode = nfstov_mode(*tl);
attrsum += NFSX_UNSIGNED;
@@ -2871,6 +2875,32 @@ nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, str
if (!toclient)
nvap->na_vaflags |= VA_UTIMES_NULL;
}
+ break;
+ case NFSATTRBIT_MODESETMASKED:
+ NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
+ mode = fxdr_unsigned(u_short, *tl++);
+ mask = fxdr_unsigned(u_short, *tl);
+ /*
+ * vp == NULL implies an Open/Create operation.
+ * This attribute can only be used for Setattr and
+ * only for NFSv4.1 or higher.
+ * If moderet != 0, a mode attribute has also been
+ * specified and this attribute cannot be done in the
+ * same Setattr operation.
+ */
+ if ((nd->nd_flag & ND_NFSV41) == 0)
+ nd->nd_repstat = NFSERR_ATTRNOTSUPP;
+ else if ((mode & ~07777) != 0 || (mask & ~07777) != 0 ||
+ vp == NULL)
+ nd->nd_repstat = NFSERR_INVAL;
+ else if (moderet == 0)
+ moderet = VOP_GETATTR(vp, &va, nd->nd_cred);
+ if (moderet == 0)
+ nvap->na_mode = (mode & mask) |
+ (va.va_mode & ~mask);
+ else
+ nd->nd_repstat = moderet;
+ attrsum += 2 * NFSX_UNSIGNED;
break;
default:
nd->nd_repstat = NFSERR_ATTRNOTSUPP;
Modified: head/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdserv.c Fri Apr 19 23:27:23 2019 (r346423)
+++ head/sys/fs/nfsserver/nfs_nfsdserv.c Fri Apr 19 23:35:08 2019 (r346424)
@@ -464,13 +464,18 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int
}
}
if (!nd->nd_repstat &&
- NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_MODE)) {
+ (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_MODE) ||
+ NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_MODESETMASKED))) {
NFSVNO_ATTRINIT(&nva2);
NFSVNO_SETATTRVAL(&nva2, mode, nva.na_mode);
nd->nd_repstat = nfsvno_setattr(vp, &nva2, nd->nd_cred, p,
exp);
- if (!nd->nd_repstat)
- NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_MODE);
+ if (!nd->nd_repstat) {
+ if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_MODE))
+ NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_MODE);
+ if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_MODESETMASKED))
+ NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_MODESETMASKED);
+ }
}
#ifdef NFS4_ACL_EXTATTR_NAME
More information about the svn-src-all
mailing list