svn commit: r253401 - projects/nfsv4.1-server/sys/fs/nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Tue Jul 16 23:29:25 UTC 2013
Author: rmacklem
Date: Tue Jul 16 23:29:24 2013
New Revision: 253401
URL: http://svnweb.freebsd.org/changeset/base/253401
Log:
Merge in the NFSv4.1 server code for 2 more files.
Modified:
projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdsocket.c
projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdsubs.c
Modified: projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdsocket.c
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdsocket.c Tue Jul 16 23:19:05 2013 (r253400)
+++ projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdsocket.c Tue Jul 16 23:29:24 2013 (r253401)
@@ -48,6 +48,7 @@ extern struct nfsv4lock nfsv4rootfs_lock
extern struct nfsrv_stablefirst nfsrv_stablefirst;
extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE];
extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies;
+extern int nfsd_debuglevel;
NFSV4ROOTLOCKMUTEX;
NFSSTATESPINLOCK;
@@ -131,7 +132,7 @@ int (*nfsrv3_procs2[NFS_V3NPROCS])(struc
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
};
-int (*nfsrv4_ops0[NFSV4OP_NOPS])(struct nfsrv_descript *,
+int (*nfsrv4_ops0[NFSV41_NOPS])(struct nfsrv_descript *,
int, vnode_t , NFSPROC_T *, struct nfsexstuff *) = {
(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , NFSPROC_T *, struct nfsexstuff *))0,
@@ -173,9 +174,28 @@ int (*nfsrv4_ops0[NFSV4OP_NOPS])(struct
nfsrvd_verify,
nfsrvd_write,
nfsrvd_releaselckown,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_exchangeid,
+ nfsrvd_createsession,
+ nfsrvd_destroysession,
+ nfsrvd_freestateid,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_sequence,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_notsupp,
+ nfsrvd_destroyclientid,
+ nfsrvd_reclaimcomplete,
};
-int (*nfsrv4_ops1[NFSV4OP_NOPS])(struct nfsrv_descript *,
+int (*nfsrv4_ops1[NFSV41_NOPS])(struct nfsrv_descript *,
int, vnode_t , vnode_t *, fhandle_t *,
NFSPROC_T *, struct nfsexstuff *) = {
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
@@ -218,9 +238,28 @@ int (*nfsrv4_ops1[NFSV4OP_NOPS])(struct
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t *, fhandle_t *, NFSPROC_T *, struct nfsexstuff *))0,
};
-int (*nfsrv4_ops2[NFSV4OP_NOPS])(struct nfsrv_descript *,
+int (*nfsrv4_ops2[NFSV41_NOPS])(struct nfsrv_descript *,
int, vnode_t , vnode_t , NFSPROC_T *,
struct nfsexstuff *, struct nfsexstuff *) = {
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
@@ -263,6 +302,25 @@ int (*nfsrv4_ops2[NFSV4OP_NOPS])(struct
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
(int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
+ (int (*)(struct nfsrv_descript *, int, vnode_t , vnode_t , NFSPROC_T *, struct nfsexstuff *, struct nfsexstuff *))0,
};
#endif /* !APPLEKEXT */
@@ -304,7 +362,7 @@ static int nfs_writerpc[NFS_NPROCS] = {
/* local functions */
static void nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
- NFSPROC_T *p);
+ u_char *tag, int taglen, u_int32_t minorvers, NFSPROC_T *p);
/*
@@ -314,7 +372,7 @@ static void nfsrvd_compound(struct nfsrv
static int nfs_retfh[NFS_V3NPROCS] = { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0 };
-extern struct nfsv4_opflag nfsv4_opflag[NFSV4OP_NOPS];
+extern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS];
static int nfsv3to4op[NFS_V3NPROCS] = {
NFSPROC_NULL,
@@ -349,8 +407,8 @@ static int nfsv3to4op[NFS_V3NPROCS] = {
* The NFS V4 Compound RPC is performed separately by nfsrvd_compound().
*/
APPLESTATIC void
-nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
- NFSPROC_T *p)
+nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen,
+ u_int32_t minorvers, NFSPROC_T *p)
{
int error = 0, lktype;
vnode_t vp;
@@ -427,7 +485,7 @@ nfsrvd_dorpc(struct nfsrv_descript *nd,
* The group is indicated by the value in nfs_retfh[].
*/
if (nd->nd_flag & ND_NFSV4) {
- nfsrvd_compound(nd, isdgram, p);
+ nfsrvd_compound(nd, isdgram, tag, taglen, minorvers, p);
} else {
if (nfs_retfh[nd->nd_procnum] == 1) {
if (vp)
@@ -482,15 +540,14 @@ out:
* vnode pointer handling.
*/
static void
-nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
- NFSPROC_T *p)
+nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
+ int taglen, u_int32_t minorvers, NFSPROC_T *p)
{
- int i, op;
+ int i, op, op0 = 0;
u_int32_t *tl;
struct nfsclient *clp, *nclp;
- int numops, taglen = -1, error = 0, igotlock;
- u_int32_t minorvers, retops = 0, *retopsp = NULL, *repp;
- u_char tag[NFSV4_SMALLSTR + 1], *tagstr;
+ int numops, error = 0, igotlock;
+ u_int32_t retops = 0, *retopsp = NULL, *repp;
vnode_t vp, nvp, savevp;
struct nfsrvfh fh;
mount_t new_mp, temp_mp = NULL;
@@ -595,31 +652,17 @@ nfsrvd_compound(struct nfsrv_descript *n
savevp = vp = NULL;
save_fsid.val[0] = save_fsid.val[1] = 0;
cur_fsid.val[0] = cur_fsid.val[1] = 0;
- NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
- taglen = fxdr_unsigned(int, *tl);
+
+ /* If taglen < 0, there was a parsing error in nfsd_getminorvers(). */
if (taglen < 0) {
error = EBADRPC;
goto nfsmout;
}
- if (taglen <= NFSV4_SMALLSTR)
- tagstr = tag;
- else
- tagstr = malloc(taglen + 1, M_TEMP, M_WAITOK);
- error = nfsrv_mtostr(nd, tagstr, taglen);
- if (error) {
- if (taglen > NFSV4_SMALLSTR)
- free(tagstr, M_TEMP);
- taglen = -1;
- goto nfsmout;
- }
+
(void) nfsm_strtom(nd, tag, taglen);
- if (taglen > NFSV4_SMALLSTR) {
- free(tagstr, M_TEMP);
- }
NFSM_BUILD(retopsp, u_int32_t *, NFSX_UNSIGNED);
- NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
- minorvers = fxdr_unsigned(u_int32_t, *tl++);
- if (minorvers != NFSV4_MINORVERSION)
+ NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
+ if (minorvers != NFSV4_MINORVERSION && minorvers != NFSV41_MINORVERSION)
nd->nd_repstat = NFSERR_MINORVERMISMATCH;
if (nd->nd_repstat)
numops = 0;
@@ -638,7 +681,10 @@ nfsrvd_compound(struct nfsrv_descript *n
NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED);
*repp = *tl;
op = fxdr_unsigned(int, *tl);
- if (op < NFSV4OP_ACCESS || op >= NFSV4OP_NOPS) {
+ NFSD_DEBUG(4, "op=%d\n", op);
+ if (op < NFSV4OP_ACCESS ||
+ (op >= NFSV4OP_NOPS && (nd->nd_flag & ND_NFSV41) == 0) ||
+ (op >= NFSV41_NOPS && (nd->nd_flag & ND_NFSV41) != 0)) {
nd->nd_repstat = NFSERR_OPILLEGAL;
*repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL);
*repp = nfsd_errmap(nd);
@@ -647,6 +693,10 @@ nfsrvd_compound(struct nfsrv_descript *n
} else {
repp++;
}
+ if (i == 0)
+ op0 = op;
+ if (i == numops - 1)
+ nd->nd_flag |= ND_LASTOP;
/*
* Check for a referral on the current FH and, if so, return
@@ -661,6 +711,29 @@ nfsrvd_compound(struct nfsrv_descript *n
break;
}
+ /*
+ * For NFSv4.1, check for a Sequence Operation being first
+ * or one of the other allowed operations by itself.
+ */
+ if ((nd->nd_flag & ND_NFSV41) != 0) {
+ if (i != 0 && op == NFSV4OP_SEQUENCE)
+ nd->nd_repstat = NFSERR_SEQUENCEPOS;
+ else if (i == 0 && op != NFSV4OP_SEQUENCE &&
+ op != NFSV4OP_EXCHANGEID &&
+ op != NFSV4OP_CREATESESSION &&
+ op != NFSV4OP_BINDCONNTOSESS &&
+ op != NFSV4OP_DESTROYCLIENTID &&
+ op != NFSV4OP_DESTROYSESSION)
+ nd->nd_repstat = NFSERR_OPNOTINSESS;
+ else if (i != 0 && op0 != NFSV4OP_SEQUENCE)
+ nd->nd_repstat = NFSERR_NOTONLYOP;
+ if (nd->nd_repstat != 0) {
+ *repp = nfsd_errmap(nd);
+ retops++;
+ break;
+ }
+ }
+
nd->nd_procnum = op;
/*
* If over flood level, reply NFSERR_RESOURCE, if at the first
@@ -672,7 +745,8 @@ nfsrvd_compound(struct nfsrv_descript *n
* If nfsrv_mallocmget_limit() returns True, the system is near
* to its limit for memory that malloc()/mget() can allocate.
*/
- if (i == 0 && nd->nd_rp->rc_refcnt == 0 &&
+ if (i == 0 && (nd->nd_rp == NULL ||
+ nd->nd_rp->rc_refcnt == 0) &&
(nfsrv_mallocmget_limit() ||
nfsrc_tcpsavedreplies > nfsrc_floodlevel)) {
if (nfsrc_tcpsavedreplies > nfsrc_floodlevel) {
Modified: projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdsubs.c
==============================================================================
--- projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdsubs.c Tue Jul 16 23:19:05 2013 (r253400)
+++ projects/nfsv4.1-server/sys/fs/nfsserver/nfs_nfsdsubs.c Tue Jul 16 23:29:24 2013 (r253401)
@@ -46,6 +46,7 @@ extern u_int32_t newnfs_true, newnfs_fal
extern int nfs_pubfhset;
extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE];
extern struct nfslockhashhead nfslockhash[NFSLOCKHASHSIZE];
+extern struct nfssessionhash nfssessionhash[NFSSESSIONHASHSIZE];
extern int nfsrv_useacl;
extern uid_t nfsrv_defaultuid;
extern gid_t nfsrv_defaultgid;
@@ -56,6 +57,8 @@ static nfstype newnfsv2_type[9] = { NFNO
extern nfstype nfsv34_type[9];
#endif /* !APPLEKEXT */
+static u_int32_t nfsrv_isannfserr(u_int32_t);
+
SYSCTL_DECL(_vfs_nfsd);
static int disable_checkutf8 = 0;
@@ -68,16 +71,16 @@ static char nfsrv_hexdigit(char, int *);
/*
* Maps errno values to nfs error numbers.
* Use NFSERR_IO as the catch all for ones not specifically defined in
- * RFC 1094.
+ * RFC 1094. (It now includes the errors added for NFSv3.)
*/
-static u_char nfsrv_v2errmap[ELAST] = {
+static u_char nfsrv_v2errmap[NFSERR_REMOTE] = {
NFSERR_PERM, NFSERR_NOENT, NFSERR_IO, NFSERR_IO, NFSERR_IO,
NFSERR_NXIO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO,
NFSERR_IO, NFSERR_IO, NFSERR_ACCES, NFSERR_IO, NFSERR_IO,
- NFSERR_IO, NFSERR_EXIST, NFSERR_IO, NFSERR_NODEV, NFSERR_NOTDIR,
- NFSERR_ISDIR, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO,
+ NFSERR_IO, NFSERR_EXIST, NFSERR_XDEV, NFSERR_NODEV, NFSERR_NOTDIR,
+ NFSERR_ISDIR, NFSERR_INVAL, NFSERR_IO, NFSERR_IO, NFSERR_IO,
NFSERR_IO, NFSERR_FBIG, NFSERR_NOSPC, NFSERR_IO, NFSERR_ROFS,
- NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO,
+ NFSERR_MLINK, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO,
NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO,
NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO,
NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO,
@@ -85,9 +88,7 @@ static u_char nfsrv_v2errmap[ELAST] = {
NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO,
NFSERR_IO, NFSERR_IO, NFSERR_NAMETOL, NFSERR_IO, NFSERR_IO,
NFSERR_NOTEMPTY, NFSERR_IO, NFSERR_IO, NFSERR_DQUOT, NFSERR_STALE,
- NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO,
- NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO,
- NFSERR_IO,
+ NFSERR_REMOTE,
};
/*
@@ -1493,19 +1494,41 @@ nfsd_errmap(struct nfsrv_descript *nd)
else if (nd->nd_repstat == NFSERR_MINORVERMISMATCH ||
nd->nd_repstat == NFSERR_OPILLEGAL)
return (txdr_unsigned(nd->nd_repstat));
- else
+ else if ((nd->nd_flag & ND_NFSV41) != 0) {
+ if (nd->nd_repstat == EOPNOTSUPP)
+ nd->nd_repstat = NFSERR_NOTSUPP;
+ nd->nd_repstat = nfsrv_isannfserr(nd->nd_repstat);
+ return (txdr_unsigned(nd->nd_repstat));
+ } else
errp = defaulterrp = nfsrv_v4errmap[nd->nd_procnum];
while (*++errp)
if (*errp == nd->nd_repstat)
return (txdr_unsigned(nd->nd_repstat));
return (txdr_unsigned(*defaulterrp));
}
- if (nd->nd_repstat <= ELAST)
+ if (nd->nd_repstat <= NFSERR_REMOTE)
return (txdr_unsigned(nfsrv_v2errmap[nd->nd_repstat - 1]));
return (txdr_unsigned(NFSERR_IO));
}
/*
+ * Check to see if the error is a valid NFS one. If not, replace it with
+ * NFSERR_IO.
+ */
+static u_int32_t
+nfsrv_isannfserr(u_int32_t errval)
+{
+
+ if (errval == NFSERR_OK)
+ return (errval);
+ if (errval >= NFSERR_BADHANDLE && errval <= NFSERR_DELEGREVOKED)
+ return (errval);
+ if (errval > 0 && errval <= NFSERR_REMOTE)
+ return (nfsrv_v2errmap[errval - 1]);
+ return (NFSERR_IO);
+}
+
+/*
* Check to see if setting a uid/gid is permitted when creating a new
* file object. (Called when uid and/or gid is specified in the
* settable attributes for V4.
@@ -2046,6 +2069,8 @@ nfsd_init(void)
LIST_INIT(&nfsclienthash[i]);
for (i = 0; i < NFSLOCKHASHSIZE; i++)
LIST_INIT(&nfslockhash[i]);
+ for (i = 0; i < NFSSESSIONHASHSIZE; i++)
+ LIST_INIT(&nfssessionhash[i].list);
/* and the v2 pubfh should be all zeros */
NFSBZERO(nfs_v2pubfh, NFSX_V2FH);
@@ -2073,3 +2098,42 @@ nfsd_checkrootexp(struct nfsrv_descript
return (1);
}
+/*
+ * Parse the first part of an NFSv4 compound to find out what the minor
+ * version# is.
+ */
+void
+nfsd_getminorvers(struct nfsrv_descript *nd, u_char *tag, u_char **tagstrp,
+ int *taglenp, u_int32_t *minversp)
+{
+ uint32_t *tl;
+ int error = 0, taglen = -1;
+ u_char *tagstr = NULL;
+
+ NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
+ taglen = fxdr_unsigned(int, *tl);
+ if (taglen < 0 || taglen > NFSV4_OPAQUELIMIT) {
+ error = EBADRPC;
+ goto nfsmout;
+ }
+ if (taglen <= NFSV4_SMALLSTR)
+ tagstr = tag;
+ else
+ tagstr = malloc(taglen + 1, M_TEMP, M_WAITOK);
+ error = nfsrv_mtostr(nd, tagstr, taglen);
+ if (error != 0)
+ goto nfsmout;
+ NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
+ *minversp = fxdr_unsigned(u_int32_t, *tl);
+ *tagstrp = tagstr;
+ if (*minversp == NFSV41_MINORVERSION)
+ nd->nd_flag |= ND_NFSV41;
+nfsmout:
+ if (error != 0) {
+ if (tagstr != NULL && taglen > NFSV4_SMALLSTR)
+ free(tagstr, M_TEMP);
+ taglen = -1;
+ }
+ *taglenp = taglen;
+}
+
More information about the svn-src-projects
mailing list