aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/nfsserver
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/nfsserver')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c40
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c30
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsocket.c12
3 files changed, 53 insertions, 29 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 7040c4afb797..841ec2315f1c 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -675,7 +675,7 @@ nfsvno_namei(struct nfsrv_descript *nd, struct nameidata *ndp,
}
if (islocked)
NFSVOPUNLOCK(dp);
- VREF(dp);
+ vref(dp);
*retdirp = dp;
if (NFSVNO_EXRDONLY(exp))
cnp->cn_flags |= RDONLY;
@@ -697,7 +697,7 @@ nfsvno_namei(struct nfsrv_descript *nd, struct nameidata *ndp,
goto out;
}
dp = rootvnode;
- VREF(dp);
+ vref(dp);
}
} else if ((nfsrv_enable_crossmntpt == 0 && NFSVNO_EXPORTED(exp)) ||
(nd->nd_flag & ND_NFSV4) == 0) {
@@ -814,7 +814,7 @@ nfsvno_namei(struct nfsrv_descript *nd, struct nameidata *ndp,
if (cnp->cn_pnbuf[0] == '/') {
vrele(ndp->ni_dvp);
ndp->ni_dvp = ndp->ni_rootdir;
- VREF(ndp->ni_dvp);
+ vref(ndp->ni_dvp);
}
ndp->ni_startdir = ndp->ni_dvp;
ndp->ni_dvp = NULL;
@@ -2114,7 +2114,7 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp,
struct ucred *cred, struct thread *p, int isdgram, int reterr,
int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno,
bool xattrsupp, bool has_hiddensystem, bool has_namedattr,
- uint32_t clone_blksize)
+ uint32_t clone_blksize, bool has_caseinsensitive)
{
struct statfs *sf;
int error;
@@ -2135,7 +2135,7 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp,
error = nfsv4_fillattr(nd, mp, vp, NULL, &nvap->na_vattr, fhp, rderror,
attrbitp, cred, p, isdgram, reterr, supports_nfsv4acls, at_root,
mounted_on_fileno, sf, xattrsupp, has_hiddensystem, has_namedattr,
- clone_blksize);
+ clone_blksize, NULL, has_caseinsensitive);
free(sf, M_TEMP);
NFSEXITCODE2(0, nd);
return (error);
@@ -2468,7 +2468,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
int bextpg0, bextpg1, bextpgsiz0, bextpgsiz1;
size_t atsiz;
long pathval;
- bool has_hiddensystem, has_namedattr, xattrsupp;
+ bool has_caseinsensitive, has_hiddensystem, has_namedattr, xattrsupp;
if (nd->nd_repstat) {
nfsrv_postopattr(nd, getret, &at);
@@ -2949,6 +2949,7 @@ ateof:
xattrsupp = false;
has_hiddensystem = false;
has_namedattr = false;
+ has_caseinsensitive = false;
clone_blksize = 0;
if (nvp != NULL) {
supports_nfsv4acls =
@@ -2978,6 +2979,11 @@ ateof:
&pathval) != 0)
pathval = 0;
clone_blksize = pathval;
+ if (VOP_PATHCONF(nvp,
+ _PC_CASE_INSENSITIVE,
+ &pathval) != 0)
+ pathval = 0;
+ has_caseinsensitive = pathval > 0;
NFSVOPUNLOCK(nvp);
} else
supports_nfsv4acls = 0;
@@ -2999,7 +3005,7 @@ ateof:
supports_nfsv4acls, at_root,
mounted_on_fileno, xattrsupp,
has_hiddensystem, has_namedattr,
- clone_blksize);
+ clone_blksize, has_caseinsensitive);
} else {
dirlen += nfsvno_fillattr(nd, new_mp,
nvp, nvap, &nfh, r, &attrbits,
@@ -3007,7 +3013,7 @@ ateof:
supports_nfsv4acls, at_root,
mounted_on_fileno, xattrsupp,
has_hiddensystem, has_namedattr,
- clone_blksize);
+ clone_blksize, has_caseinsensitive);
}
if (nvp != NULL)
vrele(nvp);
@@ -3193,7 +3199,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 +3233,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:
@@ -3478,11 +3487,6 @@ nfsd_excred(struct nfsrv_descript *nd, struct nfsexstuff *exp,
(nd->nd_flag & ND_AUTHNONE) != 0) {
nd->nd_cred->cr_uid = credanon->cr_uid;
nd->nd_cred->cr_gid = credanon->cr_gid;
- /*
- * 'credanon' is already a 'struct ucred' that was built
- * internally with calls to crsetgroups_and_egid(), so
- * we don't need a fallback here.
- */
crsetgroups(nd->nd_cred, credanon->cr_ngroups,
credanon->cr_groups);
} else if ((nd->nd_flag & ND_GSS) == 0) {
@@ -6407,7 +6411,7 @@ nfsrv_setacldsdorpc(fhandle_t *fhp, struct ucred *cred, NFSPROC_T *p,
* the same type (VREG).
*/
nfsv4_fillattr(nd, NULL, vp, aclp, NULL, NULL, 0, &attrbits, NULL,
- NULL, 0, 0, 0, 0, 0, NULL, false, false, false, 0);
+ NULL, 0, 0, 0, 0, 0, NULL, false, false, false, 0, NULL, false);
error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred,
NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL);
if (error != 0) {
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index a881968b03be..394b63c2ab07 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -252,7 +252,7 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
struct thread *p = curthread;
size_t atsiz;
long pathval;
- bool has_hiddensystem, has_namedattr, xattrsupp;
+ bool has_caseinsensitive, has_hiddensystem, has_namedattr, xattrsupp;
uint32_t clone_blksize;
if (nd->nd_repstat)
@@ -336,13 +336,17 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
&pathval) != 0)
pathval = 0;
clone_blksize = pathval;
+ if (VOP_PATHCONF(vp, _PC_CASE_INSENSITIVE,
+ &pathval) != 0)
+ pathval = 0;
+ has_caseinsensitive = pathval > 0;
mp = vp->v_mount;
if (nfsrv_enable_crossmntpt != 0 &&
vp->v_type == VDIR &&
(vp->v_vflag & VV_ROOT) != 0 &&
vp != rootvnode) {
tvp = mp->mnt_vnodecovered;
- VREF(tvp);
+ vref(tvp);
at_root = 1;
} else
at_root = 0;
@@ -371,7 +375,8 @@ nfsrvd_getattr(struct nfsrv_descript *nd, int isdgram,
isdgram, 1, supports_nfsv4acls,
at_root, mounted_on_fileno,
xattrsupp, has_hiddensystem,
- has_namedattr, clone_blksize);
+ has_namedattr, clone_blksize,
+ has_caseinsensitive);
vfs_unbusy(mp);
}
vrele(vp);
@@ -436,6 +441,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 +575,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 +601,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))
@@ -1766,7 +1781,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
/* If this is the same file handle, just VREF() the vnode. */
if (!NFSBCMP(tfh.nfsrvfh_data, &fh, NFSX_MYFH)) {
- VREF(dp);
+ vref(dp);
tdp = dp;
tnes = *exp;
tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd, p, 1,
@@ -5128,6 +5143,11 @@ nfsrvd_layoutcommit(struct nfsrv_descript *nd, __unused int isdgram,
NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED);
layouttype = fxdr_unsigned(int, *tl++);
maxcnt = fxdr_unsigned(int, *tl);
+ /* There is no limit in the RFC, so use 1000 as a sanity limit. */
+ if (maxcnt < 0 || maxcnt > 1000) {
+ error = NFSERR_BADXDR;
+ goto nfsmout;
+ }
if (maxcnt > 0) {
layp = malloc(maxcnt + 1, M_TEMP, M_WAITOK);
error = nfsrv_mtostr(nd, layp, maxcnt);
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c
index 636c4735a131..201f3b74b946 100644
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -1110,7 +1110,7 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
if (vp != savevp) {
if (savevp)
vrele(savevp);
- VREF(vp);
+ vref(vp);
savevp = vp;
savevpnes = vpnes;
save_fsid = cur_fsid;
@@ -1155,7 +1155,7 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
nfsvno_testexp(nd,
&savevpnes);
if (nd->nd_repstat == 0) {
- VREF(savevp);
+ vref(savevp);
vrele(vp);
vp = savevp;
vpnes = savevpnes;
@@ -1235,7 +1235,7 @@ tryagain:
break;
}
}
- VREF(vp);
+ vref(vp);
if (nfsv4_opflag[op].modifyfs)
vn_start_write(vp, &temp_mp, V_WAIT);
error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
@@ -1279,8 +1279,8 @@ tryagain:
if (nfsv4_opflag[op].modifyfs)
vn_start_write(savevp, &temp_mp, V_WAIT);
if (NFSVOPLOCK(savevp, LK_EXCLUSIVE) == 0) {
- VREF(vp);
- VREF(savevp);
+ vref(vp);
+ vref(savevp);
error = (*(nfsrv4_ops2[op]))(nd, isdgram,
savevp, vp, &savevpnes, &vpnes);
} else
@@ -1301,7 +1301,7 @@ tryagain:
lktype = LK_SHARED;
}
if (NFSVOPLOCK(vp, lktype) == 0)
- VREF(vp);
+ vref(vp);
else
nd->nd_repstat = NFSERR_PERM;
} else {