mirror of
https://github.com/opnsense/src.git
synced 2026-06-19 21:49:14 -04:00
nfscommon: Use _PC_HAS_NAMEDATTR to check for named attributes
Commit 0f12c3cd0d added the _PC_HAS_NAMEDATTR name for pathconf(2).
This commit uses this to determine if named attributes are
associated with a file handle for the named_attr NFSv4
attribute.
This avoids the need for nfs_test_namedattr() function.
This commit is contained in:
parent
91f53f4e06
commit
9419e086e1
2 changed files with 26 additions and 72 deletions
|
|
@ -223,7 +223,6 @@ 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);
|
||||
|
|
@ -1282,70 +1281,6 @@ 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,
|
||||
|
|
@ -1442,6 +1377,7 @@ 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;
|
||||
|
|
@ -1581,13 +1517,25 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
|||
break;
|
||||
case NFSATTRBIT_NAMEDATTR:
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
if (compare && !(*retcmpp)) {
|
||||
bool named_attr;
|
||||
if (compare) {
|
||||
if (!(*retcmpp)) {
|
||||
long has_named_attr;
|
||||
|
||||
named_attr = nfs_test_namedattr(nd, vp);
|
||||
if ((named_attr && *tl != newnfs_true) ||
|
||||
(!named_attr && *tl != newnfs_false))
|
||||
*retcmpp = NFSERR_NOTSAME;
|
||||
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;
|
||||
}
|
||||
attrsum += NFSX_UNSIGNED;
|
||||
break;
|
||||
|
|
@ -2684,6 +2632,7 @@ 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;
|
||||
|
|
@ -2840,7 +2789,10 @@ 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 (nfs_test_namedattr(nd, vp))
|
||||
if (VOP_PATHCONF(vp, _PC_HAS_NAMEDATTR, &has_named_attr)
|
||||
!= 0)
|
||||
has_named_attr = 0;
|
||||
if (has_named_attr != 0)
|
||||
*tl = newnfs_true;
|
||||
else
|
||||
*tl = newnfs_false;
|
||||
|
|
|
|||
|
|
@ -1414,6 +1414,7 @@ struct nfsv3_sattr {
|
|||
* NFSGETATTRBIT_PATHCONF0 - bits 0<->31
|
||||
*/
|
||||
#define NFSGETATTRBIT_PATHCONF0 (NFSATTRBIT_GETATTR0 | \
|
||||
NFSATTRBM_NAMEDATTR | \
|
||||
NFSATTRBM_CASEINSENSITIVE | \
|
||||
NFSATTRBM_CASEPRESERVING | \
|
||||
NFSATTRBM_CHOWNRESTRICTED | \
|
||||
|
|
@ -1645,6 +1646,7 @@ struct nfsv3_pathconf {
|
|||
u_int32_t pc_chownrestricted;
|
||||
u_int32_t pc_caseinsensitive;
|
||||
u_int32_t pc_casepreserving;
|
||||
bool pc_has_namedattr;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue