svn commit: r229166 - in projects/nfsv4.1-client/sys/fs: nfs nfsclient

Rick Macklem rmacklem at FreeBSD.org
Sun Jan 1 02:34:16 UTC 2012


Author: rmacklem
Date: Sun Jan  1 02:34:15 2012
New Revision: 229166
URL: http://svn.freebsd.org/changeset/base/229166

Log:
  Define the structure that stores an NFSv4.1 File Layout and add
  the function nfsrpc_layoutget() that does the LayoutGet Operation
  to fill it in. The function is untested at this point and the
  structure may need to change.

Modified:
  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_clrpcops.c

Modified: projects/nfsv4.1-client/sys/fs/nfs/nfs_commonport.c
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfs/nfs_commonport.c	Sun Jan  1 01:08:51 2012	(r229165)
+++ projects/nfsv4.1-client/sys/fs/nfs/nfs_commonport.c	Sun Jan  1 02:34:15 2012	(r229166)
@@ -104,6 +104,7 @@ MALLOC_DEFINE(M_NEWNFSDIROFF, "NFSCL dir
     "New NFS directory offset data");
 MALLOC_DEFINE(M_NEWNFSDROLLBACK, "NFSD rollback",
     "New NFS local lock rollback");
+MALLOC_DEFINE(M_NEWNFSFLAYOUT, "NFSCL flayout", "NFSv4.1 File Layout");
 
 /*
  * 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	Sun Jan  1 01:08:51 2012	(r229165)
+++ projects/nfsv4.1-client/sys/fs/nfs/nfs_var.h	Sun Jan  1 02:34:15 2012	(r229166)
@@ -73,6 +73,8 @@ struct nfsclsession;
 struct nfscllockowner;
 struct nfscllock;
 struct nfscldeleg;
+struct nfsclflayout;
+struct nfsclflayouthead;
 struct nfsv4lock;
 struct nfsvattr;
 struct nfs_vattr;
@@ -440,6 +442,9 @@ int nfsrpc_destroysession(struct nfsmoun
     struct ucred *, NFSPROC_T *);
 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 *);
 
 /* 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 01:08:51 2012	(r229165)
+++ projects/nfsv4.1-client/sys/fs/nfs/nfsclstate.h	Sun Jan  1 02:34:15 2012	(r229166)
@@ -40,6 +40,8 @@ LIST_HEAD(nfsclhead, nfsclclient);
 LIST_HEAD(nfsclownerhead, nfsclowner);
 TAILQ_HEAD(nfscldeleghead, nfscldeleg);
 LIST_HEAD(nfscldeleghash, nfscldeleg);
+TAILQ_HEAD(nfsclflayouthead, nfsclflayout);
+LIST_HEAD(nfsclflayouthash, nfsclflayout);
 #define	NFSCLDELEGHASHSIZE	256
 #define	NFSCLDELEGHASH(c, f, l)						\
 	(&((c)->nfsc_deleghash[ncl_hash((f), (l)) % NFSCLDELEGHASHSIZE]))
@@ -198,6 +200,27 @@ struct nfscllockownerfh {
 };
 
 /*
+ * MALLOC'd to the correct length to accommodate the file handle list.
+ */
+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;
+	uint8_t				nfsfl_dev[NFSX_V4DEVICEID];
+	uint64_t			nfsfl_off;
+	uint64_t			nfsfl_len;
+	uint64_t			nfsfl_patoff;
+	uint32_t			nfsfl_iomode;
+	uint32_t			nfsfl_util;
+	uint32_t			nfsfl_stripe1;
+	uint16_t			nfsfl_retonclose;
+	uint16_t			nfsfl_fhcnt;
+	struct nfsfh			*nfsfl_fh[1];	/* FH list for DS */
+};
+
+/*
  * Macro for incrementing the seqid#.
  */
 #define	NFSCL_INCRSEQID(s, n)	do { 					\

Modified: projects/nfsv4.1-client/sys/fs/nfs/nfsport.h
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfs/nfsport.h	Sun Jan  1 01:08:51 2012	(r229165)
+++ projects/nfsv4.1-client/sys/fs/nfs/nfsport.h	Sun Jan  1 02:34:15 2012	(r229166)
@@ -732,6 +732,7 @@ MALLOC_DECLARE(M_NEWNFSV4NODE);
 MALLOC_DECLARE(M_NEWNFSDIRECTIO);
 MALLOC_DECLARE(M_NEWNFSMNT);
 MALLOC_DECLARE(M_NEWNFSDROLLBACK);
+MALLOC_DECLARE(M_NEWNFSFLAYOUT);
 #define	M_NFSRVCACHE	M_NEWNFSRVCACHE
 #define	M_NFSDCLIENT	M_NEWNFSDCLIENT
 #define	M_NFSDSTATE	M_NEWNFSDSTATE
