From owner-svn-src-projects@FreeBSD.ORG Thu Feb 23 03:16:10 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 206FF1065674; Thu, 23 Feb 2012 03:16:10 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0E62A8FC1B; Thu, 23 Feb 2012 03:16:10 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q1N3G9xG081132; Thu, 23 Feb 2012 03:16:09 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q1N3G9v6081126; Thu, 23 Feb 2012 03:16:09 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <201202230316.q1N3G9v6081126@svn.freebsd.org> From: Rick Macklem Date: Thu, 23 Feb 2012 03:16:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r232017 - in projects/nfsv4.1-client/sys/fs: nfs nfsclient X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Feb 2012 03:16:10 -0000 Author: rmacklem Date: Thu Feb 23 03:16:09 2012 New Revision: 232017 URL: http://svn.freebsd.org/changeset/base/232017 Log: Implement the nfscl_getsameserver() function that searches the list of nfsclds structures for ones that are for the same server as the new one. If it finds a match that supports Data Server (DS), just return that one to use. If it finds a match that doesn't support DS, then return that one, so that the nfsess_sequenceid field can be use to sequence a new session. The list of nfsclds needed to be changed to a tailq so that the list could be maintained in temporal order (although the first one should be the only one that is for a MDS and, therefore, might not support DS). Flags were added to struct nfsclds to indicate MDS and/or DS support. Modified: 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/nfsclient/nfs_clrpcops.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_var.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h Thu Feb 23 01:22:40 2012 (r232016) +++ projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h Thu Feb 23 03:16:09 2012 (r232017) @@ -440,7 +440,7 @@ int nfsrpc_exchangeid(struct nfsmount *, struct nfssockreq *, uint32_t, struct nfsclds **, struct ucred *, NFSPROC_T *); int nfsrpc_createsession(struct nfsmount *, struct nfsclsession *, - struct ucred *, NFSPROC_T *); + uint32_t, struct ucred *, NFSPROC_T *); int nfsrpc_destroysession(struct nfsmount *, struct nfsclclient *, struct ucred *, NFSPROC_T *); int nfsrpc_destroyclient(struct nfsmount *, struct nfsclclient *, Modified: projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h Thu Feb 23 01:22:40 2012 (r232016) +++ projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h Thu Feb 23 03:16:09 2012 (r232017) @@ -70,20 +70,28 @@ struct nfsclsession { }; /* - * This structure holds the information used to access a Data Server (DS). + * This structure holds the session, clientid and related information + * needed for an NFSv4.1 Meta Data Server (MDS) or Data Server (DS). * It is malloc'd to the correct length. */ struct nfsclds { - LIST_ENTRY(nfsclds) nfsclds_list; + TAILQ_ENTRY(nfsclds) nfsclds_list; struct nfsclsession nfsclds_sess; struct mtx nfsclds_mtx; struct nfssockreq *nfsclds_sockp; - uint16_t nfsclds_haswriteverf; + uint16_t nfsclds_flags; uint16_t nfsclds_servownlen; uint8_t nfsclds_verf[NFSX_VERF]; uint8_t nfsclds_serverown[0]; }; +/* + * Flags for nfsclds_flags. + */ +#define NFSCLDS_HASWRITEVERF 0x0001 +#define NFSCLDS_MDS 0x0002 +#define NFSCLDS_DS 0x0004 + struct nfsclclient { LIST_ENTRY(nfsclclient) nfsc_list; struct nfsclownerhead nfsc_owner; Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c Thu Feb 23 01:22:40 2012 (r232016) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c Thu Feb 23 03:16:09 2012 (r232017) @@ -66,6 +66,19 @@ int nfstest_openallsetattr = 0; #define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1)) +/* + * nfscl_getsameserver() can return one of three values: + * NFSDSP_USETHISSESSION - Use this session for the DS. + * NFSDSP_SEQTHISSESSION - Use the nfsclds_sequence field of this dsp for new + * session. + * NFSDSP_NOTFOUND - No matching server was found. + */ +enum nfsclds_state { + NFSDSP_USETHISSESSION = 0, + NFSDSP_SEQTHISSESSION = 1, + NFSDSP_NOTFOUND = 2, +}; + static int nfsrpc_setattrrpc(vnode_t , struct vattr *, nfsv4stateid_t *, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *, void *); static int nfsrpc_readrpc(vnode_t , struct uio *, struct ucred *, @@ -101,7 +114,8 @@ 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 *); +static enum nfsclds_state nfscl_getsameserver(struct nfsmount *, + struct nfsclds *, struct nfsclds **); /* * nfs null call from vfs. @@ -818,12 +832,12 @@ nfsrpc_setclient(struct nfsmount *nmp, s if (error) printf("exch=%d\n",error); if (error == 0) { error = nfsrpc_createsession(nmp, &dsp->nfsclds_sess, - cred, p); + dsp->nfsclds_sess.nfsess_sequenceid, cred, p); if (error == 0) { - KASSERT(LIST_FIRST(&nmp->nm_sess) == NULL, + KASSERT(TAILQ_FIRST(&nmp->nm_sess) == NULL, ("nfscl session non-NULL")); NFSLOCKMNT(nmp); - LIST_INSERT_HEAD(&nmp->nm_sess, dsp, + TAILQ_INSERT_HEAD(&nmp->nm_sess, dsp, nfsclds_list); NFSUNLOCKMNT(nmp); } else @@ -4389,7 +4403,10 @@ printf("v41fl=0x%x\n", v41flags); NFSLOCKMNT(nmp); nmp->nm_state |= NFSSTA_PNFS; NFSUNLOCKMNT(nmp); + dsp->nfsclds_flags |= NFSCLDS_MDS; } + if ((v41flags & NFSV4EXCH_USEPNFSDS) != 0) + dsp->nfsclds_flags |= NFSCLDS_DS; nd->nd_repstat = nfsrv_mtostr(nd, dsp->nfsclds_serverown, len); if (nd->nd_repstat == 0) { mtx_init(&dsp->nfsclds_mtx, "nfsds", NULL, MTX_DEF); @@ -4411,7 +4428,7 @@ nfsmout: */ int nfsrpc_createsession(struct nfsmount *nmp, struct nfsclsession *sep, - struct ucred *cred, NFSPROC_T *p) + uint32_t sequenceid, struct ucred *cred, NFSPROC_T *p) { uint32_t *tl; struct nfsrv_descript nfsd; @@ -4422,8 +4439,8 @@ nfsrpc_createsession(struct nfsmount *nm NFSM_BUILD(tl, uint32_t *, 4 * NFSX_UNSIGNED); *tl++ = sep->nfsess_clientid.lval[0]; *tl++ = sep->nfsess_clientid.lval[1]; - *tl++ = txdr_unsigned(sep->nfsess_sequenceid); -printf("clseq0=0x%x\n",sep->nfsess_sequenceid); + *tl++ = txdr_unsigned(sequenceid); +printf("clseq0=0x%x\n",sequenceid); if (nfscl_enablecallb != 0 && nfs_numnfscbd > 0) *tl = txdr_unsigned(NFSV4CRSESS_PERSIST | NFSV4CRSESS_CONNBACKCHAN); @@ -5055,6 +5072,8 @@ nfsrpc_fillsa(struct nfsmount *nmp, stru struct nfssockreq *nrp; struct nfsclds *dsp, *tdsp; int error; + enum nfsclds_state retv; + uint32_t sequenceid; KASSERT(nmp->nm_sockreq.nr_cred != NULL, ("nfsrpc_fillsa: NULL nr_cred")); @@ -5106,8 +5125,10 @@ nfsrpc_fillsa(struct nfsmount *nmp, stru &dsp, nrp->nr_cred, p); if (error == 0) { dsp->nfsclds_sockp = nrp; - tdsp = nfscl_getsameserver(nmp, dsp); - if (tdsp != NULL) { + NFSLOCKMNT(nmp); + retv = nfscl_getsameserver(nmp, dsp, &tdsp); + if (retv == NFSDSP_USETHISSESSION) { + NFSUNLOCKMNT(nmp); /* * If there is already a session for this server, * use it. @@ -5117,8 +5138,14 @@ nfsrpc_fillsa(struct nfsmount *nmp, stru *dspp = tdsp; return (0); } + if (retv == NFSDSP_SEQTHISSESSION) { + tdsp->nfsclds_sess.nfsess_sequenceid++; + sequenceid = tdsp->nfsclds_sess.nfsess_sequenceid; + } else + sequenceid = dsp->nfsclds_sess.nfsess_sequenceid; + NFSUNLOCKMNT(nmp); error = nfsrpc_createsession(nmp, &dsp->nfsclds_sess, - nrp->nr_cred, p); + sequenceid, nrp->nr_cred, p); } else { NFSFREECRED(nrp->nr_cred); NFSFREEMUTEX(&nrp->nr_mtx); @@ -5127,14 +5154,13 @@ nfsrpc_fillsa(struct nfsmount *nmp, stru } if (error == 0) { /* - * The first element should be the one for the MDS. + * Put it at the end of the list. That way the list + * is ordered by when the entry was added. This matters + * since the one done first is the one that should be + * used for sequencid'ing any subsequent create sessions. */ 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); + TAILQ_INSERT_TAIL(&nmp->nm_sess, dsp, nfsclds_list); NFSUNLOCKMNT(nmp); *dspp = dsp; } else if (dsp != NULL) @@ -5498,9 +5524,9 @@ nfsrpc_writeds(vnode_t vp, struct uio *u NFSUNLOCKMNT(nmp); } else { NFSLOCKDS(dsp); - if (dsp->nfsclds_haswriteverf == 0) { + if ((dsp->nfsclds_flags & NFSCLDS_HASWRITEVERF) == 0) { NFSBCOPY(tl, dsp->nfsclds_verf, NFSX_VERF); - dsp->nfsclds_haswriteverf = 1; + dsp->nfsclds_flags |= NFSCLDS_HASWRITEVERF; } else if (NFSBCMP(tl, dsp->nfsclds_verf, NFSX_VERF)) { *must_commit = 1; NFSBCOPY(tl, dsp->nfsclds_verf, NFSX_VERF); @@ -5543,14 +5569,40 @@ nfscl_freenfsclds(struct nfsclds *dsp) free(dsp, M_NFSCLDS); } -static struct nfsclds * -nfscl_getsameserver(struct nfsmount *nmp, struct nfsclds *newdsp) +static enum nfsclds_state +nfscl_getsameserver(struct nfsmount *nmp, struct nfsclds *newdsp, + struct nfsclds **retdspp) { + struct nfsclds *dsp, *cur_dsp; /* * Search the list of nfsclds structures for one with the same * server. */ - return (LIST_FIRST(&nmp->nm_sess)); + cur_dsp = NULL; + TAILQ_FOREACH(dsp, &nmp->nm_sess, nfsclds_list) { + if (dsp->nfsclds_servownlen == newdsp->nfsclds_servownlen && + !NFSBCMP(dsp->nfsclds_serverown, newdsp->nfsclds_serverown, + dsp->nfsclds_servownlen)) { +printf("fnd same fdsp=%p dsp=%p flg=0x%x\n", TAILQ_FIRST(&nmp->nm_sess), dsp, dsp->nfsclds_flags); + /* Server major id matches. */ + if ((dsp->nfsclds_flags & NFSCLDS_DS) != 0) { + *retdspp = dsp; + return (NFSDSP_USETHISSESSION); + } + + /* + * Note the first match, so it can be used for + * sequence'ing new sessions. + */ + if (cur_dsp == NULL) + cur_dsp = dsp; + } + } + if (cur_dsp != NULL) { + *retdspp = cur_dsp; + return (NFSDSP_SEQTHISSESSION); + } + return (NFSDSP_NOTFOUND); } Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c Thu Feb 23 01:22:40 2012 (r232016) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clvfsops.c Thu Feb 23 03:16:09 2012 (r232017) @@ -1452,7 +1452,7 @@ bad: NFSUNLOCKCLSTATE(); free(nmp->nm_clp, M_NFSCLCLIENT); } - LIST_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) + TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) nfscl_freenfsclds(dsp); FREE(nmp, M_NEWNFSMNT); FREE(nam, M_SONAME); @@ -1509,7 +1509,7 @@ nfs_unmount(struct mount *mp, int mntfla mtx_destroy(&nmp->nm_sockreq.nr_mtx); mtx_destroy(&nmp->nm_mtx); - LIST_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) + TAILQ_FOREACH_SAFE(dsp, &nmp->nm_sess, nfsclds_list, tdsp) nfscl_freenfsclds(dsp); FREE(nmp, M_NEWNFSMNT); out: Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h ============================================================================== --- projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h Thu Feb 23 01:22:40 2012 (r232016) +++ projects/nfsv4.1-client/sys/fs/nfsclient/nfsmount.h Thu Feb 23 03:16:09 2012 (r232017) @@ -70,7 +70,7 @@ struct nfsmount { int nm_negnametimeo; /* timeout for -ve entries (sec) */ /* Newnfs additions */ - LIST_HEAD(, nfsclds) nm_sess; /* Session(s) for NFSv4.1. */ + TAILQ_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 */ @@ -113,7 +113,7 @@ struct nfsmount { * 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)) +#define NFSMNT_MDSSESSION(m) (&(TAILQ_FIRST(&((m)->nm_sess))->nfsclds_sess)) #ifndef NFS_DEFAULT_NAMETIMEO #define NFS_DEFAULT_NAMETIMEO 60