From owner-svn-src-projects@FreeBSD.ORG Sun Jan 1 02:34:16 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 8198E106564A; Sun, 1 Jan 2012 02:34:16 +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 6F0788FC08; Sun, 1 Jan 2012 02:34:16 +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 q012YGwI093403; Sun, 1 Jan 2012 02:34:16 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q012YGbj093397; Sun, 1 Jan 2012 02:34:16 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <201201010234.q012YGbj093397@svn.freebsd.org> From: Rick Macklem Date: Sun, 1 Jan 2012 02:34:16 +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: r229166 - 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: Sun, 01 Jan 2012 02:34:16 -0000 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); +} +