@@ -751,6 +752,7 @@ MALLOC_DECLARE(M_NEWNFSDROLLBACK);
 #define	M_NFSV4NODE	M_NEWNFSV4NODE
 #define	M_NFSDIRECTIO	M_NEWNFSDIRECTIO
 #define	M_NFSDROLLBACK	M_NEWNFSDROLLBACK
+#define	M_NFSFLAYOUT	M_NEWNFSFLAYOUT
 
 #define	NFSINT_SIGMASK(set) 						\
 	(SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) ||	\

Modified: projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c	Sun Jan  1 01:08:51 2012	(r229165)
+++ projects/nfsv4.1-client/sys/fs/nfsclient/nfs_clrpcops.c	Sun Jan  1 02:34:15 2012	(r229166)
@@ -4451,3 +4451,153 @@ nfsrpc_destroyclient(struct nfsmount *nm
 	return (error);
 }
 
+/*
+ * Do the NFSv4.1 LayoutGet.
+ */
+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)
+{
+	uint32_t *tl;
+	struct nfsrv_descript nfsd, *nd = &nfsd;
+	struct nfsfh *fhp;
+	struct nfsclflayout *flp, *nflp;
+	struct nfsnode *np;
+	nfsv4stateid_t st;
+	int cnt, error, fhcnt, fhlen, i, j, retonclose;
+	uint8_t *cp;
+
+	np = VTONFS(vp);
+	NFSCL_REQSTART(nd, NFSPROC_LAYOUTGET, vp);
+	NFSM_BUILD(tl, uint32_t *, 4 * NFSX_UNSIGNED + 3 * NFSX_HYPER +
+	    NFSX_STATEID);
+	*tl++ = newnfs_false;		/* Don't signal availability. */
+	*tl++ = txdr_unsigned(NFSLAYOUT_NFSV4_1_FILES);
+	*tl++ = txdr_unsigned(iomode);
+	txdr_hyper(offset, tl);
+	tl += 2;
+	txdr_hyper(len, tl);
+	tl += 2;
+	txdr_hyper(minlen, tl);
+	tl += 2;
+	*tl++ = stateidp->seqid;
+	*tl++ = stateidp->other[0];
+	*tl++ = stateidp->other[1];
+	*tl++ = stateidp->other[2];
+	*tl = txdr_unsigned(100000);	/* take a large layout list */
+	nd->nd_flag |= ND_USEGSSNAME;
+	error = nfscl_request(nd, vp, p, cred, stuff);
+	if (error)
+		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++;
+		cnt = fxdr_unsigned(int, *tl);
+printf("layg cnt=%d\n", cnt);
+		if (cnt <= 0 || cnt > 10000) {
+			/* Don't accept more than 10000 layouts in reply. */
+			error = NFSERR_BADXDR;
+			goto nfsmout;
+		}
+		for (i = 0; i < cnt; i++) {
+			/* Dissect all the way to the file handle cnt. */
+			NFSM_DISSECT(tl, uint32_t *, 3 * NFSX_HYPER +
+			    6 * NFSX_UNSIGNED + NFSX_V4DEVICEID);
+			fhcnt = fxdr_unsigned(int, *(tl + 11 +
+			    NFSX_V4DEVICEID / NFSX_UNSIGNED));
+printf("fhcnt=%d\n", fhcnt);
+			if (fhcnt < 0 || fhcnt > 100) {
+				/* Don't accept more than 100 file handles. */
+				error = NFSERR_BADXDR;
+				goto nfsmout;
+			}
+			if (fhcnt > 1)
+				flp = malloc(sizeof(*flp) + (fhcnt - 1) *
+				    sizeof(struct nfsfh *),
+				    M_NFSFLAYOUT, M_WAITOK);
+			else
+				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++);
+printf("layg iom=%d\n", iomode);
+			if (fxdr_unsigned(int, *tl++) !=
+			    NFSLAYOUT_NFSV4_1_FILES) {
+				printf("NFSv4.1: got non-files layout\n");
+				error = NFSERR_BADXDR;
+				goto nfsmout;
+			}
+			NFSBCOPY(++tl, flp->nfsfl_dev, NFSX_V4DEVICEID);
+			tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED);
+			flp->nfsfl_util = fxdr_unsigned(uint32_t, *tl++);
+			flp->nfsfl_stripe1 = fxdr_unsigned(uint32_t, *tl++);
+			flp->nfsfl_patoff = fxdr_hyper(tl); tl += 2;
+			if (fxdr_unsigned(int, *tl) != fhcnt) {
+				printf("EEK! bad fhcnt\n");
+				error = NFSERR_BADXDR;
+				goto nfsmout;
+			}
+			for (j = 0; j < fhcnt; j++) {
+				NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED);
+				fhlen = fxdr_unsigned(int, *tl);
+				if (fhlen <= 0 || fhlen > NFSX_V4FHMAX) {
+					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);
+				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 (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);
+	}
+	mbuf_freem(nd->nd_mrep);
+	return (error);
+}
+


More information about the svn-src-projects mailing list