svn commit: r232017 - in projects/nfsv4.1-client/sys/fs: nfs
nfsclient
Rick Macklem
rmacklem at FreeBSD.org
Thu Feb 23 03:16:10 UTC 2012
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
More information about the svn-src-projects
mailing list