aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/nfs')
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c94
-rw-r--r--sys/fs/nfs/nfs_var.h6
-rw-r--r--sys/fs/nfs/nfsproto.h4
3 files changed, 75 insertions, 29 deletions
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index 7f5b29ca2085..707ad5749ab2 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -194,7 +194,6 @@ struct nfsv4_opflag nfsv4_opflag[NFSV42_NOPS] = {
{ 0, 1, 1, 1, LK_EXCLUSIVE, 1, 1 }, /* Removexattr */
};
-static int ncl_mbuf_mhlen = MHLEN;
struct nfsrv_lughash {
struct mtx mtx;
struct nfsuserhashhead lughead;
@@ -216,10 +215,17 @@ NFSD_VNET_DEFINE_STATIC(u_char *, nfsrv_dnsname) = NULL;
* marked 0 in this array, the code will still work, just not quite as
* efficiently.)
*/
-static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 };
+static bool nfs_bigreply[NFSV42_NPROCS] = {
+ [NFSPROC_GETACL] = true,
+ [NFSPROC_GETEXTATTR] = true,
+ [NFSPROC_LISTEXTATTR] = true,
+ [NFSPROC_LOOKUP] = true,
+ [NFSPROC_READ] = true,
+ [NFSPROC_READDIR] = true,
+ [NFSPROC_READDIRPLUS] = true,
+ [NFSPROC_READDS] = true,
+ [NFSPROC_READLINK] = true,
+};
/* local functions */
static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep);
@@ -232,6 +238,8 @@ static int nfsrv_getrefstr(struct nfsrv_descript *, u_char **, u_char **,
static void nfsrv_refstrbigenough(int, u_char **, u_char **, int *);
static uint32_t vtonfsv4_type(struct vattr *);
static __enum_uint8(vtype) nfsv4tov_type(uint32_t, uint16_t *);
+static void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *,
+ struct nfsclsession *, bool, struct ucred *);
static struct {
int op;
@@ -632,6 +640,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);
}
@@ -649,7 +658,7 @@ nfscl_fillsattr(struct nfsrv_descript *nd, struct vattr *vap,
NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMECREATE);
(void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0,
&attrbits, NULL, NULL, 0, 0, 0, 0, (uint64_t)0, NULL,
- false, false, false, 0);
+ false, false, false, 0, NULL, false);
break;
}
}
@@ -760,7 +769,7 @@ nfsm_dissct(struct nfsrv_descript *nd, int siz, int how)
nd->nd_dpos += siz;
} else if (nd->nd_md->m_next == NULL) {
return (retp);
- } else if (siz > ncl_mbuf_mhlen) {
+ } else if (siz > MHLEN) {
panic("nfs S too big");
} else {
MGET(mp2, how, MT_DATA);
@@ -1663,9 +1672,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:
@@ -1689,11 +1706,18 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
attrsum += NFSX_UNSIGNED;
break;
case NFSATTRBIT_CASEINSENSITIVE:
- NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
+ NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
if (compare) {
if (!(*retcmpp)) {
- if (*tl != newnfs_false)
- *retcmpp = NFSERR_NOTSAME;
+ if (vp == NULL || VOP_PATHCONF(vp,
+ _PC_CASE_INSENSITIVE,
+ &has_pathconf) != 0)
+ has_pathconf = 0;
+ if ((has_pathconf != 0 &&
+ *tl != newnfs_true) ||
+ (has_pathconf == 0 &&
+ *tl != newnfs_false))
+ *retcmpp = NFSERR_NOTSAME;
}
} else if (pc != NULL) {
pc->pc_caseinsensitive =
@@ -2673,7 +2697,8 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram,
int reterr, int supports_nfsv4acls, int at_root, uint64_t mounted_on_fileno,
struct statfs *pnfssf, bool xattrsupp, bool has_hiddensystem,
- bool has_namedattr, uint32_t clone_blksize)
+ bool has_namedattr, uint32_t clone_blksize, fsid_t *fsidp,
+ bool has_caseinsensitive)
{
int bitpos, retnum = 0;
u_int32_t *tl;
@@ -2795,6 +2820,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,
@@ -2847,10 +2873,12 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
break;
case NFSATTRBIT_FSID:
NFSM_BUILD(tl, u_int32_t *, NFSX_V4FSID);
+ if (fsidp == NULL)
+ fsidp = &mp->mnt_stat.f_fsid;
*tl++ = 0;
- *tl++ = txdr_unsigned(mp->mnt_stat.f_fsid.val[0]);
+ *tl++ = txdr_unsigned(fsidp->val[0]);
*tl++ = 0;
- *tl = txdr_unsigned(mp->mnt_stat.f_fsid.val[1]);
+ *tl = txdr_unsigned(fsidp->val[1]);
retnum += NFSX_V4FSID;
break;
case NFSATTRBIT_UNIQUEHANDLES:
@@ -2879,6 +2907,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)
@@ -2888,8 +2924,11 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
retnum += NFSX_UNSIGNED;
break;
case NFSATTRBIT_CASEINSENSITIVE:
- NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
- *tl = newnfs_false;
+ NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED);
+ if (has_caseinsensitive)
+ *tl = newnfs_true;
+ else
+ *tl = newnfs_false;
retnum += NFSX_UNSIGNED;
break;
case NFSATTRBIT_CASEPRESERVING:
@@ -4165,10 +4204,15 @@ nfssvc_idname(struct nfsd_idargs *nidp)
nidp->nid_namelen);
if (error == 0 && nidp->nid_ngroup > 0 &&
(nidp->nid_flag & NFSID_ADDUID) != 0) {
- grps = malloc(sizeof(gid_t) * nidp->nid_ngroup, M_TEMP,
- M_WAITOK);
- error = copyin(nidp->nid_grps, grps,
- sizeof(gid_t) * nidp->nid_ngroup);
+ grps = NULL;
+ if (nidp->nid_ngroup > NGROUPS_MAX)
+ error = EINVAL;
+ if (error == 0) {
+ grps = malloc(sizeof(gid_t) * nidp->nid_ngroup, M_TEMP,
+ M_WAITOK);
+ error = copyin(nidp->nid_grps, grps,
+ sizeof(gid_t) * nidp->nid_ngroup);
+ }
if (error == 0) {
/*
* Create a credential just like svc_getcred(),
@@ -5021,9 +5065,9 @@ nfsv4_seqsess_cacherep(uint32_t slotid, struct nfsslot *slots, int repstat,
/*
* Generate the xdr for an NFSv4.1 Sequence Operation.
*/
-void
+static void
nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd,
- struct nfsclsession *sep, int dont_replycache, struct ucred *cred)
+ struct nfsclsession *sep, bool dont_replycache, struct ucred *cred)
{
uint32_t *tl, slotseq = 0;
int error, maxslot, slotpos;
@@ -5054,7 +5098,7 @@ nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd,
*tl++ = txdr_unsigned(slotseq);
*tl++ = txdr_unsigned(slotpos);
*tl++ = txdr_unsigned(maxslot);
- if (dont_replycache == 0)
+ if (!dont_replycache)
*tl = newnfs_true;
else
*tl = newnfs_false;
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 61083ecf2d66..7db3952ecf5c 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -361,8 +361,6 @@ int nfsv4_getipaddr(struct nfsrv_descript *, struct sockaddr_in *,
int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *,
struct mbuf **, uint16_t);
void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, int, struct mbuf **);
-void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *,
- struct nfsclsession *, int, struct ucred *);
int nfsv4_sequencelookup(struct nfsmount *, struct nfsclsession *, int *,
int *, uint32_t *, uint8_t *, bool);
void nfsv4_freeslot(struct nfsclsession *, int, bool);
@@ -400,7 +398,7 @@ void nfsrv_wcc(struct nfsrv_descript *, int, struct nfsvattr *, int,
int nfsv4_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, NFSACL_T *,
struct vattr *, fhandle_t *, int, nfsattrbit_t *, struct ucred *,
NFSPROC_T *, int, int, int, int, uint64_t, struct statfs *, bool, bool,
- bool, uint32_t);
+ bool, uint32_t, fsid_t *, bool);
void nfsrv_fillattr(struct nfsrv_descript *, struct nfsvattr *);
struct mbuf *nfsrv_adj(struct mbuf *, int, int);
void nfsrv_postopattr(struct nfsrv_descript *, int, struct nfsvattr *);
@@ -742,7 +740,7 @@ int nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct nfsrv_descript *,
int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t,
struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *,
struct ucred *, NFSPROC_T *, int, int, int, int, uint64_t, bool, bool,
- bool, uint32_t);
+ bool, uint32_t, bool);
int nfsrv_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *,
NFSACL_T *, NFSPROC_T *);
int nfsv4_sattr(struct nfsrv_descript *, vnode_t, struct nfsvattr *, nfsattrbit_t *,
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)