Date: Wed, 22 Feb 2012 04:52:39 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r231993 - in projects/nfsv4.1-client/sys/fs: nfs nfsclient Message-ID: <201202220452.q1M4qd6W035189@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Wed Feb 22 04:52:38 2012 New Revision: 231993 URL: http://svn.freebsd.org/changeset/base/231993 Log: Restructure the nfsclds structure which holds NFSv4.1 sessions so that it becomes a list off of the mount point. This is needed so that it can be easily searched for the "same server" as the DS just connected to. In turn, this is needed, since you cannot create a second session on the same server unless you have the record with the sequence# for the first session. The code currently will simply reuse the session that is already established. The nfscl_sameserver() is currently a stub that needs to be coded. This code has done a trivial file read through the DS provided by a Linux pNFS single server, but still needs a lot of work. Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c projects/nfsv4.1-client/sys/fs/nfs/nfs_commonport.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/nfsclient/nfs_clcomsubs.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_commonkrpc.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c Wed Feb 22 04:51:17 2012 (r231992) +++ projects/nfsv4.1-client/sys/fs/nfs/nfs_commonkrpc.c Wed Feb 22 04:52:38 2012 (r231993) @@ -799,7 +799,7 @@ tryagain: if (nd->nd_procnum != NFSPROC_NULL) { /* If sep == NULL, set it to the default in nmp. */ if (sep == NULL && nmp != NULL) - sep = &nmp->nm_sess; + sep = NFSMNT_MDSSESSION(nmp); /* * and now the actual NFS xdr. */ Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_commonport.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfs_commonport.c Wed Feb 22 04:51:17 2012 (r231992) +++ projects/nfsv4.1-client/sys/fs/nfs/nfs_commonport.c Wed Feb 22 04:52:38 2012 (r231993) @@ -107,6 +107,8 @@ MALLOC_DEFINE(M_NEWNFSDROLLBACK, "NFSD r MALLOC_DEFINE(M_NEWNFSLAYOUT, "NFSCL layout", "NFSv4.1 Layout"); MALLOC_DEFINE(M_NEWNFSFLAYOUT, "NFSCL flayout", "NFSv4.1 File Layout"); MALLOC_DEFINE(M_NEWNFSDEVINFO, "NFSCL devinfo", "NFSv4.1 Device Info"); +MALLOC_DEFINE(M_NEWNFSSOCKREQ, "NFSCL sockreq", "NFS Sock Req"); +MALLOC_DEFINE(M_NEWNFSCLDS, "NFSCL session", "NFSv4.1 Session"); /* * Definition of mutex locks. Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h Wed Feb 22 04:51:17 2012 (r231992) +++ projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h Wed Feb 22 04:52:38 2012 (r231993) @@ -437,7 +437,8 @@ int nfsrpc_delegreturn(struct nfscldeleg 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 nfsclsession *, uint32_t, struct ucred *, NFSPROC_T *); + struct nfssockreq *, uint32_t, struct nfsclds **, struct ucred *, + NFSPROC_T *); int nfsrpc_createsession(struct nfsmount *, struct nfsclsession *, struct ucred *, NFSPROC_T *); int nfsrpc_destroysession(struct nfsmount *, struct nfsclclient *, @@ -457,6 +458,7 @@ int nfsrpc_layoutreturn(vnode_t, int, in int nfsrpc_reclaimcomplete(struct nfsmount *, struct ucred *, NFSPROC_T *); int nfscl_doiods(vnode_t, struct uio *, int *, int *, uint32_t, struct ucred *, NFSPROC_T *); +void nfscl_freenfsclds(struct nfsclds *); /* nfs_clstate.c */ int nfscl_open(vnode_t, u_int8_t *, int, u_int32_t, int, Modified: projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h Wed Feb 22 04:51:17 2012 (r231992) +++ projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h Wed Feb 22 04:52:38 2012 (r231993) @@ -71,13 +71,17 @@ struct nfsclsession { /* * This structure holds the information used to access a Data Server (DS). + * It is malloc'd to the correct length. */ struct nfsclds { - struct mtx nfsclds_mtx; - struct nfssockreq nfsclds_sock; + LIST_ENTRY(nfsclds) nfsclds_list; struct nfsclsession nfsclds_sess; - int nfsclds_haswriteverf; + struct mtx nfsclds_mtx; + struct nfssockreq *nfsclds_sockp; + uint16_t nfsclds_haswriteverf; + uint16_t nfsclds_servownlen; uint8_t nfsclds_verf[NFSX_VERF]; + uint8_t nfsclds_serverown[0]; }; struct nfsclclient { @@ -268,14 +272,14 @@ struct nfscldevinfo { uint32_t nfsdi_refcnt; uint16_t nfsdi_stripecnt; uint16_t nfsdi_addrcnt; - struct nfsclds nfsdi_data[1]; + struct nfsclds *nfsdi_data[0]; }; /* These inline functions return values from nfsdi_data[]. */ /* * Return a pointer to the address at "pos". */ -static __inline struct nfsclds * +static __inline struct nfsclds ** nfsfldi_addr(struct nfscldevinfo *ndi, int pos) { Modified: projects/nfsv4.1-client/sys/fs/nfs/nfsport.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfsport.h Wed Feb 22 04:51:17 2012 (r231992) +++ projects/nfsv4.1-client/sys/fs/nfs/nfsport.h Wed Feb 22 04:52:38 2012 (r231993) @@ -739,6 +739,8 @@ MALLOC_DECLARE(M_NEWNFSDROLLBACK); MALLOC_DECLARE(M_NEWNFSLAYOUT); MALLOC_DECLARE(M_NEWNFSFLAYOUT); MALLOC_DECLARE(M_NEWNFSDEVINFO); +MALLOC_DECLARE(M_NEWNFSSOCKREQ); +MALLOC_DECLARE(M_NEWNFSCLDS); #define M_NFSRVCACHE M_NEWNFSRVCACHE #define M_NFSDCLIENT M_NEWNFSDCLIENT #define M_NFSDSTATE M_NEWNFSDSTATE @@ -761,6 +763,8 @@ MALLOC_DECLARE(M_NEWNFSDEVINFO); #define M_NFSLAYOUT M_NEWNFSLAYOUT #define M_NFSFLAYOUT M_NEWNFSFLAYOUT #define M_NFSDEVINFO M_NEWNFSDEVINFO +#define M_NFSSOCKREQ M_NEWNFSSOCKREQ +#define M_NFSCLDS M_NEWNFSCLDS #define NFSINT_SIGMASK(set) \ (SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) || \ Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c Wed Feb 22 04:51:17 2012 (r231992) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clcomsubs.c Wed Feb 22 04:52:38 2012 (r231993) @@ -200,7 +200,7 @@ nfscl_reqstart(struct nfsrv_descript *nd NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_SEQUENCE); if (sep == NULL) - nfsv4_setsequence(nd, &nmp->nm_sess, + nfsv4_setsequence(nd, NFSMNT_MDSSESSION(nmp), nfs_bigreply[procnum]); else nfsv4_setsequence(nd, sep, Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c Wed Feb 22 04:51:17 2012 (r231992) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c Wed Feb 22 04:52:38 2012 (r231993) @@ -87,8 +87,8 @@ static int nfsrpc_setaclrpc(vnode_t, str struct acl *, nfsv4stateid_t *, void *); static int nfsrpc_getlayout(struct nfsmount *, struct nfsfh *, int, uint32_t *, nfsv4stateid_t *, struct ucred *, NFSPROC_T *); -static int nfsrpc_fillsa(struct nfsmount *, struct nfsclds *, - struct sockaddr_storage *, NFSPROC_T *); +static int nfsrpc_fillsa(struct nfsmount *, struct sockaddr_storage *, + struct nfsclds **, NFSPROC_T *); static void nfscl_initsessionslots(struct nfsclsession *); static int nfscl_findlayoutforio(struct nfscllayout *, uint64_t, uint32_t, struct nfsclflayout **); @@ -101,6 +101,7 @@ static int nfsrpc_readds(vnode_t, struct static int nfsrpc_writeds(vnode_t, struct uio *, int *, int *, nfsv4stateid_t *, struct nfsclds *, uint64_t, int, struct nfsfh *, int, struct ucred *, NFSPROC_T *); +static struct nfsclds *nfscl_getsameserver(struct nfsmount *, struct nfsclds *); /* * nfs null call from vfs. @@ -381,8 +382,8 @@ nfsrpc_openrpc(struct nfsmount *nmp, vno *tl++ = txdr_unsigned(op->nfso_own->nfsow_seqid); *tl++ = txdr_unsigned(mode & NFSV4OPEN_ACCESSBOTH); *tl++ = txdr_unsigned((mode >> NFSLCK_SHIFT) & NFSV4OPEN_DENYBOTH); - *tl++ = nmp->nm_sess.nfsess_clientid.lval[0]; - *tl = nmp->nm_sess.nfsess_clientid.lval[1]; + *tl++ = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[0]; + *tl = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[1]; (void) nfsm_strtom(nd, op->nfso_own->nfsow_owner, NFSV4CL_LOCKNAMELEN); NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(NFSV4OPEN_NOCREATE); @@ -806,18 +807,27 @@ nfsrpc_setclient(struct nfsmount *nmp, s nfsquad_t confirm; u_int32_t lease; static u_int32_t rev = 0; + struct nfsclds *dsp; if (nfsboottime.tv_sec == 0) NFSSETBOOTTIME(nfsboottime); clp->nfsc_rev = rev++; if (NFSHASNFSV4N(nmp)) { - error = nfsrpc_exchangeid(nmp, clp, &nmp->nm_sess, - NFSV4EXCH_USEPNFSMDS | NFSV4EXCH_USENONPNFS, cred, p); + error = nfsrpc_exchangeid(nmp, clp, &nmp->nm_sockreq, + NFSV4EXCH_USEPNFSMDS | NFSV4EXCH_USENONPNFS, &dsp, cred, p); if (error) printf("exch=%d\n",error); if (error == 0) { - nfscl_initsessionslots(&nmp->nm_sess); - error = nfsrpc_createsession(nmp, &nmp->nm_sess, cred, - p); + error = nfsrpc_createsession(nmp, &dsp->nfsclds_sess, + cred, p); + if (error == 0) { + KASSERT(LIST_FIRST(&nmp->nm_sess) == NULL, + ("nfscl session non-NULL")); + NFSLOCKMNT(nmp); + LIST_INSERT_HEAD(&nmp->nm_sess, dsp, + nfsclds_list); + NFSUNLOCKMNT(nmp); + } else + nfscl_freenfsclds(dsp); if (error) printf("aft crs=%d\n",error); } if (error == 0 && reclaim == 0) { @@ -888,8 +898,8 @@ if (error) printf("aft reclcom=%d\n",err return (error); if (nd->nd_repstat == 0) { NFSM_DISSECT(tl, u_int32_t *, 4 * NFSX_UNSIGNED); - nmp->nm_sess.nfsess_clientid.lval[0] = *tl++; - nmp->nm_sess.nfsess_clientid.lval[1] = *tl++; + NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[0] = *tl++; + NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[1] = *tl++; confirm.lval[0] = *tl++; confirm.lval[1] = *tl; mbuf_freem(nd->nd_mrep); @@ -901,8 +911,8 @@ if (error) printf("aft reclcom=%d\n",err nfscl_reqstart(nd, NFSPROC_SETCLIENTIDCFRM, nmp, NULL, 0, NULL, NULL); NFSM_BUILD(tl, u_int32_t *, 4 * NFSX_UNSIGNED); - *tl++ = nmp->nm_sess.nfsess_clientid.lval[0]; - *tl++ = nmp->nm_sess.nfsess_clientid.lval[1]; + *tl++ = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[0]; + *tl++ = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[1]; *tl++ = confirm.lval[0]; *tl = confirm.lval[1]; nd->nd_flag |= ND_USEGSSNAME; @@ -1925,8 +1935,8 @@ nfsrpc_createv4(vnode_t dvp, char *name, *tl++ = txdr_unsigned(NFSV4OPEN_ACCESSWRITE | NFSV4OPEN_ACCESSREAD); *tl++ = txdr_unsigned(NFSV4OPEN_DENYNONE); - *tl++ = nmp->nm_sess.nfsess_clientid.lval[0]; - *tl = nmp->nm_sess.nfsess_clientid.lval[1]; + *tl++ = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[0]; + *tl = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[1]; (void) nfsm_strtom(nd, owp->nfsow_owner, NFSV4CL_LOCKNAMELEN); NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(NFSV4OPEN_CREATE); @@ -3718,8 +3728,8 @@ nfsrpc_lockt(struct nfsrv_descript *nd, tl += 2; txdr_hyper(len, tl); tl += 2; - *tl++ = nmp->nm_sess.nfsess_clientid.lval[0]; - *tl = nmp->nm_sess.nfsess_clientid.lval[1]; + *tl++ = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[0]; + *tl = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[1]; nfscl_filllockowner(id, own, flags); np = VTONFS(vp); NFSBCOPY(np->n_fhp->nfh_fh, &own[NFSV4CL_LOCKNAMELEN], @@ -3849,8 +3859,8 @@ nfsrpc_lock(struct nfsrv_descript *nd, s *tl++ = lp->nfsl_open->nfso_stateid.other[1]; *tl++ = lp->nfsl_open->nfso_stateid.other[2]; *tl++ = txdr_unsigned(lp->nfsl_seqid); - *tl++ = nmp->nm_sess.nfsess_clientid.lval[0]; - *tl = nmp->nm_sess.nfsess_clientid.lval[1]; + *tl++ = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[0]; + *tl = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[1]; NFSBCOPY(lp->nfsl_owner, own, NFSV4CL_LOCKNAMELEN); NFSBCOPY(nfhp, &own[NFSV4CL_LOCKNAMELEN], fhlen); (void)nfsm_strtom(nd, own, NFSV4CL_LOCKNAMELEN + fhlen); @@ -4095,8 +4105,8 @@ nfsrpc_renew(struct nfsclclient *clp, st if (!NFSHASNFSV4N(nmp)) { /* NFSv4.1 just uses a Sequence Op and not a Renew. */ NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = nmp->nm_sess.nfsess_clientid.lval[0]; - *tl = nmp->nm_sess.nfsess_clientid.lval[1]; + *tl++ = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[0]; + *tl = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[1]; } nd->nd_flag |= ND_USEGSSNAME; error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred, @@ -4129,8 +4139,8 @@ nfsrpc_rellockown(struct nfsmount *nmp, nfscl_reqstart(nd, NFSPROC_RELEASELCKOWN, nmp, NULL, 0, NULL, NULL); NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = nmp->nm_sess.nfsess_clientid.lval[0]; - *tl = nmp->nm_sess.nfsess_clientid.lval[1]; + *tl++ = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[0]; + *tl = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[1]; NFSBCOPY(lp->nfsl_owner, own, NFSV4CL_LOCKNAMELEN); NFSBCOPY(fh, &own[NFSV4CL_LOCKNAMELEN], fhlen); (void)nfsm_strtom(nd, own, NFSV4CL_LOCKNAMELEN + fhlen); @@ -4323,22 +4333,24 @@ nfsrpc_setaclrpc(vnode_t vp, struct ucre */ int nfsrpc_exchangeid(struct nfsmount *nmp, struct nfsclclient *clp, - struct nfsclsession *sep, uint32_t exchflags, struct ucred *cred, - NFSPROC_T *p) + struct nfssockreq *nrp, uint32_t exchflags, struct nfsclds **dspp, + struct ucred *cred, NFSPROC_T *p) { uint32_t *tl, v41flags; struct nfsrv_descript nfsd; struct nfsrv_descript *nd = &nfsd; + struct nfsclds *dsp; struct timespec verstime; - int error; + int error, len; + *dspp = NULL; nfscl_reqstart(nd, NFSPROC_EXCHANGEID, nmp, NULL, 0, NULL, NULL); NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(nfsboottime.tv_sec); /* Client owner */ *tl = txdr_unsigned(clp->nfsc_rev); (void) nfsm_strtom(nd, clp->nfsc_id, clp->nfsc_idlen); - NFSM_BUILD(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + NFSM_BUILD(tl, uint32_t *, 3 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(exchflags); *tl++ = txdr_unsigned(NFSV4EXCH_SP4NONE); @@ -4346,21 +4358,31 @@ nfsrpc_exchangeid(struct nfsmount *nmp, *tl = txdr_unsigned(1); (void) nfsm_strtom(nd, "freebsd.org", strlen("freebsd.org")); (void) nfsm_strtom(nd, version, strlen(version)); - NFSM_BUILD(tl, u_int32_t *, NFSX_V4TIME); + NFSM_BUILD(tl, uint32_t *, NFSX_V4TIME); verstime.tv_sec = 1293840000; /* Jan 1, 2011 */ verstime.tv_nsec = 0; txdr_nfsv4time(&verstime, tl); nd->nd_flag |= ND_USEGSSNAME; - error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred, + error = newnfs_request(nd, nmp, NULL, nrp, NULL, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL); printf("exch err=%d reps=%d\n",error,nd->nd_repstat); if (error != 0) return (error); if (nd->nd_repstat == 0) { - NFSM_DISSECT(tl, u_int32_t *, 4 * NFSX_UNSIGNED); - sep->nfsess_clientid.lval[0] = *tl++; - sep->nfsess_clientid.lval[1] = *tl++; - sep->nfsess_sequenceid = fxdr_unsigned(uint32_t, *tl++); + NFSM_DISSECT(tl, uint32_t *, 6 * NFSX_UNSIGNED + NFSX_HYPER); + len = fxdr_unsigned(int, *(tl + 7)); +printf("servlen=%d\n", len); + if (len < 1 || len > NFSV4_OPAQUELIMIT) { + error = NFSERR_BADXDR; + goto nfsmout; + } + dsp = malloc(sizeof(struct nfsclds) + len, M_NFSCLDS, + M_WAITOK | M_ZERO); + dsp->nfsclds_servownlen = len; + dsp->nfsclds_sess.nfsess_clientid.lval[0] = *tl++; + dsp->nfsclds_sess.nfsess_clientid.lval[1] = *tl++; + dsp->nfsclds_sess.nfsess_sequenceid = + fxdr_unsigned(uint32_t, *tl++); v41flags = fxdr_unsigned(uint32_t, *tl); printf("v41fl=0x%x\n", v41flags); if ((v41flags & NFSV4EXCH_USEPNFSMDS) != 0) { @@ -4368,6 +4390,15 @@ printf("v41fl=0x%x\n", v41flags); nmp->nm_state |= NFSSTA_PNFS; NFSUNLOCKMNT(nmp); } + nd->nd_repstat = nfsrv_mtostr(nd, dsp->nfsclds_serverown, len); + if (nd->nd_repstat == 0) { + mtx_init(&dsp->nfsclds_mtx, "nfsds", NULL, MTX_DEF); + mtx_init(&dsp->nfsclds_sess.nfsess_mtx, "nfssession", + NULL, MTX_DEF); + nfscl_initsessionslots(&dsp->nfsclds_sess); + *dspp = dsp; + } else + free(dsp, M_NFSCLDS); } error = nd->nd_repstat; nfsmout: @@ -4483,7 +4514,7 @@ nfsrpc_destroysession(struct nfsmount *n nfscl_reqstart(nd, NFSPROC_DESTROYSESSION, nmp, NULL, 0, NULL, NULL); NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID); - bcopy(nmp->nm_sess.nfsess_sessionid, tl, NFSX_V4SESSIONID); + bcopy(NFSMNT_MDSSESSION(nmp)->nfsess_sessionid, tl, NFSX_V4SESSIONID); nd->nd_flag |= ND_USEGSSNAME; error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL); @@ -4508,8 +4539,8 @@ nfsrpc_destroyclient(struct nfsmount *nm nfscl_reqstart(nd, NFSPROC_DESTROYCLIENT, nmp, NULL, 0, NULL, NULL); NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); - *tl++ = nmp->nm_sess.nfsess_clientid.lval[0]; - *tl = nmp->nm_sess.nfsess_clientid.lval[1]; + *tl++ = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[0]; + *tl = NFSMNT_MDSSESSION(nmp)->nfsess_clientid.lval[1]; nd->nd_flag |= ND_USEGSSNAME; error = newnfs_request(nd, nmp, NULL, &nmp->nm_sockreq, NULL, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL, NULL); @@ -4679,7 +4710,7 @@ nfsrpc_getdeviceinfo(struct nfsmount *nm struct nfsrv_descript nfsd; struct nfsrv_descript *nd = &nfsd; struct sockaddr_storage ss; - struct nfsclds *sa; + struct nfsclds *dsp = NULL, **dspp; struct nfscldevinfo *ndi; int addrcnt, bitcnt, error, i, isudp, j, pos, safilled, stripecnt; uint8_t stripeindex; @@ -4708,6 +4739,7 @@ nfsrpc_getdeviceinfo(struct nfsmount *nm if (layouttype != fxdr_unsigned(int, *tl++)) printf("EEK! devinfo layout type not same!\n"); stripecnt = fxdr_unsigned(int, *++tl); +printf("stripecnt=%d\n", stripecnt); if (stripecnt < 1 || stripecnt > 4096) { printf("NFS devinfo stripecnt %d: out of range\n", stripecnt); @@ -4716,6 +4748,7 @@ nfsrpc_getdeviceinfo(struct nfsmount *nm } NFSM_DISSECT(tl, uint32_t *, (stripecnt + 1) * NFSX_UNSIGNED); addrcnt = fxdr_unsigned(int, *(tl + stripecnt)); +printf("addrcnt=%d\n", addrcnt); if (addrcnt < 1 || addrcnt > 128) { printf("NFS devinfo addrcnt %d: out of range\n", addrcnt); @@ -4727,9 +4760,11 @@ nfsrpc_getdeviceinfo(struct nfsmount *nm * Now we know how many stripe indices and addresses, so * we can allocate the structure the correct size. */ - i = stripecnt / sizeof(struct nfsclds) + 1; - ndi = malloc(sizeof(*ndi) + (addrcnt + i - 1) * - sizeof(struct nfsclds), M_NFSDEVINFO, M_WAITOK | M_ZERO); + i = (stripecnt * sizeof(uint8_t)) / sizeof(struct nfsclds *) + + 1; +printf("i=%d\n", i); + ndi = malloc(sizeof(*ndi) + (addrcnt + i) * + sizeof(struct nfsclds *), M_NFSDEVINFO, M_WAITOK | M_ZERO); NFSBCOPY(deviceid, ndi->nfsdi_deviceid, NFSX_V4DEVICEID); ndi->nfsdi_refcnt = 0; ndi->nfsdi_stripecnt = stripecnt; @@ -4737,6 +4772,7 @@ nfsrpc_getdeviceinfo(struct nfsmount *nm /* Fill in the stripe indices. */ for (i = 0; i < stripecnt; i++) { stripeindex = fxdr_unsigned(uint8_t, *tl++); +printf("stripeind=%d\n", stripeindex); if (stripeindex >= addrcnt) { printf("NFS devinfo stripeindex %d: too big\n", (int)stripeindex); @@ -4756,9 +4792,10 @@ nfsrpc_getdeviceinfo(struct nfsmount *nm error = NFSERR_BADXDR; goto nfsmout; } - sa = nfsfldi_addr(ndi, i); + dspp = nfsfldi_addr(ndi, i); pos = arc4random() % cnt; /* Choose one. */ safilled = 0; +printf("dspp=%p pos=%d\n", dspp, pos); for (j = 0; j < cnt; j++) { error = nfsv4_getipaddr(nd, &ss, &isudp); if (error != 0 && error != EPERM) { @@ -4782,9 +4819,11 @@ nfsrpc_getdeviceinfo(struct nfsmount *nm nmp->nm_nam->sa_family)) || (safilled == 1 && ss.ss_family == nmp->nm_nam->sa_family)) { - error = nfsrpc_fillsa(nmp, sa, - &ss, p); + error = nfsrpc_fillsa(nmp, &ss, + &dsp, p); if (error == 0) { + *dspp = dsp; +printf("safill dsp=%p\n", dsp); if (ss.ss_family == nmp->nm_nam->sa_family) safilled = 2; @@ -5002,16 +5041,19 @@ nfsrpc_getlayout(struct nfsmount *nmp, s } /* - * Fill in nfsclds, doing the TCP connect plus exchangeid and create session. - * The nfsclds structure pointed to by dsp is all zero'd out. + * Do a TCP connection plus exchange id and create session. + * If successful, a "struct nfsclds" is linked into the list for the + * mount point and a pointer to it is returned. */ static int -nfsrpc_fillsa(struct nfsmount *nmp, struct nfsclds *dsp, - struct sockaddr_storage *ssp, NFSPROC_T *p) +nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_storage *ssp, + struct nfsclds **dspp, NFSPROC_T *p) { struct sockaddr_in *sad, *ssd; struct sockaddr_in6 *sad6, *ssd6; struct nfsclclient *clp; + struct nfssockreq *nrp; + struct nfsclds *dsp, *tdsp; int error; KASSERT(nmp->nm_sockreq.nr_cred != NULL, @@ -5021,6 +5063,7 @@ nfsrpc_fillsa(struct nfsmount *nmp, stru NFSUNLOCKCLSTATE(); if (clp == NULL) return (EPERM); + nrp = malloc(sizeof(*nrp), M_NFSSOCKREQ, M_WAITOK | M_ZERO); if (ssp->ss_family == AF_INET) { ssd = (struct sockaddr_in *)ssp; sad = malloc(sizeof(*sad), M_SONAME, M_WAITOK | M_ZERO); @@ -5028,7 +5071,7 @@ nfsrpc_fillsa(struct nfsmount *nmp, stru sad->sin_family = AF_INET; sad->sin_port = ssd->sin_port; sad->sin_addr.s_addr = ssd->sin_addr.s_addr; - dsp->nfsclds_sock.nr_nam = (struct sockaddr *)sad; + nrp->nr_nam = (struct sockaddr *)sad; } else if (ssp->ss_family == AF_INET6) { ssd6 = (struct sockaddr_in6 *)ssp; sad6 = malloc(sizeof(*sad6), M_SONAME, M_WAITOK | M_ZERO); @@ -5037,15 +5080,15 @@ nfsrpc_fillsa(struct nfsmount *nmp, stru sad6->sin6_port = ssd6->sin6_port; NFSBCOPY(&ssd6->sin6_addr, &sad6->sin6_addr, sizeof(struct in6_addr)); - dsp->nfsclds_sock.nr_nam = (struct sockaddr *)sad6; - } else + nrp->nr_nam = (struct sockaddr *)sad6; + } else { + free(nrp, M_NFSSOCKREQ); return (EPERM); - mtx_init(&dsp->nfsclds_mtx, "nfsds", NULL, MTX_DEF); - dsp->nfsclds_sock.nr_sotype = SOCK_STREAM; - mtx_init(&dsp->nfsclds_sock.nr_mtx, "nfssock", NULL, MTX_DEF); - dsp->nfsclds_sock.nr_prog = NFS_PROG; - dsp->nfsclds_sock.nr_vers = NFS_VER4; - mtx_init(&dsp->nfsclds_sess.nfsess_mtx, "nfssession", NULL, MTX_DEF); + } + nrp->nr_sotype = SOCK_STREAM; + mtx_init(&nrp->nr_mtx, "nfssock", NULL, MTX_DEF); + nrp->nr_prog = NFS_PROG; + nrp->nr_vers = NFS_VER4; /* * Use the credentials that were used for the mount, which are @@ -5054,26 +5097,48 @@ nfsrpc_fillsa(struct nfsmount *nmp, stru * necessary, since nm_sockreq.nr_cred won't be crfree()'d until * unmount, but I did it anyhow. */ - dsp->nfsclds_sock.nr_cred = crhold(nmp->nm_sockreq.nr_cred); - error = newnfs_connect(nmp, &dsp->nfsclds_sock, NULL, p, 0); + nrp->nr_cred = crhold(nmp->nm_sockreq.nr_cred); + error = newnfs_connect(nmp, nrp, NULL, p, 0); /* Now, do the exchangeid and create session. */ if (error == 0) - error = nfsrpc_exchangeid(nmp, clp, &dsp->nfsclds_sess, - NFSV4EXCH_USEPNFSDS, dsp->nfsclds_sock.nr_cred, p); + error = nfsrpc_exchangeid(nmp, clp, nrp, NFSV4EXCH_USEPNFSDS, + &dsp, nrp->nr_cred, p); if (error == 0) { - nfscl_initsessionslots(&dsp->nfsclds_sess); + dsp->nfsclds_sockp = nrp; + tdsp = nfscl_getsameserver(nmp, dsp); + if (tdsp != NULL) { + /* + * If there is already a session for this server, + * use it. + */ + (void)newnfs_disconnect(nrp); + nfscl_freenfsclds(dsp); + *dspp = tdsp; + return (0); + } error = nfsrpc_createsession(nmp, &dsp->nfsclds_sess, - dsp->nfsclds_sock.nr_cred, p); - } - if (error != 0) { - NFSFREECRED(dsp->nfsclds_sock.nr_cred); - NFSFREEMUTEX(&dsp->nfsclds_mtx); - NFSFREEMUTEX(&dsp->nfsclds_sock.nr_mtx); - NFSFREEMUTEX(&dsp->nfsclds_sess.nfsess_mtx); - free(dsp->nfsclds_sock.nr_nam, M_SONAME); - NFSBZERO(dsp, sizeof(*dsp)); + nrp->nr_cred, p); + } else { + NFSFREECRED(nrp->nr_cred); + NFSFREEMUTEX(&nrp->nr_mtx); + free(nrp->nr_nam, M_SONAME); + free(nrp, M_NFSSOCKREQ); } + if (error == 0) { + /* + * The first element should be the one for the MDS. + */ + NFSLOCKMNT(nmp); + tdsp = LIST_FIRST(&nmp->nm_sess); + if (tdsp == NULL) + LIST_INSERT_HEAD(&nmp->nm_sess, dsp, nfsclds_list); + else + LIST_INSERT_AFTER(tdsp, dsp, nfsclds_list); + NFSUNLOCKMNT(nmp); + *dspp = dsp; + } else if (dsp != NULL) + nfscl_freenfsclds(dsp); return (error); } @@ -5248,7 +5313,7 @@ nfscl_doflayoutio(vnode_t vp, struct uio int commit_thru_mds, error = 0, stripe_index, stripe_pos; struct nfsnode *np; struct nfsfh *fhp; - struct nfsclds *dsp; + struct nfsclds **dspp; np = VTONFS(vp); rel_off = off - flp->nfsfl_patoff; @@ -5260,7 +5325,7 @@ nfscl_doflayoutio(vnode_t vp, struct uio /* Loop around, doing I/O for each stripe unit. */ while (len > 0 && error == 0) { stripe_index = nfsfldi_stripeindex(dp, stripe_pos); - dsp = nfsfldi_addr(dp, stripe_index); + dspp = nfsfldi_addr(dp, stripe_index); if (len > transfer) xfer = transfer; else @@ -5290,11 +5355,11 @@ nfscl_doflayoutio(vnode_t vp, struct uio else commit_thru_mds = 0; if (rwflag == FREAD) - error = nfsrpc_readds(vp, uiop, stateidp, eofp, dsp, + error = nfsrpc_readds(vp, uiop, stateidp, eofp, *dspp, io_off, xfer, fhp, cred, p); else error = nfsrpc_writeds(vp, uiop, iomode, must_commit, - stateidp, dsp, io_off, xfer, fhp, commit_thru_mds, + stateidp, *dspp, io_off, xfer, fhp, commit_thru_mds, cred, p); if (error == 0) { transfer = stripe_unit_size; @@ -5319,6 +5384,7 @@ nfsrpc_readds(vnode_t vp, struct uio *ui struct nfsrv_descript nfsd; struct nfsmount *nmp = VFSTONFS(vnode_mount(vp)); struct nfsrv_descript *nd = &nfsd; + struct nfssockreq *nrp; nd->nd_mrep = NULL; nfscl_reqstart(nd, NFSPROC_READ, nmp, fhp->nfh_fh, fhp->nfh_len, @@ -5327,7 +5393,11 @@ nfsrpc_readds(vnode_t vp, struct uio *ui NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED * 3); txdr_hyper(io_off, tl); *(tl + 2) = txdr_unsigned(len); - error = newnfs_request(nd, nmp, NULL, &dsp->nfsclds_sock, vp, p, cred, + nrp = dsp->nfsclds_sockp; + if (nrp == NULL) + /* If NULL, use the MDS socket. */ + nrp = &nmp->nm_sockreq; + error = newnfs_request(nd, nmp, NULL, nrp, vp, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL, &dsp->nfsclds_sess); if (error != 0) return (error); @@ -5359,6 +5429,7 @@ nfsrpc_writeds(vnode_t vp, struct uio *u int32_t backup; struct nfsrv_descript nfsd; struct nfsrv_descript *nd = &nfsd; + struct nfssockreq *nrp; KASSERT(uiop->uio_iovcnt == 1, ("nfs: writerpc iovcnt > 1")); nd->nd_mrep = NULL; @@ -5371,7 +5442,11 @@ nfsrpc_writeds(vnode_t vp, struct uio *u *tl++ = txdr_unsigned(*iomode); *tl = txdr_unsigned(len); nfsm_uiombuf(nd, uiop, len); - error = newnfs_request(nd, nmp, NULL, &dsp->nfsclds_sock, vp, p, cred, + nrp = dsp->nfsclds_sockp; + if (nrp == NULL) + /* If NULL, use the MDS socket. */ + nrp = &nmp->nm_sockreq; + error = newnfs_request(nd, nmp, NULL, nrp, vp, p, cred, NFS_PROG, NFS_VER4, NULL, 1, NULL, &dsp->nfsclds_sess); if (error != 0) return (error); @@ -5442,3 +5517,40 @@ nfsmout: return (error); } +/* + * Free up the nfsclds structure. + */ +void +nfscl_freenfsclds(struct nfsclds *dsp) +{ + int i; + + if (dsp == NULL) + return; + if (dsp->nfsclds_sockp != NULL) { + NFSFREECRED(dsp->nfsclds_sockp->nr_cred); + NFSFREEMUTEX(&dsp->nfsclds_sockp->nr_mtx); + free(dsp->nfsclds_sockp->nr_nam, M_SONAME); + free(dsp->nfsclds_sockp, M_NFSSOCKREQ); + } + NFSFREEMUTEX(&dsp->nfsclds_mtx); + NFSFREEMUTEX(&dsp->nfsclds_sess.nfsess_mtx); + for (i = 0; i < NFSV4_CBSLOTS; i++) { + if (dsp->nfsclds_sess.nfsess_cbslots[i].nfssl_reply != NULL) + m_freem( + dsp->nfsclds_sess.nfsess_cbslots[i].nfssl_reply); + } + free(dsp, M_NFSCLDS); +} + +static struct nfsclds * +nfscl_getsameserver(struct nfsmount *nmp, struct nfsclds *newdsp) +{ + + /* + * Search the list of nfsclds structures for one with the same + * server. + */ + return (LIST_FIRST(&nmp->nm_sess)); +} + Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c Wed Feb 22 04:51:17 2012 (r231992) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clstate.c Wed Feb 22 04:52:38 2012 (r231993) @@ -3216,8 +3216,10 @@ printf("cbrecall\n"); if (error == 0) error = nfsv4_seqsession(seqid, slotid, highslot, - clp->nfsc_nmp->nm_sess.nfsess_cbslots, &rep, - clp->nfsc_nmp->nm_sess.nfsess_backslots); + NFSMNT_MDSSESSION(clp->nfsc_nmp)-> + nfsess_cbslots, &rep, + NFSMNT_MDSSESSION(clp->nfsc_nmp)-> + nfsess_backslots); NFSUNLOCKCLSTATE(); if (error == 0) { gotseq_ok = 1; @@ -3285,7 +3287,8 @@ out: clp = nfscl_getclntsess(sessionid); if (clp != NULL) { nfsv4_seqsess_cacherep(slotid, - clp->nfsc_nmp->nm_sess.nfsess_cbslots, rep); + NFSMNT_MDSSESSION(clp->nfsc_nmp)->nfsess_cbslots, + rep); NFSUNLOCKCLSTATE(); } else { NFSUNLOCKCLSTATE(); @@ -3347,8 +3350,8 @@ nfscl_getmnt(int minorvers, uint8_t *ses if (minorvers == NFSV4_MINORVERSION) { if (clp->nfsc_cbident == cbident) break; - } else if (!NFSBCMP(clp->nfsc_nmp->nm_sess.nfsess_sessionid, - sessionid, NFSX_V4SESSIONID)) + } else if (!NFSBCMP(NFSMNT_MDSSESSION(clp->nfsc_nmp)-> + nfsess_sessionid, sessionid, NFSX_V4SESSIONID)) break; } if (clp == NULL) { @@ -3389,8 +3392,8 @@ nfscl_getclntsess(uint8_t *sessionid) struct nfsclclient *clp; LIST_FOREACH(clp, &nfsclhead, nfsc_list) - if (!NFSBCMP(clp->nfsc_nmp->nm_sess.nfsess_sessionid, sessionid, - NFSX_V4SESSIONID)) + if (!NFSBCMP(NFSMNT_MDSSESSION(clp->nfsc_nmp)->nfsess_sessionid, + sessionid, NFSX_V4SESSIONID)) break; return (clp); } @@ -4659,20 +4662,7 @@ nfscl_freeflayout(struct nfsclflayout *f APPLESTATIC void nfscl_freedevinfo(struct nfscldevinfo *dip) { - int i; - struct nfsclds *dsp; - for (i = 0; i < dip->nfsdi_addrcnt; i++) { - dsp = nfsfldi_addr(dip, i); - if (dsp->nfsclds_sock.nr_nam != NULL) { - /* All are set or none are. */ - NFSFREECRED(dsp->nfsclds_sock.nr_cred); - NFSFREEMUTEX(&dsp->nfsclds_mtx); - NFSFREEMUTEX(&dsp->nfsclds_sock.nr_mtx); - NFSFREEMUTEX(&dsp->nfsclds_sess.nfsess_mtx); - free(dsp->nfsclds_sock.nr_nam, M_SONAME); - } - } free(dip, M_NFSDEVINFO); } Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c Wed Feb 22 04:51:17 2012 (r231992) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c Wed Feb 22 04:52:38 2012 (r231993) @@ -1193,9 +1193,10 @@ mountnfs(struct nfs_args *argp, struct m { struct nfsmount *nmp; struct nfsnode *np; - int error, i, trycnt, ret; + int error, trycnt, ret; struct nfsvattr nfsva; struct nfsclclient *clp; + struct nfsclds *dsp, *tdsp; uint32_t lease; static u_int64_t clval = 0; @@ -1254,7 +1255,6 @@ printf("in mnt\n"); } nmp->nm_sockreq.nr_cred = crhold(cred); mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF); - mtx_init(&nmp->nm_sess.nfsess_mtx, "nfssession", NULL, MTX_DEF); mp->mnt_data = nmp; nmp->nm_getinfo = nfs_getnlminfo; nmp->nm_vinvalbuf = ncl_vinvalbuf; @@ -1445,18 +1445,15 @@ bad: newnfs_disconnect(&nmp->nm_sockreq); crfree(nmp->nm_sockreq.nr_cred); mtx_destroy(&nmp->nm_sockreq.nr_mtx); - mtx_destroy(&nmp->nm_sess.nfsess_mtx); mtx_destroy(&nmp->nm_mtx); if (nmp->nm_clp != NULL) { NFSLOCKCLSTATE(); LIST_REMOVE(nmp->nm_clp, nfsc_list); NFSUNLOCKCLSTATE(); free(nmp->nm_clp, M_NFSCLCLIENT); - for (i = 0; i < NFSV4_CBSLOTS; i++) - if (nmp->nm_sess.nfsess_cbslots[i].nfssl_reply != NULL) - m_freem( - nmp->nm_sess.nfsess_cbslots[i].nfssl_reply); } + LIST_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) + nfscl_freenfsclds(dsp); FREE(nmp, M_NEWNFSMNT); FREE(nam, M_SONAME); return (error); @@ -1470,7 +1467,8 @@ nfs_unmount(struct mount *mp, int mntfla { struct thread *td; struct nfsmount *nmp; - int error, flags = 0, i, trycnt = 0; + int error, flags = 0, trycnt = 0; + struct nfsclds *dsp, *tdsp; td = curthread; @@ -1511,10 +1509,8 @@ nfs_unmount(struct mount *mp, int mntfla mtx_destroy(&nmp->nm_sockreq.nr_mtx); mtx_destroy(&nmp->nm_mtx); - mtx_destroy(&nmp->nm_sess.nfsess_mtx); - for (i = 0; i < NFSV4_CBSLOTS; i++) - if (nmp->nm_sess.nfsess_cbslots[i].nfssl_reply != NULL) - m_freem(nmp->nm_sess.nfsess_cbslots[i].nfssl_reply); + LIST_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) + nfscl_freenfsclds(dsp); FREE(nmp, M_NEWNFSMNT); out: return (error); Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h Wed Feb 22 04:51:17 2012 (r231992) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h Wed Feb 22 04:52:38 2012 (r231993) @@ -70,7 +70,7 @@ struct nfsmount { int nm_negnametimeo; /* timeout for -ve entries (sec) */ /* Newnfs additions */ - struct nfsclsession nm_sess; /* Session for NFSv4.1 mount. */ + LIST_HEAD(, nfsclds) nm_sess; /* Session(s) for NFSv4.1. */ struct nfsclclient *nm_clp; uid_t nm_uid; /* Uid for SetClientID etc. */ u_int64_t nm_clval; /* identifies which clientid */ @@ -109,6 +109,12 @@ struct nfsmount { */ #define VFSTONFS(mp) ((struct nfsmount *)((mp)->mnt_data)) +/* + * Get a pointer to the MDS session, which is always the first element + * in the list. + */ +#define NFSMNT_MDSSESSION(m) (&(LIST_FIRST(&((m)->nm_sess))->nfsclds_sess)) + #ifndef NFS_DEFAULT_NAMETIMEO #define NFS_DEFAULT_NAMETIMEO 60 #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202220452.q1M4qd6W035189>