Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Jan 2012 03:38:37 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r229167 - in projects/nfsv4.1-client/sys/fs: nfs nfsclient
Message-ID:  <201201010338.q013cbK2095613@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Sun Jan  1 03:38:36 2012
New Revision: 229167
URL: http://svn.freebsd.org/changeset/base/229167

Log:
  Redefine the NFSv4.1 File Layout structure as 2 structures, where
  the second one chains off the first in increasing offset order.
  This is necessary since the stateid changes for each LayoutGet
  Op. and the most up-to-date one must be used. It also simplified
  the coding of nfsrpc_layoutget().
  This function is still untested and it, along with the structures
  will continue to change for a while.

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

Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h	Sun Jan  1 02:34:15 2012	(r229166)
+++ projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h	Sun Jan  1 03:38:36 2012	(r229167)
@@ -73,8 +73,7 @@ struct nfsclsession;
 struct nfscllockowner;
 struct nfscllock;
 struct nfscldeleg;
-struct nfsclflayout;
-struct nfsclflayouthead;
+struct nfscllayout;
 struct nfsv4lock;
 struct nfsvattr;
 struct nfs_vattr;
@@ -443,8 +442,7 @@ int nfsrpc_destroysession(struct nfsmoun
 int nfsrpc_destroyclient(struct nfsmount *, struct nfsclclient *,
     struct ucred *, NFSPROC_T *);
 int nfsrpc_layoutget(vnode_t, int, uint64_t, uint64_t, uint64_t,
-    nfsv4stateid_t *, struct nfsclflayouthead *, struct ucred *,
-    NFSPROC_T *, void *);
+    struct nfscllayout *, struct ucred *, NFSPROC_T *, void *);
 
 /* 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	Sun Jan  1 02:34:15 2012	(r229166)
+++ projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h	Sun Jan  1 03:38:36 2012	(r229167)
@@ -40,8 +40,9 @@ LIST_HEAD(nfsclhead, nfsclclient);
 LIST_HEAD(nfsclownerhead, nfsclowner);
 TAILQ_HEAD(nfscldeleghead, nfscldeleg);
 LIST_HEAD(nfscldeleghash, nfscldeleg);
-TAILQ_HEAD(nfsclflayouthead, nfsclflayout);
-LIST_HEAD(nfsclflayouthash, nfsclflayout);
+TAILQ_HEAD(nfscllayouthead, nfscllayout);
+LIST_HEAD(nfscllayouthash, nfscllayout);
+LIST_HEAD(nfsclflayouthead, nfsclflayout);
 #define	NFSCLDELEGHASHSIZE	256
 #define	NFSCLDELEGHASH(c, f, l)						\
 	(&((c)->nfsc_deleghash[ncl_hash((f), (l)) % NFSCLDELEGHASHSIZE]))
@@ -200,14 +201,25 @@ struct nfscllockownerfh {
 };
 
 /*
+ * MALLOC'd to the correct length to accommodate the file handle.
+ */
+struct nfscllayout {
+	TAILQ_ENTRY(nfscllayout)	nfsly_list;
+	LIST_ENTRY(nfscllayout)		nfsly_hash;
+	nfsv4stateid_t			nfsly_stateid;
+	struct nfsclflayouthead		nfsly_flay;
+	struct nfsclclient		*nfsly_clp;
+	uint16_t			nfsly_retonclose;
+	uint16_t			nfsly_fhlen;
+	uint8_t				nfsly_fh[1];
+};
+
+/*
  * MALLOC'd to the correct length to accommodate the file handle list.
+ * These hang off of nfsly_flay, sorted in increasing offset order.
  */
 struct nfsclflayout {
-	TAILQ_ENTRY(nfsclflayout)	nfsfl_list;
-	LIST_ENTRY(nfsclflayout)	nfsfl_hash;
-	struct nfsclclient		*nfsfl_clp;
-	struct nfsfh			*nfsfl_fhp;	/* FH of vnode */
-	nfsv4stateid_t			nfsfl_stateid;
+	LIST_ENTRY(nfsclflayout)	nfsfl_list;
 	uint8_t				nfsfl_dev[NFSX_V4DEVICEID];
 	uint64_t			nfsfl_off;
 	uint64_t			nfsfl_len;
@@ -215,8 +227,7 @@ struct nfsclflayout {
 	uint32_t			nfsfl_iomode;
 	uint32_t			nfsfl_util;
 	uint32_t			nfsfl_stripe1;
-	uint16_t			nfsfl_retonclose;
-	uint16_t			nfsfl_fhcnt;
+	uint32_t			nfsfl_fhcnt;
 	struct nfsfh			*nfsfl_fh[1];	/* FH list for DS */
 };
 

Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c	Sun Jan  1 02:34:15 2012	(r229166)
+++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c	Sun Jan  1 03:38:36 2012	(r229167)
@@ -4456,19 +4456,19 @@ nfsrpc_destroyclient(struct nfsmount *nm
  */
 int
 nfsrpc_layoutget(vnode_t vp, int iomode, uint64_t offset, uint64_t len,
-    uint64_t minlen, nfsv4stateid_t *stateidp, struct nfsclflayouthead *flhp,
-    struct ucred *cred, NFSPROC_T *p, void *stuff)
+    uint64_t minlen, struct nfscllayout *lp, struct ucred *cred,
+    NFSPROC_T *p, void *stuff)
 {
 	uint32_t *tl;
 	struct nfsrv_descript nfsd, *nd = &nfsd;
 	struct nfsfh *fhp;
-	struct nfsclflayout *flp, *nflp;
+	struct nfsclflayout *flp, *nflp, *tflp;
 	struct nfsnode *np;
-	nfsv4stateid_t st;
-	int cnt, error, fhcnt, fhlen, i, j, retonclose;
+	int cnt, error, fhcnt, fhlen, i, j;
 	uint8_t *cp;
 
 	np = VTONFS(vp);
+	flp = NULL;
 	NFSCL_REQSTART(nd, NFSPROC_LAYOUTGET, vp);
 	NFSM_BUILD(tl, uint32_t *, 4 * NFSX_UNSIGNED + 3 * NFSX_HYPER +
 	    NFSX_STATEID);
@@ -4481,10 +4481,10 @@ nfsrpc_layoutget(vnode_t vp, int iomode,
 	tl += 2;
 	txdr_hyper(minlen, tl);
 	tl += 2;
-	*tl++ = stateidp->seqid;
-	*tl++ = stateidp->other[0];
-	*tl++ = stateidp->other[1];
-	*tl++ = stateidp->other[2];
+	*tl++ = lp->nfsly_stateid.seqid;
+	*tl++ = lp->nfsly_stateid.other[0];
+	*tl++ = lp->nfsly_stateid.other[1];
+	*tl++ = lp->nfsly_stateid.other[2];
 	*tl = txdr_unsigned(100000);	/* take a large layout list */
 	nd->nd_flag |= ND_USEGSSNAME;
 	error = nfscl_request(nd, vp, p, cred, stuff);
@@ -4492,15 +4492,14 @@ nfsrpc_layoutget(vnode_t vp, int iomode,
 		return (error);
 	if (nd->nd_repstat == 0) {
 		NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED + NFSX_STATEID);
-		if (*tl++ != 0)
-			retonclose = 1;
-		else
-			retonclose = 0;
-printf("layg rcl=%d\n", retonclose);
-		st.seqid = *tl++;
-		st.other[0] = *tl++;
-		st.other[1] = *tl++;
-		st.other[2] = *tl++;
+		if (*tl++ != 0) {
+			lp->nfsly_retonclose = 1;
+printf("layg setting retonclose\n");
+		}
+		lp->nfsly_stateid.seqid = *tl++;
+		lp->nfsly_stateid.other[0] = *tl++;
+		lp->nfsly_stateid.other[1] = *tl++;
+		lp->nfsly_stateid.other[2] = *tl++;
 		cnt = fxdr_unsigned(int, *tl);
 printf("layg cnt=%d\n", cnt);
 		if (cnt <= 0 || cnt > 10000) {
@@ -4528,22 +4527,6 @@ printf("fhcnt=%d\n", fhcnt);
 				flp = malloc(sizeof(*flp),
 				    M_NFSFLAYOUT, M_WAITOK);
 			flp->nfsfl_fhcnt = 0;
-			fhlen = np->n_fhp->nfh_len;
-			if (fhlen > 1)
-				fhp = malloc(sizeof(*fhp) + fhlen - 1,
-				    M_NFSFH, M_WAITOK);
-			else
-				fhp = malloc(sizeof(*fhp), M_NFSFH,
-				    M_WAITOK);
-			fhp->nfh_len = fhlen;
-			NFSBCOPY(np->n_fhp->nfh_fh, fhp->nfh_fh, fhlen);
-			flp->nfsfl_fhp = fhp;
-			TAILQ_INSERT_HEAD(flhp, flp, nfsfl_list);
-			flp->nfsfl_retonclose = retonclose;
-			flp->nfsfl_stateid.seqid = st.seqid;
-			flp->nfsfl_stateid.other[0] = st.other[0];
-			flp->nfsfl_stateid.other[1] = st.other[1];
-			flp->nfsfl_stateid.other[2] = st.other[2];
 			flp->nfsfl_off = fxdr_hyper(tl); tl += 2;
 			flp->nfsfl_len = fxdr_hyper(tl); tl += 2;
 			flp->nfsfl_iomode = fxdr_unsigned(int, *tl++);
@@ -4571,31 +4554,40 @@ printf("layg iom=%d\n", iomode);
 					error = NFSERR_BADXDR;
 					goto nfsmout;
 				}
-				if (fhlen > 1)
-					fhp = malloc(sizeof(*fhp) + fhlen - 1,
-					    M_NFSFH, M_WAITOK);
-				else
-					fhp = malloc(sizeof(*fhp), M_NFSFH,
-					    M_WAITOK);
+				fhp = malloc(sizeof(*fhp) + fhlen - 1,
+				    M_NFSFH, M_WAITOK);
 				flp->nfsfl_fh[j] = fhp;
 				flp->nfsfl_fhcnt++;
 				fhp->nfh_len = fhlen;
 				NFSM_DISSECT(cp, uint8_t *, NFSM_RNDUP(fhlen));
 				NFSBCOPY(cp, fhp->nfh_fh, fhlen);
 			}
+			if (LIST_EMPTY(&lp->nfsly_flay) ||
+			    LIST_FIRST(&lp->nfsly_flay)->nfsfl_off >=
+			    flp->nfsfl_off)
+				LIST_INSERT_HEAD(&lp->nfsly_flay, flp,
+				    nfsfl_list);
+			else {
+				nflp = LIST_FIRST(&lp->nfsly_flay);
+				tflp = LIST_NEXT(nflp, nfsfl_list);
+				while (tflp != NULL) {
+					if (tflp->nfsfl_off >= flp->nfsfl_off)
+						break;
+					nflp = tflp;
+					tflp = LIST_NEXT(tflp, nfsfl_list);
+				}
+				LIST_INSERT_AFTER(nflp, flp, nfsfl_list);
+			}
+			flp = NULL;
 		}
 	}
 	if (nd->nd_repstat != 0 && error == 0)
 		error = nd->nd_repstat;
 nfsmout:
-	if (error != 0) {
-		TAILQ_FOREACH_SAFE(flp, flhp, nfsfl_list, nflp) {
-			for (i = 0; i < flp->nfsfl_fhcnt; i++)
-				free(flp->nfsfl_fh[i], M_NFSFH);
-			free(flp->nfsfl_fhp, M_NFSFH);
-			free(flp, M_NFSFLAYOUT);
-		}
-		TAILQ_INIT(flhp);
+	if (error != 0 && flp != NULL) {
+		for (i = 0; i < flp->nfsfl_fhcnt; i++)
+			free(flp->nfsfl_fh[i], M_NFSFH);
+		free(flp, M_NFSFLAYOUT);
 	}
 	mbuf_freem(nd->nd_mrep);
 	return (error);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201010338.q013cbK2095613>