nfs: Add support for the NFSv4 archive attribute
The archive attribute (UF_ARCHIVE) is listed as deprecated in RFC8881. However, the Windows NFSv4.1 client folk disagree with this and say they need support for it. This patch adds support for it, in a manner similar to what is done for UF_SYSTEM and UF_HIDDEN. MFC after: 2 weeks
This commit is contained in:
@@ -641,6 +641,7 @@ nfscl_fillsattr(struct nfsrv_descript *nd, struct vattr *vap,
|
||||
if ((flags & NFSSATTR_FULL) && vap->va_size != VNOVAL)
|
||||
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SIZE);
|
||||
if ((flags & NFSSATTR_FULL) && vap->va_flags != VNOVAL) {
|
||||
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_ARCHIVE);
|
||||
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN);
|
||||
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM);
|
||||
}
|
||||
@@ -1672,9 +1673,17 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
attrsum += NFSX_UNSIGNED;
|
||||
break;
|
||||
case NFSATTRBIT_ARCHIVE:
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
if (compare && !(*retcmpp))
|
||||
*retcmpp = NFSERR_ATTRNOTSUPP;
|
||||
NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
|
||||
if (compare) {
|
||||
if (!(*retcmpp) && ((*tl == newnfs_true &&
|
||||
(nap->na_flags & UF_ARCHIVE) == 0) ||
|
||||
(*tl == newnfs_false &&
|
||||
(nap->na_flags & UF_ARCHIVE) != 0)))
|
||||
*retcmpp = NFSERR_NOTSAME;
|
||||
} else if (nap != NULL) {
|
||||
if (*tl == newnfs_true)
|
||||
nap->na_flags |= UF_ARCHIVE;
|
||||
}
|
||||
attrsum += NFSX_UNSIGNED;
|
||||
break;
|
||||
case NFSATTRBIT_CANSETTIME:
|
||||
@@ -2804,6 +2813,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
|
||||
if (!has_hiddensystem) {
|
||||
NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN);
|
||||
NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM);
|
||||
NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_ARCHIVE);
|
||||
}
|
||||
if (clone_blksize == 0)
|
||||
NFSCLRBIT_ATTRBIT(&attrbits,
|
||||
@@ -2888,6 +2898,14 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
|
||||
*tl = txdr_unsigned(NFSV4ACE_SUPTYPES);
|
||||
retnum += NFSX_UNSIGNED;
|
||||
break;
|
||||
case NFSATTRBIT_ARCHIVE:
|
||||
NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
|
||||
if ((vap->va_flags & UF_ARCHIVE) != 0)
|
||||
*tl = newnfs_true;
|
||||
else
|
||||
*tl = newnfs_false;
|
||||
retnum += NFSX_UNSIGNED;
|
||||
break;
|
||||
case NFSATTRBIT_CANSETTIME:
|
||||
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
if (fsinf.fs_properties & NFSV3FSINFO_CANSETTIME)
|
||||
|
||||
@@ -1135,6 +1135,7 @@ struct nfsv3_sattr {
|
||||
NFSATTRBM_RDATTRERROR | \
|
||||
NFSATTRBM_ACL | \
|
||||
NFSATTRBM_ACLSUPPORT | \
|
||||
NFSATTRBM_ARCHIVE | \
|
||||
NFSATTRBM_CANSETTIME | \
|
||||
NFSATTRBM_CASEINSENSITIVE | \
|
||||
NFSATTRBM_CASEPRESERVING | \
|
||||
@@ -1217,6 +1218,7 @@ struct nfsv3_sattr {
|
||||
#define NFSATTRBIT_SETABLE0 \
|
||||
(NFSATTRBM_SIZE | \
|
||||
NFSATTRBM_HIDDEN | \
|
||||
NFSATTRBM_ARCHIVE | \
|
||||
NFSATTRBM_ACL)
|
||||
#define NFSATTRBIT_SETABLE1 \
|
||||
(NFSATTRBM_MODE | \
|
||||
@@ -1262,6 +1264,7 @@ struct nfsv3_sattr {
|
||||
NFSATTRBM_CHANGE | \
|
||||
NFSATTRBM_SIZE | \
|
||||
NFSATTRBM_FSID | \
|
||||
NFSATTRBM_ARCHIVE | \
|
||||
NFSATTRBM_FILEID | \
|
||||
NFSATTRBM_HIDDEN | \
|
||||
NFSATTRBM_MAXREAD)
|
||||
@@ -1298,6 +1301,7 @@ struct nfsv3_sattr {
|
||||
NFSATTRBM_CHANGE | \
|
||||
NFSATTRBM_SIZE | \
|
||||
NFSATTRBM_FSID | \
|
||||
NFSATTRBM_ARCHIVE | \
|
||||
NFSATTRBM_FILEID | \
|
||||
NFSATTRBM_HIDDEN | \
|
||||
NFSATTRBM_MAXREAD)
|
||||
|
||||
@@ -4162,9 +4162,12 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
|
||||
NFSATTRBIT_TIMECREATE))
|
||||
NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMECREATE);
|
||||
if (!NFSISSET_ATTRBIT(&dnp->n_vattr.na_suppattr,
|
||||
NFSATTRBIT_ARCHIVE) ||
|
||||
!NFSISSET_ATTRBIT(&dnp->n_vattr.na_suppattr,
|
||||
NFSATTRBIT_HIDDEN) ||
|
||||
!NFSISSET_ATTRBIT(&dnp->n_vattr.na_suppattr,
|
||||
NFSATTRBIT_SYSTEM)) {
|
||||
NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_ARCHIVE);
|
||||
NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN);
|
||||
NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM);
|
||||
}
|
||||
|
||||
@@ -1081,12 +1081,14 @@ nfs_setattr(struct vop_setattr_args *ap)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Only setting of UF_HIDDEN and UF_SYSTEM are supported and
|
||||
* Only setting of UF_ARCHIVE, UF_HIDDEN and UF_SYSTEM are supported and
|
||||
* only for NFSv4 servers that support them.
|
||||
*/
|
||||
nmp = VFSTONFS(vp->v_mount);
|
||||
if (vap->va_flags != VNOVAL && (!NFSHASNFSV4(nmp) ||
|
||||
(vap->va_flags & ~(UF_HIDDEN | UF_SYSTEM)) != 0 ||
|
||||
(vap->va_flags & ~(UF_ARCHIVE | UF_HIDDEN | UF_SYSTEM)) != 0 ||
|
||||
((vap->va_flags & UF_ARCHIVE) != 0 &&
|
||||
!NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr, NFSATTRBIT_ARCHIVE)) ||
|
||||
((vap->va_flags & UF_HIDDEN) != 0 &&
|
||||
!NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr, NFSATTRBIT_HIDDEN)) ||
|
||||
((vap->va_flags & UF_SYSTEM) != 0 &&
|
||||
@@ -4835,6 +4837,8 @@ nfs_pathconf(struct vop_pathconf_args *ap)
|
||||
break;
|
||||
case _PC_HAS_HIDDENSYSTEM:
|
||||
if (NFS_ISV4(vp) && NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr,
|
||||
NFSATTRBIT_ARCHIVE) &&
|
||||
NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr,
|
||||
NFSATTRBIT_HIDDEN) &&
|
||||
NFSISSET_ATTRBIT(&np->n_vattr.na_suppattr,
|
||||
NFSATTRBIT_SYSTEM))
|
||||
|
||||
@@ -3193,7 +3193,8 @@ nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nvap,
|
||||
bitpos = NFSATTRBIT_MAX;
|
||||
} else {
|
||||
bitpos = 0;
|
||||
if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_HIDDEN) ||
|
||||
if (NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_ARCHIVE) ||
|
||||
NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_HIDDEN) ||
|
||||
NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_SYSTEM))
|
||||
nvap->na_flags = 0;
|
||||
}
|
||||
@@ -3226,9 +3227,11 @@ nfsv4_sattr(struct nfsrv_descript *nd, vnode_t vp, struct nfsvattr *nvap,
|
||||
attrsum += aclsize;
|
||||
break;
|
||||
case NFSATTRBIT_ARCHIVE:
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
if (!nd->nd_repstat)
|
||||
nd->nd_repstat = NFSERR_ATTRNOTSUPP;
|
||||
NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
|
||||
if (nd->nd_repstat == 0) {
|
||||
if (*tl == newnfs_true)
|
||||
nvap->na_flags |= UF_ARCHIVE;
|
||||
}
|
||||
attrsum += NFSX_UNSIGNED;
|
||||
break;
|
||||
case NFSATTRBIT_HIDDEN:
|
||||
|
||||
@@ -436,6 +436,7 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
|
||||
/* For NFSv4, only va_uid and va_flags is used from nva2. */
|
||||
NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_OWNER);
|
||||
NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_ARCHIVE);
|
||||
NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_HIDDEN);
|
||||
NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_SYSTEM);
|
||||
preat_ret = nfsvno_getattr(vp, &nva2, nd, p, 1, &retbits);
|
||||
@@ -569,8 +570,15 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
}
|
||||
}
|
||||
if (!nd->nd_repstat &&
|
||||
(NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN) ||
|
||||
(NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_ARCHIVE) ||
|
||||
NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN) ||
|
||||
NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM))) {
|
||||
if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_ARCHIVE)) {
|
||||
if ((nva.na_flags & UF_ARCHIVE) != 0)
|
||||
oldflags |= UF_ARCHIVE;
|
||||
else
|
||||
oldflags &= ~UF_ARCHIVE;
|
||||
}
|
||||
if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN)) {
|
||||
if ((nva.na_flags & UF_HIDDEN) != 0)
|
||||
oldflags |= UF_HIDDEN;
|
||||
@@ -588,6 +596,8 @@ nfsrvd_setattr(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
nd->nd_repstat = nfsvno_setattr(vp, &nva2, nd->nd_cred, p,
|
||||
exp);
|
||||
if (!nd->nd_repstat) {
|
||||
if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_ARCHIVE))
|
||||
NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_ARCHIVE);
|
||||
if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN))
|
||||
NFSSETBIT_ATTRBIT(&retbits, NFSATTRBIT_HIDDEN);
|
||||
if (NFSISSET_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM))
|
||||
|
||||
Reference in New Issue
Block a user