Date: Sat, 10 Dec 2011 02:06:11 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r228385 - in projects/nfsv4.1-client/sys/fs: nfs nfsclient Message-ID: <201112100206.pBA26Bhh059411@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Sat Dec 10 02:06:11 2011 New Revision: 228385 URL: http://svn.freebsd.org/changeset/base/228385 Log: Add the NFS client changes for a basic NFSv4.1 client. This includes support for sessions for both fore and back channels, creation of a ClientID the NFSv4.1 way and code that avoids using NFSv4.0 operations defined as "mandatory to not implement" for NFSv4.1. It includes handling of NFSv4.1 callbacks via a callback session. It does not include the new NFSv4.1 optional features like pNFS, but does allow the client to work with an NFSv4.1 server and creates the base on which pNFS can be implemented. The new operations are not counted in the nfsstats structure, since it needs to remain the same size, so that the nfsstats command will still work. It adds a new mount option called "minvers" which can be used to specify an NFSv4.1 mount. For example: "mount -t nfs -o nfsv4,minvers=1 <server>:/ /<path> Changes to sys/rpc are required before this will build/work. Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs.h projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c projects/nfsv4.1-client/sys/fs/nfs/nfs_commonsubs.c projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h projects/nfsv4.1-client/sys/fs/nfs/nfsport.h projects/nfsv4.1-client/sys/fs/nfs/nfsproto.h projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clkdtrace.c projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clkrpc.c projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfs.h Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfs/nfs.h Sat Dec 10 02:06:11 2011 (r228385) @@ -50,6 +50,7 @@ #define NFS_MAXREXMIT 100 /* Stop counting after this many */ #define NFSV4_CALLBACKTIMEO (2 * NFS_HZ) /* Timeout in ticks */ #define NFSV4_CALLBACKRETRY 5 /* Number of retries before failure */ +#define NFSV4_CBSLOTS 8 /* Number of slots for session */ #define NFSV4_CBRETRYCNT 4 /* # of CBRecall retries upon err */ #define NFSV4_UPCALLTIMEO (15 * NFS_HZ) /* Timeout in ticks for upcalls */ /* to gssd or nfsuserd */ @@ -529,6 +530,7 @@ struct nfsrv_descript { nfsquad_t nd_clientid; /* Implied clientid */ int nd_gssnamelen; /* principal name length */ char *nd_gssname; /* principal name */ + uint32_t *nd_slotseq; /* ptr to slot seq# in req */ }; #define nd_princlen nd_gssnamelen @@ -559,6 +561,8 @@ struct nfsrv_descript { #define ND_EXGSSINTEGRITY 0x00200000 #define ND_EXGSSPRIVACY 0x00400000 #define ND_INCRSEQID 0x00800000 +#define ND_NFSV41 0x01000000 +#define ND_HASSEQUENCE 0x02000000 /* * ND_GSS should be the "or" of all GSS type authentications. @@ -571,6 +575,7 @@ struct nfsv4_opflag { int savereply; int modifyfs; int lktype; + int needsseq; }; /* @@ -644,6 +649,15 @@ struct nfsv4lock { #define NFSACCCHK_VPNOTLOCKED 0 #define NFSACCCHK_VPISLOCKED 1 +/* + * Slot for the NFSv4.1 Sequence Op. + */ +struct nfsslot { + int nfssl_inprog; + uint32_t nfssl_seq; + struct mbuf *nfssl_reply; +}; + #endif /* _KERNEL */ #endif /* _NFS_NFS_H */ Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c Sat Dec 10 02:06:11 2011 (r228385) @@ -77,23 +77,26 @@ dtrace_nfsclient_nfs23_done_probe_func_t /* * Registered probes by RPC type. */ -uint32_t nfscl_nfs2_start_probes[NFS_NPROCS + 1]; -uint32_t nfscl_nfs2_done_probes[NFS_NPROCS + 1]; +uint32_t nfscl_nfs2_start_probes[NFSV41_NPROCS + 1]; +uint32_t nfscl_nfs2_done_probes[NFSV41_NPROCS + 1]; -uint32_t nfscl_nfs3_start_probes[NFS_NPROCS + 1]; -uint32_t nfscl_nfs3_done_probes[NFS_NPROCS + 1]; +uint32_t nfscl_nfs3_start_probes[NFSV41_NPROCS + 1]; +uint32_t nfscl_nfs3_done_probes[NFSV41_NPROCS + 1]; -uint32_t nfscl_nfs4_start_probes[NFS_NPROCS + 1]; -uint32_t nfscl_nfs4_done_probes[NFS_NPROCS + 1]; +uint32_t nfscl_nfs4_start_probes[NFSV41_NPROCS + 1]; +uint32_t nfscl_nfs4_done_probes[NFSV41_NPROCS + 1]; #endif NFSSTATESPINLOCK; NFSREQSPINLOCK; +NFSDLOCKMUTEX; extern struct nfsstats newnfsstats; extern struct nfsreqhead nfsd_reqq; extern int nfscl_ticks; extern void (*ncl_call_invalcaches)(struct vnode *); +extern int nfs_numnfscbd; +SVCPOOL *nfscbd_pool; static int nfsrv_gsscallbackson = 0; static int nfs_bufpackets = 4; static int nfs_reconnects; @@ -168,6 +171,7 @@ newnfs_connect(struct nfsmount *nmp, str struct socket *so; int one = 1, retries, error = 0; struct thread *td = curthread; + SVCXPRT *xprt; /* * We need to establish the socket using the credentials of @@ -268,6 +272,24 @@ newnfs_connect(struct nfsmount *nmp, str retries = nmp->nm_retry; else retries = INT_MAX; + if (NFSHASNFSV4N(nmp)) { + /* + * Make sure the nfscbd_pool doesn't get destroyed + * while doing this. + */ + NFSD_LOCK(); + if (nfs_numnfscbd > 0) { + nfs_numnfscbd++; + NFSD_UNLOCK(); + xprt = svc_vc_create_backchannel(nfscbd_pool); + CLNT_CONTROL(client, CLSET_BACKCHANNEL, xprt); + NFSD_LOCK(); + nfs_numnfscbd--; + if (nfs_numnfscbd == 0) + wakeup(&nfs_numnfscbd); + } + NFSD_UNLOCK(); + } } else { /* * Three cases: @@ -440,9 +462,9 @@ newnfs_request(struct nfsrv_descript *nd struct thread *td, struct ucred *cred, u_int32_t prog, u_int32_t vers, u_char *retsum, int toplevel, u_int64_t *xidp) { - u_int32_t *tl; + u_int32_t retseq, retval, *tl; time_t waituntil; - int i, j, set_uid = 0, set_sigset = 0; + int i = 0, j = 0, opcnt, set_uid = 0, set_sigset = 0, slot, freeslot; int trycnt, error = 0, usegssname = 0, secflavour = AUTH_SYS; u_int16_t procnum; u_int trylater_delay = 1; @@ -627,7 +649,9 @@ newnfs_request(struct nfsrv_descript *nd #endif } trycnt = 0; + freeslot = -1; /* Set to slot that needs to be free'd */ tryagain: + slot = -1; /* Slot that needs a sequence# increment. */ if (nmp == NULL) { timo.tv_usec = 0; if (clp == NULL) @@ -714,6 +738,81 @@ tryagain: */ NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); nd->nd_repstat = fxdr_unsigned(u_int32_t, *tl); +if (nd->nd_repstat >= 10000) printf("proc=%d reps=%d\n",nd->nd_procnum,nd->nd_repstat); + + /* + * Get rid of the tag, return count and SEQUENCE result for + * NFSv4. + */ + if ((nd->nd_flag & ND_NFSV4) != 0) { + NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); + i = fxdr_unsigned(int, *tl); + error = nfsm_advance(nd, NFSM_RNDUP(i), -1); + if (error) + goto nfsmout; + NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + opcnt = fxdr_unsigned(int, *tl++); + i = fxdr_unsigned(int, *tl++); + j = fxdr_unsigned(int, *tl); +if (j >= 10000) printf("fop=%d fst=%d\n",i,j); + /* + * If the first op is Sequence, free up the slot. + */ +if (nmp != NULL && i == NFSV4OP_SEQUENCE && j != 0) printf("failed seq=%d\n", j); + if (nmp != NULL && i == NFSV4OP_SEQUENCE && j == 0) { + NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID + + 5 * NFSX_UNSIGNED); + NFSLOCKMNT(nmp); + tl += NFSX_V4SESSIONID / NFSX_UNSIGNED; + retseq = fxdr_unsigned(uint32_t, *tl++); + slot = fxdr_unsigned(int, *tl++); + freeslot = slot; + if (retseq != nmp->nm_slotseq[slot]) + printf("retseq diff 0x%x\n", retseq); + retval = fxdr_unsigned(uint32_t, *++tl); +#ifdef notyet + if ((retval + 1) < nmp->nm_foreslots) + nmp->nm_foreslots = (retval + 1); + else if ((retval + 1) > nmp->nm_foreslots) + nmp->nm_foreslots = (retval < 64) ? + (retval + 1) : 64; +#else + /* + * There seems to be some confusion with + * respect to whether this value is the + * largest slot number to be used, numbered + * 0<->N-1 or the size of the slot table. + * In other words, is it N or N-1? + * For now, play it safe and assume the + * worst cases of the above, such that + * nm_foreslots might be one less than the + * server specified. This is safe, whereas + * setting nm_foreslots one greater than + * the server intended could cause grief. + */ + if (retval < nmp->nm_foreslots) +{ +printf("foreslots shrinking %d\n", retval); + nmp->nm_foreslots = retval; +} + else if (retval > nmp->nm_foreslots) +{ +printf("foreslots growing %d\n", retval); + nmp->nm_foreslots = (retval < 64) ? + retval : 64; +} +#endif /* notyet */ + NFSUNLOCKMNT(nmp); + + /* Grab the op and status for the next one. */ + if (opcnt > 1) { + NFSM_DISSECT(tl, uint32_t *, + 2 * NFSX_UNSIGNED); + i = fxdr_unsigned(int, *tl++); + j = fxdr_unsigned(int, *tl); + } + } + } if (nd->nd_repstat != 0) { if (((nd->nd_repstat == NFSERR_DELAY || nd->nd_repstat == NFSERR_GRACE) && @@ -738,6 +837,13 @@ tryagain: while (NFSD_MONOSEC < waituntil) (void) nfs_catnap(PZERO, 0, "nfstry"); trylater_delay *= 2; + if (slot != -1) { + NFSLOCKMNT(nmp); + nmp->nm_slotseq[slot]++; + *nd->nd_slotseq = txdr_unsigned( + nmp->nm_slotseq[slot]); + NFSUNLOCKMNT(nmp); + } m_freem(nd->nd_mrep); nd->nd_mrep = NULL; goto tryagain; @@ -754,34 +860,19 @@ tryagain: (*ncl_call_invalcaches)(vp); } } - - /* - * Get rid of the tag, return count, and PUTFH result for V4. - */ - if (nd->nd_flag & ND_NFSV4) { - NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); - i = fxdr_unsigned(int, *tl); - error = nfsm_advance(nd, NFSM_RNDUP(i), -1); - if (error) - goto nfsmout; - NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - i = fxdr_unsigned(int, *++tl); - - /* - * If the first op's status is non-zero, mark that - * there is no more data to process. - */ - if (*++tl) - nd->nd_flag |= ND_NOMOREDATA; - + if ((nd->nd_flag & ND_NFSV4) != 0) { + /* Free the slot, as required. */ + if (freeslot != -1) + nfscl_freeslot(nmp, freeslot); /* - * If the first op is Putfh, throw its results away - * and toss the op# and status for the first op. + * If this op is Putfh, throw its results away. */ - if (nmp != NULL && i == NFSV4OP_PUTFH && *tl == 0) { +if (j >= 10000) printf("nop=%d nst=%d\n",i,j); + if (nmp != NULL && i == NFSV4OP_PUTFH && j == 0) { NFSM_DISSECT(tl,u_int32_t *,2 * NFSX_UNSIGNED); i = fxdr_unsigned(int, *tl++); j = fxdr_unsigned(int, *tl); +if (j >= 10000) printf("n2op=%d n2st=%d\n",i,j); /* * All Compounds that do an Op that must * be in sequence consist of NFSV4OP_PUTFH @@ -804,13 +895,13 @@ tryagain: j != NFSERR_RESOURCE && j != NFSERR_NOFILEHANDLE))) nd->nd_flag |= ND_INCRSEQID; - /* - * If the first op's status is non-zero, mark - * that there is no more data to process. - */ - if (j) - nd->nd_flag |= ND_NOMOREDATA; } + /* + * If this op's status is non-zero, mark + * that there is no more data to process. + */ + if (j) + nd->nd_flag |= ND_NOMOREDATA; /* * If R_DONTRECOVER is set, replace the stale error Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_commonsubs.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfs_commonsubs.c Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfs/nfs_commonsubs.c Sat Dec 10 02:06:11 2011 (r228385) @@ -83,47 +83,66 @@ NFSSOCKMUTEX; * non-idempotent Ops. * Define it here, since it is used by both the client and server. */ -struct nfsv4_opflag nfsv4_opflag[NFSV4OP_NOPS] = { - { 0, 0, 0, 0, LK_EXCLUSIVE }, /* undef */ - { 0, 0, 0, 0, LK_EXCLUSIVE }, /* undef */ - { 0, 0, 0, 0, LK_EXCLUSIVE }, /* undef */ - { 0, 1, 0, 0, LK_SHARED }, /* Access */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* Close */ - { 0, 2, 0, 1, LK_EXCLUSIVE }, /* Commit */ - { 1, 2, 1, 1, LK_EXCLUSIVE }, /* Create */ - { 0, 0, 0, 0, LK_EXCLUSIVE }, /* Delegpurge */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* Delegreturn */ - { 0, 1, 0, 0, LK_SHARED }, /* Getattr */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* GetFH */ - { 2, 1, 1, 1, LK_EXCLUSIVE }, /* Link */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* Lock */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* LockT */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* LockU */ - { 1, 1, 0, 0, LK_EXCLUSIVE }, /* Lookup */ - { 1, 1, 0, 0, LK_EXCLUSIVE }, /* Lookupp */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* NVerify */ - { 1, 1, 0, 1, LK_EXCLUSIVE }, /* Open */ - { 1, 1, 0, 0, LK_EXCLUSIVE }, /* OpenAttr */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* OpenConfirm */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* OpenDowngrade */ - { 1, 0, 0, 0, LK_EXCLUSIVE }, /* PutFH */ - { 1, 0, 0, 0, LK_EXCLUSIVE }, /* PutPubFH */ - { 1, 0, 0, 0, LK_EXCLUSIVE }, /* PutRootFH */ - { 0, 1, 0, 0, LK_SHARED }, /* Read */ - { 0, 1, 0, 0, LK_SHARED }, /* Readdir */ - { 0, 1, 0, 0, LK_SHARED }, /* ReadLink */ - { 0, 2, 1, 1, LK_EXCLUSIVE }, /* Remove */ - { 2, 1, 1, 1, LK_EXCLUSIVE }, /* Rename */ - { 0, 0, 0, 0, LK_EXCLUSIVE }, /* Renew */ - { 0, 0, 0, 0, LK_EXCLUSIVE }, /* RestoreFH */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* SaveFH */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* SecInfo */ - { 0, 2, 1, 1, LK_EXCLUSIVE }, /* Setattr */ - { 0, 0, 0, 0, LK_EXCLUSIVE }, /* SetClientID */ - { 0, 0, 0, 0, LK_EXCLUSIVE }, /* SetClientIDConfirm */ - { 0, 1, 0, 0, LK_EXCLUSIVE }, /* Verify */ - { 0, 2, 1, 1, LK_EXCLUSIVE }, /* Write */ - { 0, 0, 0, 0, LK_EXCLUSIVE }, /* ReleaseLockOwner */ +struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS] = { + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* undef */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* undef */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* undef */ + { 0, 1, 0, 0, LK_SHARED, 1 }, /* Access */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* Close */ + { 0, 2, 0, 1, LK_EXCLUSIVE, 1 }, /* Commit */ + { 1, 2, 1, 1, LK_EXCLUSIVE, 1 }, /* Create */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Delegpurge */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* Delegreturn */ + { 0, 1, 0, 0, LK_SHARED, 1 }, /* Getattr */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* GetFH */ + { 2, 1, 1, 1, LK_EXCLUSIVE, 1 }, /* Link */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* Lock */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* LockT */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* LockU */ + { 1, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* Lookup */ + { 1, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* Lookupp */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* NVerify */ + { 1, 1, 0, 1, LK_EXCLUSIVE, 1 }, /* Open */ + { 1, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* OpenAttr */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* OpenConfirm */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* OpenDowngrade */ + { 1, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* PutFH */ + { 1, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* PutPubFH */ + { 1, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* PutRootFH */ + { 0, 1, 0, 0, LK_SHARED, 1 }, /* Read */ + { 0, 1, 0, 0, LK_SHARED, 1 }, /* Readdir */ + { 0, 1, 0, 0, LK_SHARED, 1 }, /* ReadLink */ + { 0, 2, 1, 1, LK_EXCLUSIVE, 1 }, /* Remove */ + { 2, 1, 1, 1, LK_EXCLUSIVE, 1 }, /* Rename */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Renew */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* RestoreFH */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* SaveFH */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* SecInfo */ + { 0, 2, 1, 1, LK_EXCLUSIVE, 1 }, /* Setattr */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* SetClientID */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* SetClientIDConfirm */ + { 0, 1, 0, 0, LK_EXCLUSIVE, 1 }, /* Verify */ + { 0, 2, 1, 1, LK_EXCLUSIVE, 1 }, /* Write */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* ReleaseLockOwner */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Backchannel Ctrl */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Bind Conn to Sess */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 0 }, /* Exchange ID */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 0 }, /* Create Session */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 0 }, /* Destroy Session */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Free StateID */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Get Dir Deleg */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Get Device Info */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Get Device List */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Layout Commit */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Layout Get */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Layout Return */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Secinfo No name */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Sequence */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Set SSV */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Test StateID */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Want Delegation */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 0 }, /* Destroy ClientID */ + { 0, 0, 0, 0, LK_EXCLUSIVE, 1 }, /* Reclaim Complete */ }; #endif /* !APPLEKEXT */ @@ -145,9 +164,9 @@ static struct nfsuserlruhead nfsuserlruh * marked 0 in this array, the code will still work, just not quite as * efficiently.) */ -static int nfs_bigreply[NFS_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, +int nfs_bigreply[NFSV41_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, 0, 0 }; + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* local functions */ static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep); @@ -1855,7 +1874,7 @@ nfsv4_getref(struct nfsv4lock *lp, int * if (isleptp) *isleptp = 1; (void) nfsmsleep(&lp->nfslock_lock, mutex, - PZERO - 1, "nfsv4lck", NULL); + PZERO - 1, "nfsv4gr", NULL); } if (mp != NULL && (mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) return; @@ -3478,3 +3497,47 @@ newnfs_sndunlock(int *flagp) NFSUNLOCKSOCK(); } +/* + * Handle an NFSv4.1 Sequence request for the session. + */ +int +nfsv4_seqsession(uint32_t seqid, uint32_t slotid, uint32_t highslot, + struct nfsslot *slots, struct mbuf **reply, uint16_t maxslot) +{ + int error; + + error = 0; + *reply = NULL; + if (slotid > maxslot) + return (NFSERR_BADSLOT); + if (seqid == slots[slotid].nfssl_seq) { + /* A retry. */ + if (slots[slotid].nfssl_inprog != 0) + error = NFSERR_DELAY; + else if (slots[slotid].nfssl_reply != NULL) { + *reply = slots[slotid].nfssl_reply; + slots[slotid].nfssl_reply = NULL; + slots[slotid].nfssl_inprog = 1; + } else + error = NFSERR_SEQMISORDERED; + } else if ((slots[slotid].nfssl_seq + 1) == seqid) { + m_freem(slots[slotid].nfssl_reply); + slots[slotid].nfssl_reply = NULL; + slots[slotid].nfssl_inprog = 1; + slots[slotid].nfssl_seq++; + } else + error = NFSERR_SEQMISORDERED; + return (error); +} + +/* + * Cache this reply for the slot. + */ +void +nfsv4_seqsess_cacherep(uint32_t slotid, struct nfsslot *slots, struct mbuf *rep) +{ + + slots[slotid].nfssl_reply = rep; + slots[slotid].nfssl_inprog = 0; +} + Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h Sat Dec 10 02:06:11 2011 (r228385) @@ -257,6 +257,9 @@ int nfsrv_mtostr(struct nfsrv_descript * int nfsrv_checkutf8(u_int8_t *, int); int newnfs_sndlock(int *); void newnfs_sndunlock(int *); +int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *, + struct mbuf **, uint16_t); +void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, struct mbuf *); /* nfs_clcomsubs.c */ void nfsm_uiombuf(struct nfsrv_descript *, struct uio *, int); @@ -362,7 +365,7 @@ int nfsrpc_setclient(struct nfsmount *, int nfsrpc_getattr(vnode_t, struct ucred *, NFSPROC_T *, struct nfsvattr *, void *); int nfsrpc_getattrnovp(struct nfsmount *, u_int8_t *, int, int, - struct ucred *, NFSPROC_T *, struct nfsvattr *, u_int64_t *); + struct ucred *, NFSPROC_T *, struct nfsvattr *, u_int64_t *, uint32_t *); int nfsrpc_setattr(vnode_t, struct vattr *, NFSACL_T *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *); int nfsrpc_lookup(vnode_t, char *, int, struct ucred *, NFSPROC_T *, @@ -426,6 +429,14 @@ int nfsrpc_delegreturn(struct nfscldeleg struct nfsmount *, NFSPROC_T *, int); int nfsrpc_getacl(vnode_t, struct ucred *, NFSPROC_T *, NFSACL_T *, void *); int nfsrpc_setacl(vnode_t, struct ucred *, NFSPROC_T *, NFSACL_T *, void *); +int nfsrpc_exchangeid(struct nfsmount *, struct nfsclclient *, + struct ucred *, NFSPROC_T *); +int nfsrpc_createsession(struct nfsmount *, struct nfsclclient *, + struct ucred *, NFSPROC_T *); +int nfsrpc_destroysession(struct nfsmount *, struct nfsclclient *, + struct ucred *, NFSPROC_T *); +int nfsrpc_destroyclient(struct nfsmount *, struct nfsclclient *, + struct ucred *, NFSPROC_T *); /* nfs_clstate.c */ int nfscl_open(vnode_t, u_int8_t *, int, u_int32_t, int, @@ -435,7 +446,7 @@ int nfscl_getstateid(vnode_t, u_int8_t * NFSPROC_T *, nfsv4stateid_t *, void **); void nfscl_ownerrelease(struct nfsclowner *, int, int, int); void nfscl_openrelease(struct nfsclopen *, int, int); -int nfscl_getcl(vnode_t, struct ucred *, NFSPROC_T *, +int nfscl_getcl(struct mount *, struct ucred *, NFSPROC_T *, int, struct nfsclclient **); struct nfsclclient *nfscl_findcl(struct nfsmount *); void nfscl_clientrelease(struct nfsclclient *); @@ -487,6 +498,8 @@ void nfscl_deleggetmodtime(vnode_t, stru int nfscl_tryclose(struct nfsclopen *, struct ucred *, struct nfsmount *, NFSPROC_T *); void nfscl_cleanup(NFSPROC_T *); +void nfscl_setsequence(struct nfsrv_descript *, struct nfsmount *, int); +void nfscl_freeslot(struct nfsmount *, int); /* nfs_clport.c */ int nfscl_nget(mount_t, vnode_t, struct nfsfh *, Modified: projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h Sat Dec 10 02:06:11 2011 (r228385) @@ -50,6 +50,8 @@ struct nfsclclient { struct nfscldeleghead nfsc_deleg; struct nfscldeleghash nfsc_deleghash[NFSCLDELEGHASHSIZE]; struct nfsv4lock nfsc_lock; + struct nfsslot nfsc_cbslots[NFSV4_CBSLOTS]; /* NFSv4.1 cb slot table */ + uint8_t nfsc_sessionid[NFSX_V4SESSIONID]; /* NFSv4.1 session id */ struct proc *nfsc_renewthread; struct nfsmount *nfsc_nmp; nfsquad_t nfsc_clientid; @@ -58,6 +60,7 @@ struct nfsclclient { u_int32_t nfsc_renew; u_int32_t nfsc_cbident; u_int16_t nfsc_flags; + u_int16_t nfsc_backslots; /* Number of back channel slots. */ u_int16_t nfsc_idlen; u_int8_t nfsc_id[1]; /* Malloc'd to correct length */ }; Modified: projects/nfsv4.1-client/sys/fs/nfs/nfsport.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfsport.h Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfs/nfsport.h Sat Dec 10 02:06:11 2011 (r228385) @@ -229,6 +229,34 @@ */ #define NFSV4OP_NOPS 40 +/* + * Additional Ops for NFSv4.1. + */ +#define NFSV4OP_BACKCHANNELCTL 40 +#define NFSV4OP_BINDCONNTOSESS 41 +#define NFSV4OP_EXCHANGEID 42 +#define NFSV4OP_CREATESESSION 43 +#define NFSV4OP_DESTROYSESSION 44 +#define NFSV4OP_FREESTATEID 45 +#define NFSV4OP_GETDIRDELEG 46 +#define NFSV4OP_GETDEVINFO 47 +#define NFSV4OP_GETDEVLIST 48 +#define NFSV4OP_LAYOUTCOMMIT 49 +#define NFSV4OP_LAYOUTGET 50 +#define NFSV4OP_LAYOUTRETURN 51 +#define NFSV4OP_SECINFONONAME 52 +#define NFSV4OP_SEQUENCE 53 +#define NFSV4OP_SETSSV 54 +#define NFSV4OP_TESTSTATEID 55 +#define NFSV4OP_WANTDELEG 56 +#define NFSV4OP_DESTROYCLIENTID 57 +#define NFSV4OP_RECLAIMCOMPL 58 + +/* + * Must be one more than last op#. + */ +#define NFSV41_NOPS 59 + /* Quirky case if the illegal op code */ #define NFSV4OP_OPILLEGAL 10044 @@ -262,6 +290,20 @@ #define NFSV4OP_CBNOPS 5 /* + * Additional Callback Ops for NFSv4.1 only. Not yet in nfsstats. + */ +#define NFSV4OP_CBLAYOUTRECALL 5 +#define NFSV4OP_CBNOTIFY 6 +#define NFSV4OP_CBPUSHDELEG 7 +#define NFSV4OP_CBRECALLANY 8 +#define NFSV4OP_CBRECALLOBJAVAIL 9 +#define NFSV4OP_CBRECALLSLOT 10 +#define NFSV4OP_CBSEQUENCE 11 +#define NFSV4OP_CBWANTCANCELLED 12 +#define NFSV4OP_CBNOTIFYLOCK 13 +#define NFSV4OP_CBNOTIFYDEVID 14 + +/* * The lower numbers -> 21 are used by NFSv2 and v3. These define higher * numbers used by NFSv4. * NFS_V3NPROCS is one greater than the last V3 op and NFS_NPROCS is @@ -294,6 +336,19 @@ * Must be defined as one higher than the last Proc# above. */ #define NFSV4_NPROCS 41 + +/* Additional procedures for NFSv4.1. */ +#define NFSPROC_EXCHANGEID 41 +#define NFSPROC_CREATESESSION 42 +#define NFSPROC_DESTROYSESSION 43 +#define NFSPROC_DESTROYCLIENT 44 +#define NFSPROC_FREESTATEID 45 + +/* + * Must be defined as one higher than the last NFSv4.1 Proc# above. + */ +#define NFSV41_NPROCS 46 + #endif /* NFS_V3NPROCS */ /* @@ -766,6 +821,7 @@ void newnfs_realign(struct mbuf **); #define NFSHASNFSV3(n) ((n)->nm_flag & NFSMNT_NFSV3) #define NFSHASNFSV4(n) ((n)->nm_flag & NFSMNT_NFSV4) +#define NFSHASNFSV4N(n) ((n)->nm_minorvers > 0) #define NFSHASNFSV3OR4(n) ((n)->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) #define NFSHASGOTFSINFO(n) ((n)->nm_state & NFSSTA_GOTFSINFO) #define NFSHASHASSETFSID(n) ((n)->nm_state & NFSSTA_HASSETFSID) Modified: projects/nfsv4.1-client/sys/fs/nfs/nfsproto.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfsproto.h Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfs/nfsproto.h Sat Dec 10 02:06:11 2011 (r228385) @@ -62,7 +62,9 @@ #define NFS_MINPACKET 20 #define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */ #define NFSV4_MINORVERSION 0 /* V4 Minor version */ +#define NFSV41_MINORVERSION 1 /* V4 Minor version */ #define NFSV4_CBVERS 1 /* V4 CB Version */ +#define NFSV41_CBVERS 4 /* V4.1 CB Version */ #define NFSV4_SMALLSTR 50 /* Strings small enough for stack */ /* Stat numbers for rpc returns (version 2, 3 and 4) */ @@ -145,6 +147,12 @@ #define NFSERR_ADMINREVOKED 10047 #define NFSERR_CBPATHDOWN 10048 +/* NFSv4.1 specific errors. */ +#define NFSERR_BADSLOT 10053 +#define NFSERR_SEQMISORDERED 10063 +#define NFSERR_SEQUENCEPOS 10064 +#define NFSERR_OPNOTINSESS 10071 + #define NFSERR_STALEWRITEVERF 30001 /* Fake return for nfs_commit() */ #define NFSERR_DONTREPLY 30003 /* Don't process request */ #define NFSERR_RETVOID 30004 /* Return void, not error */ @@ -189,6 +197,7 @@ #define NFSX_V4SPECDATA (2 * NFSX_UNSIGNED) #define NFSX_V4TIME (NFSX_HYPER + NFSX_UNSIGNED) #define NFSX_V4SETTIME (NFSX_UNSIGNED + NFSX_V4TIME) +#define NFSX_V4SESSIONID 16 /* sizes common to multiple NFS versions */ #define NFSX_FHMAX (NFSX_V4FHMAX) @@ -258,6 +267,19 @@ * Must be defined as one higher than the last Proc# above. */ #define NFSV4_NPROCS 41 + +/* Additional procedures for NFSv4.1. */ +#define NFSPROC_EXCHANGEID 41 +#define NFSPROC_CREATESESSION 42 +#define NFSPROC_DESTROYSESSION 43 +#define NFSPROC_DESTROYCLIENT 44 +#define NFSPROC_FREESTATEID 45 + +/* + * Must be defined as one higher than the last NFSv4.1 Proc# above. + */ +#define NFSV41_NPROCS 46 + #endif /* NFS_V3NPROCS */ /* @@ -269,10 +291,10 @@ /* * NFSPROC_NOOP is a fake op# that can't be the same as any V2/3/4 Procedure - * or Operation#. Since the NFS V4 Op #s go higher, use NFSV4OP_NOPS, which + * or Operation#. Since the NFS V4 Op #s go higher, use NFSV41_NOPS, which * is one greater than the highest Op#. */ -#define NFSPROC_NOOP NFSV4OP_NOPS +#define NFSPROC_NOOP NFSV41_NOPS /* Actual Version 2 procedure numbers */ #define NFSV2PROC_NULL 0 @@ -468,6 +490,42 @@ #define NFSV3FSINFO_HOMOGENEOUS 0x08 #define NFSV3FSINFO_CANSETTIME 0x10 +/* Flags for Exchange ID */ +#define NFSV4EXCH_SUPPMOVEDREFER 0x00000001 +#define NFSV4EXCH_SUPPMOVEDMIGR 0x00000002 +#define NFSV4EXCH_BINDPRINCSTATEID 0x00000100 +#define NFSV4EXCH_USENONPNFS 0x00010000 +#define NFSV4EXCH_USEPNFSMDS 0x00020000 +#define NFSV4EXCH_USEPNFSDS 0x00040000 +#define NFSV4EXCH_MASKPNFS 0x00070000 +#define NFSV4EXCH_UPDCONFIRMEDRECA 0x40000000 +#define NFSV4EXCH_CONFIRMEDR 0x80000000 + +/* State Protects */ +#define NFSV4EXCH_SP4NONE 0 +#define NFSV4EXCH_SP4MACHCRED 1 +#define NFSV4EXCH_SP4SSV 2 + +/* Flags for Create Session */ +#define NFSV4CRSESS_PERSIST 0x00000001 +#define NFSV4CRSESS_CONNBACKCHAN 0x00000002 +#define NFSV4CRSESS_CONNRDMA 0x00000004 + +/* Flags for Sequence */ +#define NFSV4SEQ_CBPATHDOWN 0x00000001 +#define NFSV4SEQ_CBGSSCONTEXPIRING 0x00000002 +#define NFSV4SEQ_CBGSSCONTEXPIRED 0x00000004 +#define NFSV4SEQ_EXPIREDALLSTATEREVOKED 0x00000008 +#define NFSV4SEQ_EXPIREDSOMESTATEREVOKED 0x00000010 +#define NFSV4SEQ_ADMINSTATEREVOKED 0x00000020 +#define NFSV4SEQ_RECALLABLESTATEREVOKED 0x00000040 +#define NFSV4SEQ_LEASEMOVED 0x00000080 +#define NFSV4SEQ_RESTARTRECLAIMNEEDED 0x00000100 +#define NFSV4SEQ_CBPATHDOWNSESSION 0x00000200 +#define NFSV4SEQ_BACKCHANNELFAULT 0x00000400 +#define NFSV4SEQ_DEVIDCHANGED 0x00000800 +#define NFSV4SEQ_DEVIDDELETED 0x00001000 + /* Conversion macros */ #define vtonfsv2_mode(t,m) \ txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \ Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c Sat Dec 10 02:06:11 2011 (r228385) @@ -43,10 +43,11 @@ __FBSDID("$FreeBSD$"); #include <fs/nfs/nfsport.h> extern struct nfsstats newnfsstats; -extern struct nfsv4_opflag nfsv4_opflag[NFSV4OP_NOPS]; +extern struct nfsv4_opflag nfsv4_opflag[NFSV41_NOPS]; extern int ncl_mbuf_mlen; extern enum vtype newnv2tov_type[8]; extern enum vtype nv34tov_type[8]; +extern int nfs_bigreply[NFSV41_NPROCS]; NFSCLSTATEMUTEX; #endif /* !APPLEKEXT */ @@ -56,7 +57,7 @@ static struct { int opcnt; const u_char *tag; int taglen; -} nfsv4_opmap[NFS_NPROCS] = { +} nfsv4_opmap[NFSV41_NPROCS] = { { 0, 1, "Null", 4 }, { NFSV4OP_GETATTR, 1, "Getattr", 7, }, { NFSV4OP_SETATTR, 2, "Setattr", 7, }, @@ -98,15 +99,20 @@ static struct { { NFSV4OP_DELEGRETURN, 9, "DelegRename2", 12, }, { NFSV4OP_GETATTR, 1, "Getacl", 6, }, { NFSV4OP_SETATTR, 1, "Setacl", 6, }, + { NFSV4OP_EXCHANGEID, 1, "ExchangeID", 10, }, + { NFSV4OP_CREATESESSION, 1, "CreateSession", 13, }, + { NFSV4OP_DESTROYSESSION, 1, "DestroySession", 14, }, + { NFSV4OP_DESTROYCLIENTID, 1, "DestroyClient", 13, }, + { NFSV4OP_FREESTATEID, 1, "FreeStateID", 11, }, }; /* * NFS RPCS that have large request message size. */ -static int nfs_bigrequest[NFS_NPROCS] = { +static int nfs_bigrequest[NFSV41_NPROCS] = { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* @@ -125,9 +131,12 @@ nfscl_reqstart(struct nfsrv_descript *nd /* * First, fill in some of the fields of nd. */ - if (NFSHASNFSV4(nmp)) + nd->nd_slotseq = NULL; + if (NFSHASNFSV4(nmp)) { nd->nd_flag = ND_NFSV4; - else if (NFSHASNFSV3(nmp)) + if (NFSHASNFSV4N(nmp)) + nd->nd_flag |= ND_NFSV41; + } else if (NFSHASNFSV3(nmp)) nd->nd_flag = ND_NFSV3; else nd->nd_flag = ND_NFSV2; @@ -151,17 +160,36 @@ nfscl_reqstart(struct nfsrv_descript *nd if (nd->nd_flag & ND_NFSV4) { opcnt = nfsv4_opmap[procnum].opcnt + nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh; + if ((nd->nd_flag & ND_NFSV41) != 0) { + opcnt += nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq; + if (procnum == NFSPROC_RENEW) + /* + * For the special case of Renew, just do a + * Sequence Op. + */ + opcnt = 1; + } /* * What should the tag really be? */ (void) nfsm_strtom(nd, nfsv4_opmap[procnum].tag, nfsv4_opmap[procnum].taglen); - NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(NFSV4_MINORVERSION); + NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + if ((nd->nd_flag & ND_NFSV41) != 0) + *tl++ = txdr_unsigned(NFSV41_MINORVERSION); + else + *tl++ = txdr_unsigned(NFSV4_MINORVERSION); if (opcntpp != NULL) *opcntpp = tl; - *tl++ = txdr_unsigned(opcnt); + *tl = txdr_unsigned(opcnt); + if ((nd->nd_flag & ND_NFSV41) != 0 && + nfsv4_opflag[nfsv4_opmap[procnum].op].needsseq > 0) { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV4OP_SEQUENCE); + nfscl_setsequence(nd, nmp, nfs_bigreply[procnum]); + } if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_PUTFH); (void) nfsm_fhtom(nd, nfhp, fhlen, 0); if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh==2){ @@ -171,13 +199,17 @@ nfscl_reqstart(struct nfsrv_descript *nd (void) nfsrv_putattrbit(nd, &attrbits); nd->nd_flag |= ND_V4WCCATTR; } + } + if (procnum != NFSPROC_RENEW || + (nd->nd_flag & ND_NFSV41) == 0) { NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(nfsv4_opmap[procnum].op); } - *tl = txdr_unsigned(nfsv4_opmap[procnum].op); } else { (void) nfsm_fhtom(nd, nfhp, fhlen, 0); } - NFSINCRGLOBAL(newnfsstats.rpccnt[procnum]); + if (procnum < NFSV4_NPROCS) + NFSINCRGLOBAL(newnfsstats.rpccnt[procnum]); } #ifndef APPLE Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clkdtrace.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clkdtrace.c Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clkdtrace.c Sat Dec 10 02:06:11 2011 (r228385) @@ -92,7 +92,7 @@ struct dtnfsclient_rpc { * This table is indexed by NFSv3 procedure number, but also used for NFSv2 * procedure names and NFSv4 operations. */ -static struct dtnfsclient_rpc dtnfsclient_rpcs[NFS_NPROCS + 1] = { +static struct dtnfsclient_rpc dtnfsclient_rpcs[NFSV41_NPROCS + 1] = { { "null", "null", "null" }, { "getattr", "getattr", "getattr" }, { "setattr", "setattr", "setattr" }, @@ -196,17 +196,17 @@ extern uint32_t nfscl_attrcache_load_don * stored in one of these two NFS client-allocated arrays; 0 indicates that * the event is not being traced so probes should not be called. * - * For simplicity, we allocate both v2, v3 and v4 arrays as NFS_NPROCS + 1, and - * the v2, v3 arrays are simply sparse. + * For simplicity, we allocate both v2, v3 and v4 arrays as NFSV41_NPROCS + 1, + * and the v2, v3 arrays are simply sparse. */ -extern uint32_t nfscl_nfs2_start_probes[NFS_NPROCS + 1]; -extern uint32_t nfscl_nfs2_done_probes[NFS_NPROCS + 1]; +extern uint32_t nfscl_nfs2_start_probes[NFSV41_NPROCS + 1]; +extern uint32_t nfscl_nfs2_done_probes[NFSV41_NPROCS + 1]; -extern uint32_t nfscl_nfs3_start_probes[NFS_NPROCS + 1]; -extern uint32_t nfscl_nfs3_done_probes[NFS_NPROCS + 1]; +extern uint32_t nfscl_nfs3_start_probes[NFSV41_NPROCS + 1]; +extern uint32_t nfscl_nfs3_done_probes[NFSV41_NPROCS + 1]; -extern uint32_t nfscl_nfs4_start_probes[NFS_NPROCS + 1]; -extern uint32_t nfscl_nfs4_done_probes[NFS_NPROCS + 1]; +extern uint32_t nfscl_nfs4_start_probes[NFSV41_NPROCS + 1]; +extern uint32_t nfscl_nfs4_done_probes[NFSV41_NPROCS + 1]; /* * Look up a DTrace probe ID to see if it's associated with a "done" event -- @@ -217,7 +217,7 @@ dtnfs234_isdoneprobe(dtrace_id_t id) { int i; - for (i = 0; i < NFS_NPROCS + 1; i++) { + for (i = 0; i < NFSV41_NPROCS + 1; i++) { if (dtnfsclient_rpcs[i].nr_v4_id_done == id || dtnfsclient_rpcs[i].nr_v3_id_done == id || dtnfsclient_rpcs[i].nr_v2_id_done == id) @@ -401,7 +401,7 @@ dtnfsclient_provide(void *arg, dtrace_pr * Register NFSv2 RPC procedures; note sparseness check for each slot * in the NFSv3, NFSv4 procnum-indexed array. */ - for (i = 0; i < NFS_NPROCS + 1; i++) { + for (i = 0; i < NFSV41_NPROCS + 1; i++) { if (dtnfsclient_rpcs[i].nr_v2_name != NULL && dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str, dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_start_str) == @@ -430,7 +430,7 @@ dtnfsclient_provide(void *arg, dtrace_pr * Register NFSv3 RPC procedures; note sparseness check for each slot * in the NFSv4 procnum-indexed array. */ - for (i = 0; i < NFS_NPROCS + 1; i++) { + for (i = 0; i < NFSV41_NPROCS + 1; i++) { if (dtnfsclient_rpcs[i].nr_v3_name != NULL && dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str, dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_start_str) == @@ -458,7 +458,7 @@ dtnfsclient_provide(void *arg, dtrace_pr /* * Register NFSv4 RPC procedures. */ - for (i = 0; i < NFS_NPROCS + 1; i++) { + for (i = 0; i < NFSV41_NPROCS + 1; i++) { if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs4_str, dtnfsclient_rpcs[i].nr_v4_name, dtnfsclient_start_str) == 0) { Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clkrpc.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clkrpc.c Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clkrpc.c Sat Dec 10 02:06:11 2011 (r228385) @@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$"); NFSDLOCKMUTEX; -SVCPOOL *nfscbd_pool; +extern SVCPOOL *nfscbd_pool; static int nfs_cbproc(struct nfsrv_descript *, u_int32_t); @@ -91,6 +91,7 @@ nfscb_program(struct svc_req *rqst, SVCX nd.nd_mreq = NULL; nd.nd_cred = NULL; +printf("cbproc=%d\n",nd.nd_procnum); if (nd.nd_procnum != NFSPROC_NULL) { if (!svc_getcred(rqst, &nd.nd_cred, &credflavor)) { svcerr_weakauth(rqst); @@ -136,6 +137,8 @@ nfscb_program(struct svc_req *rqst, SVCX m_freem(nd.nd_mreq); } else if (!svc_sendreply_mbuf(rqst, nd.nd_mreq)) { svcerr_systemerr(rqst); +} else { +printf("cbrep sent\n"); } svc_freereq(rqst); } @@ -272,13 +275,15 @@ nfsrvd_cbinit(int terminating) NFSD_LOCK_ASSERT(); if (terminating) { + /* Wait for any xprt registrations to complete. */ + while (nfs_numnfscbd > 0) + msleep(&nfs_numnfscbd, NFSDLOCKMUTEXPTR, PZERO, + "nfscbdt", 0); NFSD_UNLOCK(); svcpool_destroy(nfscbd_pool); nfscbd_pool = NULL; - NFSD_LOCK(); - } - - NFSD_UNLOCK(); + } else + NFSD_UNLOCK(); nfscbd_pool = svcpool_create("nfscbd", NULL); nfscbd_pool->sp_rcache = NULL; Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c Sat Dec 10 01:44:24 2011 (r228384) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c Sat Dec 10 02:06:11 2011 (r228385) @@ -720,10 +720,13 @@ nfsrpc_openconfirm(vnode_t vp, u_int8_t { u_int32_t *tl; struct nfsrv_descript nfsd, *nd = &nfsd; + struct nfsmount *nmp; int error; - nfscl_reqstart(nd, NFSPROC_OPENCONFIRM, VFSTONFS(vnode_mount(vp)), *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201112100206.pBA26Bhh059411>