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