Date: Wed, 5 Nov 2025 01:33:15 GMT From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 3a64c667f16f - stable/15 - nfs: Add support for the NFSv4 archive attribute Message-ID: <202511050133.5A51XFlM047009@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch stable/15 has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=3a64c667f16fbc3c1cedee081de895aa911be523 commit 3a64c667f16fbc3c1cedee081de895aa911be523 Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2025-10-22 21:16:48 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2025-11-05 02:29:27 +0000 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. (cherry picked from commit 3b6d4c6cdffd6e37b8fa6e0b0fe3067210582c9c) --- sys/fs/nfs/nfs_commonsubs.c | 24 +++++++++++++++++++++--- sys/fs/nfs/nfsproto.h | 4 ++++ sys/fs/nfsclient/nfs_clrpcops.c | 3 +++ sys/fs/nfsclient/nfs_clvnops.c | 8 ++++++-- sys/fs/nfsserver/nfs_nfsdport.c | 11 +++++++---- sys/fs/nfsserver/nfs_nfsdserv.c | 12 +++++++++++- 6 files changed, 52 insertions(+), 10 deletions(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index abfec9edc485..8e1a26eef354 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -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) diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h index d628108bdc1a..13fec8a102a3 100644 --- a/sys/fs/nfs/nfsproto.h +++ b/sys/fs/nfs/nfsproto.h @@ -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) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 544b1962de26..bad3e69ca5cf 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -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); } diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index eee571a04821..5ce764fcedea 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -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)) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 5ba86314ead1..ff28b089da5d 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -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: diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 9dda65d5cbcf..217675173add 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -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))help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202511050133.5A51XFlM047009>
