git: 2c0e6f53171c - main - Revert "nfscommon: Use _PC_HAS_NAMEDATTR to check for named attributes"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 05 May 2025 02:41:32 UTC
The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=2c0e6f53171c4c8100235811912444bba08185f4 commit 2c0e6f53171c4c8100235811912444bba08185f4 Author: Rick Macklem <rmacklem@FreeBSD.org> AuthorDate: 2025-05-05 02:38:44 +0000 Commit: Rick Macklem <rmacklem@FreeBSD.org> CommitDate: 2025-05-05 02:38:44 +0000 Revert "nfscommon: Use _PC_HAS_NAMEDATTR to check for named attributes" This reverts commit 9419e086e1a37124d11e428892d60a514e5c579e. --- sys/fs/nfs/nfs_commonsubs.c | 98 +++++++++++++++++++++++++++++++++------------ sys/fs/nfs/nfsproto.h | 2 - 2 files changed, 73 insertions(+), 27 deletions(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index f3305ccdde80..3e70eb50a54e 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -223,6 +223,7 @@ static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, /* local functions */ static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep); +static bool nfs_test_namedattr(struct nfsrv_descript *nd, struct vnode *vp); static void nfsv4_wanted(struct nfsv4lock *lp); static uint32_t nfsv4_filesavail(struct statfs *, struct mount *); static int nfsrv_getuser(int procnum, uid_t uid, gid_t gid, char *name); @@ -1281,6 +1282,70 @@ nfsmout: return (error); } +/* + * Check to see if a named attribute exists for this file. + */ +static bool +nfs_test_namedattr(struct nfsrv_descript *nd, struct vnode *vp) +{ + struct uio io; + struct iovec iv; + struct componentname cn; + struct vnode *dvp; + struct dirent *dp; + int eofflag, error; + char *buf, *cp, *endcp; + bool ret; + + if (vp == NULL || (vp->v_mount->mnt_flag & MNT_NAMEDATTR) == 0) + return (false); + NFSNAMEICNDSET(&cn, nd->nd_cred, LOOKUP, OPENNAMED | ISLASTCN | + NOFOLLOW | LOCKLEAF); + cn.cn_lkflags = LK_SHARED; + cn.cn_nameptr = "."; + cn.cn_namelen = 1; + error = VOP_LOOKUP(vp, &dvp, &cn); + if (error != 0) + return (false); + + /* Now we have to read the directory, looking for a valid entry. */ + buf = malloc(DIRBLKSIZ, M_TEMP, M_WAITOK); + ret = false; + io.uio_offset = 0; + io.uio_segflg = UIO_SYSSPACE; + io.uio_rw = UIO_READ; + io.uio_td = NULL; + do { + iv.iov_base = buf; + iv.iov_len = DIRBLKSIZ; + io.uio_iov = &iv; + io.uio_iovcnt = 1; + io.uio_resid = DIRBLKSIZ; + error = VOP_READDIR(dvp, &io, nd->nd_cred, &eofflag, NULL, + NULL); + if (error != 0 || io.uio_resid == DIRBLKSIZ) + break; + cp = buf; + endcp = &buf[DIRBLKSIZ - io.uio_resid]; + while (cp < endcp) { + dp = (struct dirent *)cp; + if (dp->d_fileno != 0 && dp->d_type != DT_WHT && + ((dp->d_namlen == 1 && dp->d_name[0] != '.') || + (dp->d_namlen == 2 && (dp->d_name[0] != '.' || + dp->d_name[1] != '.')) || dp->d_namlen > 2)) { + ret = true; + break; + } + cp += dp->d_reclen; + } + if (ret) + break; + } while (eofflag == 0); + vput(dvp); + free(buf, M_TEMP); + return (ret); +} + /* * Get the attributes for V4. * If the compare flag is true, test for any attribute changes, @@ -1377,7 +1442,6 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, pc->pc_chownrestricted = 0; pc->pc_caseinsensitive = 0; pc->pc_casepreserving = 1; - pc->pc_has_namedattr = false; } if (sfp != NULL) { sfp->sf_ffiles = UINT64_MAX; @@ -1517,25 +1581,13 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, break; case NFSATTRBIT_NAMEDATTR: NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); - if (compare) { - if (!(*retcmpp)) { - long has_named_attr; - - if (vp == NULL || VOP_PATHCONF(vp, - _PC_HAS_NAMEDATTR, &has_named_attr) - != 0) - has_named_attr = 0; - if ((has_named_attr != 0 && - *tl != newnfs_true) || - (has_named_attr == 0 && - *tl != newnfs_false)) - *retcmpp = NFSERR_NOTSAME; - } - } else if (pc != NULL) { - if (*tl == newnfs_true) - pc->pc_has_namedattr = true; - else - pc->pc_has_namedattr = false; + if (compare && !(*retcmpp)) { + bool named_attr; + + named_attr = nfs_test_namedattr(nd, vp); + if ((named_attr && *tl != newnfs_true) || + (!named_attr && *tl != newnfs_false)) + *retcmpp = NFSERR_NOTSAME; } attrsum += NFSX_UNSIGNED; break; @@ -2632,7 +2684,6 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, size_t atsiz; bool xattrsupp; short irflag; - long has_named_attr; #ifdef QUOTA struct dqblk dqb; uid_t savuid; @@ -2789,10 +2840,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, break; case NFSATTRBIT_NAMEDATTR: NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - if (VOP_PATHCONF(vp, _PC_HAS_NAMEDATTR, &has_named_attr) - != 0) - has_named_attr = 0; - if (has_named_attr != 0) + if (nfs_test_namedattr(nd, vp)) *tl = newnfs_true; else *tl = newnfs_false; diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h index 0a11e906569d..d0660cafdedb 100644 --- a/sys/fs/nfs/nfsproto.h +++ b/sys/fs/nfs/nfsproto.h @@ -1414,7 +1414,6 @@ struct nfsv3_sattr { * NFSGETATTRBIT_PATHCONF0 - bits 0<->31 */ #define NFSGETATTRBIT_PATHCONF0 (NFSATTRBIT_GETATTR0 | \ - NFSATTRBM_NAMEDATTR | \ NFSATTRBM_CASEINSENSITIVE | \ NFSATTRBM_CASEPRESERVING | \ NFSATTRBM_CHOWNRESTRICTED | \ @@ -1646,7 +1645,6 @@ struct nfsv3_pathconf { u_int32_t pc_chownrestricted; u_int32_t pc_caseinsensitive; u_int32_t pc_casepreserving; - bool pc_has_namedattr; }; /*