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;
};
/*