From nobody Tue Jun 23 01:23:06 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gknPk5h2Lz6hxcb for ; Tue, 23 Jun 2026 01:23:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gknPk5JNPz3qBB for ; Tue, 23 Jun 2026 01:23:06 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782177786; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=2MF2ekxZeoyrMr4rhYgxhdUn6RjavyUBIUeMefLBazE=; b=w7dqGCGvcAOkLjbFLaSOpfDfjxEIcJpD1IFkExQXSEHd6vogVfx5QSSVxOl7alhQk2U8cX dJRl8BEpqhzcnhjC3Mjqb36Xyv/aCWbaF/yCwtVK72ikmllA6XG+z/vcoGkIvI8UbX/FZS HE+OauacXWl8jTfG/tvWV7H5aGwnsjbUJ0jYD0j6UU5en9m6kG/tefZMTQOC0opG0Huu3J bryFsyzQYTQlBU//Ycx+r53H34q7i6mYlyRi4BQiQVXP8fQRheee4OP9HtTydIinC4dqs+ j8pnrMvDOJq5BX/BzbYnMixosOCXZJsv5oi4xnElE+5utOheIWWgWS7T9VCWVg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1782177786; a=rsa-sha256; cv=none; b=Qb6hruaPuNeqQsdEW5CdMn+32WL332Ua1lwajNdAOwwM/KD9wBkG4RHW7+JSa19oNWM5fU pTb+kcyQHRkQNPNYnEgzvozPwQEfQp0Jna9xynP78p7I07lVqvNKasQ3DZXasKVmpbLsfi WIyZMhwJFYtZxIYRKDi78gvlJG2bzdcKu8Aprw1/2VG3MOoHoWefuNHcyzt3WQdERN8eOY 3vXm0BFu533/FLZm7j+ol3znAqsH8xEhhfSa4LhWQGx6K/iCv4Dckm16vv4bRAJ5Lj0pHa iqclAJk9O4Qok1+8syJg58k51SMhwAsm1U6wxGzQIe0eN6J+RQudq1jXMEkd/w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1782177786; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=2MF2ekxZeoyrMr4rhYgxhdUn6RjavyUBIUeMefLBazE=; b=Pc7s9DlN/RYL+u6cF9c0WH9ZbMkRJQ90cCL79qUgkwcjxPRzVqo2MKMvAt2Wf/h2fkuLWT IDHUs/OyJH8dDqf6Ai1JdJpsctLdyBOYrtn47Wa6txUQm6fAA/rjba2+KBWTdooLYfF2sH s7WIK6CMrS8Ahxr/fqKkK1Bf77GDHrZ/mvv63Vk4GurdACL9CFItn9Hss7u5JOHKAKJuBn vMSQ2kVtki+tAHLhSuovKGnNgknZM+Tt/t9LVcKygoAfyW+vK9hYFWFghgxA3f4l6TAf14 YK82lhhjuC6/Traa+me4DUM4q9c//xH7l7S0eiyZOT/Uclir9MzWLMJOHxa+aQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gknPk4BmHz1Bfn for ; Tue, 23 Jun 2026 01:23:06 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3f036 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 23 Jun 2026 01:23:06 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Rick Macklem Subject: git: cf523f4beb8f - main - nfscl: Add support for flexible file layout striping List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rmacklem X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: cf523f4beb8ff148828694485ab56f2c1f8f0159 Auto-Submitted: auto-generated Date: Tue, 23 Jun 2026 01:23:06 +0000 Message-Id: <6a39dffa.3f036.542b0928@gitrepo.freebsd.org> The branch main has been updated by rmacklem: URL: https://cgit.FreeBSD.org/src/commit/?id=cf523f4beb8ff148828694485ab56f2c1f8f0159 commit cf523f4beb8ff148828694485ab56f2c1f8f0159 Author: Rick Macklem AuthorDate: 2026-06-23 01:21:08 +0000 Commit: Rick Macklem CommitDate: 2026-06-23 01:21:08 +0000 nfscl: Add support for flexible file layout striping Commit 72e57bc26417 added support for striping to the pNFS server configuration. This patch adds support for striping to the NFS client. For striped flexible file layouts, an extra structure must be malloc()d for each stripe, since the number of stripe servers can vary from one mirror to another. This new structure is called nfsffs and a single one of these structures is in the nfsffm structure so that the non-striped layouts can avoid the additional malloc()'s. This patch only affects NFSv4.1/4.2 mounts that use the "pnfs" mount option against servers that support the flexible file layout. --- sys/fs/nfs/nfs_var.h | 2 +- sys/fs/nfs/nfsclstate.h | 10 +- sys/fs/nfsclient/nfs_clrpcops.c | 305 ++++++++++++++++++++++++++-------------- sys/fs/nfsclient/nfs_clstate.c | 36 +++-- 4 files changed, 234 insertions(+), 119 deletions(-) diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 00ed32ae705e..525f573b5167 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -661,7 +661,7 @@ void nfscl_rellayout(struct nfscllayout *, int); struct nfscldevinfo *nfscl_getdevinfo(struct nfsclclient *, uint8_t *, struct nfscldevinfo *); void nfscl_reldevinfo(struct nfscldevinfo *); -int nfscl_adddevinfo(struct nfsmount *, struct nfscldevinfo *, int, +int nfscl_adddevinfo(struct nfsmount *, struct nfscldevinfo *, int, int, struct nfsclflayout *); void nfscl_freelayout(struct nfscllayout *); void nfscl_freeflayout(struct nfsclflayout *); diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h index 92669ff8d1aa..860a2bd1d4c3 100644 --- a/sys/fs/nfs/nfsclstate.h +++ b/sys/fs/nfs/nfsclstate.h @@ -281,17 +281,23 @@ struct nfscllayout { /* * Flex file layout mirror specific stuff for nfsclflayout. */ -struct nfsffm { +struct nfsffs { nfsv4stateid_t st; struct nfscldevinfo *devp; + struct nfsfh *fh[NFSDEV_MAXVERS]; char dev[NFSX_V4DEVICEID]; uint32_t eff; uid_t user; gid_t group; - struct nfsfh *fh[NFSDEV_MAXVERS]; uint16_t fhcnt; }; +struct nfsffm { + struct nfsffs nonstriped; + struct nfsffs *stripep; + uint16_t stripecnt; +}; + /* * MALLOC'd to the correct length to accommodate the file handle list for File * layout and the list of mirrors for the Flex File Layout. diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 812bb5279e07..fedfc7259197 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -158,12 +158,16 @@ static int nfsrpc_fillsa(struct nfsmount *, struct sockaddr_in *, struct sockaddr_in6 *, sa_family_t, int, int, struct nfsclds **, NFSPROC_T *); static void nfscl_initsessionslots(struct nfsclsession *); +static struct nfscldevinfo **nfscl_getdevlist(struct nfsclclient *, + struct nfsclflayout *, int); +static void nfscl_reldevlist(struct nfscldevinfo **, struct nfsclflayout *, + int); static int nfscl_doflayoutio(vnode_t, struct uio *, int *, int *, int *, nfsv4stateid_t *, int, struct nfscldevinfo *, struct nfscllayout *, struct nfsclflayout *, uint64_t, uint64_t, int, struct ucred *, NFSPROC_T *); static int nfscl_dofflayoutio(vnode_t, struct uio *, int *, int *, int *, - nfsv4stateid_t *, int, struct nfscldevinfo *, struct nfscllayout *, + nfsv4stateid_t *, int, struct nfscldevinfo **, struct nfscllayout *, struct nfsclflayout *, uint64_t, uint64_t, int, int, struct mbuf *, struct nfsclwritedsdorpc *, struct ucred *, NFSPROC_T *); static int nfsrpc_readds(vnode_t, struct uio *, nfsv4stateid_t *, int *, @@ -6552,7 +6556,7 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, struct nfsnode *np = VTONFS(vp); struct nfsmount *nmp = VFSTONFS(vp->v_mount); struct nfscllayout *layp; - struct nfscldevinfo *dip; + struct nfscldevinfo *dip, **dpp; struct nfsclflayout *rflp; struct mbuf *m, *m2; struct nfsclwritedsdorpc *drpc, *tdrpc; @@ -6683,34 +6687,37 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, m = NULL; } if ((layp->nfsly_flags & NFSLY_FLEXFILE) != 0) { - dev = rflp->nfsfl_ffm[i].dev; - dip = nfscl_getdevinfo(nmp->nm_clp, dev, - rflp->nfsfl_ffm[i].devp); - } else { - dev = rflp->nfsfl_dev; - dip = nfscl_getdevinfo(nmp->nm_clp, dev, - rflp->nfsfl_devp); - } - if (dip != NULL) { - if ((rflp->nfsfl_flags & NFSFL_FLEXFILE) - != 0) + dpp = nfscl_getdevlist(nmp->nm_clp, + rflp, i); + if (dpp != NULL) { error = nfscl_dofflayoutio(vp, uiop, iomode, must_commit, &eof, &stateid, rwaccess, - dip, layp, rflp, off, xfer, + dpp, layp, rflp, off, xfer, i, docommit, m2, tdrpc, newcred, p); - else + nfscl_reldevlist(dpp, rflp, i); + } else { + if (m2 != NULL) + m_freem(m2); + error = EIO; + } + } else { + dev = rflp->nfsfl_dev; + dip = nfscl_getdevinfo(nmp->nm_clp, dev, + rflp->nfsfl_devp); + if (dip != NULL) { error = nfscl_doflayoutio(vp, uiop, iomode, must_commit, &eof, &stateid, rwaccess, dip, layp, rflp, off, xfer, docommit, newcred, p); - nfscl_reldevinfo(dip); - } else { - if (m2 != NULL) - m_freem(m2); - error = EIO; + nfscl_reldevinfo(dip); + } else { + if (m2 != NULL) + m_freem(m2); + error = EIO; + } } tdrpc++; } @@ -6794,6 +6801,52 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, return (error); } +/* + * Get the list of device structures for a mirror for a flex file layout. + * (If any stripe entry is missing, return NULL, since the mirror cannot + * be used.) + */ +static struct nfscldevinfo ** +nfscl_getdevlist(struct nfsclclient *clp, struct nfsclflayout *flp, int mirror) +{ + struct nfscldevinfo **dpp, **tdpp; + struct nfsffs *sp; + int i, j; + + dpp = tdpp = malloc(sizeof(*dpp) * flp->nfsfl_ffm[mirror].stripecnt, + M_TEMP, M_WAITOK); + sp = flp->nfsfl_ffm[mirror].stripep; + for (i = 0; i < flp->nfsfl_ffm[mirror].stripecnt; i++, sp++, tdpp++) { + *tdpp = nfscl_getdevinfo(clp, sp->dev, sp->devp); + if (*tdpp == NULL) { + tdpp = dpp; + for (j = 0; j < i; j++, tdpp++) + nfscl_reldevinfo(*tdpp); + free(dpp, M_TEMP); + return (NULL); + } + } + return (dpp); +} + +/* + * Release a device list for a flex file mirror. + */ +static void +nfscl_reldevlist(struct nfscldevinfo **dpp, struct nfsclflayout *flp, + int mirror) +{ + struct nfscldevinfo **tdpp; + int i; + + tdpp = dpp; + for (i = 0; i < flp->nfsfl_ffm[mirror].stripecnt; i++, tdpp++) { + KASSERT(*tdpp != NULL, ("nfscl_reldevlist: NULL devinfo")); + nfscl_reldevinfo(*tdpp); + } + free(dpp, M_TEMP); +} + /* * Find a file layout that will handle the first bytes of the requested * range and return the information from it needed to the I/O operation. @@ -6944,16 +6997,18 @@ nfscl_doflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, */ static int nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, - int *eofp, nfsv4stateid_t *stateidp, int rwflag, struct nfscldevinfo *dp, + int *eofp, nfsv4stateid_t *stateidp, int rwflag, struct nfscldevinfo **dpp, struct nfscllayout *lyp, struct nfsclflayout *flp, uint64_t off, uint64_t len, int mirror, int docommit, struct mbuf *mp, struct nfsclwritedsdorpc *drpc, struct ucred *cred, NFSPROC_T *p) { - uint64_t xfer; - int error; + uint64_t xfer, transfer; + int error, stripe_pos; struct nfsnode *np; struct nfsfh *fhp; struct nfsclds **dspp; + struct nfscldevinfo *dp; + struct nfsffs *sp; struct ucred *tcred; struct mbuf *m, *m2; uint32_t copylen; @@ -6964,15 +7019,37 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, (uintmax_t)len); /* Loop around, doing I/O for each stripe unit. */ while (len > 0 && error == 0) { + if (flp->nfsfl_stripeunit > 0 && + flp->nfsfl_ffm[mirror].stripecnt > 1) { + stripe_pos = (off / flp->nfsfl_stripeunit) % + flp->nfsfl_ffm[mirror].stripecnt; + transfer = flp->nfsfl_stripeunit - + (off % flp->nfsfl_stripeunit); + transfer = (len < transfer) ? len : transfer; + } else { + /* Only one stripe. */ + if (flp->nfsfl_ffm[mirror].stripecnt != 1) { + printf("nfscl_dofflayoutio: stripecnt=%d\n", + flp->nfsfl_ffm[mirror].stripecnt); + error = EIO; + break; + } + stripe_pos = 0; + transfer = len; + } + dp = dpp[stripe_pos]; dspp = nfsfldi_addr(dp, 0); - fhp = flp->nfsfl_ffm[mirror].fh[dp->nfsdi_versindex]; - stateidp = &flp->nfsfl_ffm[mirror].st; - NFSCL_DEBUG(4, "mirror=%d vind=%d fhlen=%d st.seqid=0x%x\n", - mirror, dp->nfsdi_versindex, fhp->nfh_len, stateidp->seqid); + sp = flp->nfsfl_ffm[mirror].stripep; + sp += stripe_pos; + fhp = sp->fh[dp->nfsdi_versindex]; + stateidp = &sp->st; + NFSCL_DEBUG(4, "mirror=%d stripe=%d vind=%d fhlen=%d " + "st.seqid=0x%x\n", mirror, stripe_pos, + dp->nfsdi_versindex, fhp->nfh_len, stateidp->seqid); if ((dp->nfsdi_flags & NFSDI_TIGHTCOUPLED) == 0) { tcred = NFSNEWCRED(cred); - tcred->cr_uid = flp->nfsfl_ffm[mirror].user; - tcred->cr_gid = flp->nfsfl_ffm[mirror].group; + tcred->cr_uid = sp->user; + tcred->cr_gid = sp->group; tcred->cr_ngroups = 0; } else tcred = cred; @@ -6980,7 +7057,7 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, copylen = dp->nfsdi_rsize; else { copylen = dp->nfsdi_wsize; - if (len > copylen && mp != NULL) { + if (transfer > copylen && mp != NULL) { /* * When a mirrored configuration needs to do * multiple writes to each mirror, all writes @@ -7000,10 +7077,10 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, NFSLOCKNODE(np); np->n_flag |= NDSCOMMIT; NFSUNLOCKNODE(np); - if (len > copylen && docommit == 0) + if (transfer > copylen && docommit == 0) xfer = copylen; else - xfer = len; + xfer = transfer; if (docommit != 0) { if (error == 0) { /* @@ -7990,6 +8067,7 @@ nfsrv_parselayoutget(struct nfsmount *nmp, struct nfsrv_descript *nd, { uint32_t *tl; struct nfsclflayout *flp, *prevflp, *tflp; + struct nfsffs *sp; int cnt, error, fhcnt, gotiomode, i, iomode, j, k, l, laytype, nfhlen; int m, mirrorcnt; uint64_t retlen, off; @@ -8104,7 +8182,7 @@ nfsrv_parselayoutget(struct nfsmount *nmp, struct nfsrv_descript *nd, flp->nfsfl_flags = NFSFL_FLEXFILE; flp->nfsfl_mirrorcnt = mirrorcnt; for (j = 0; j < mirrorcnt; j++) - flp->nfsfl_ffm[j].devp = NULL; + flp->nfsfl_ffm[j].stripep = NULL; flp->nfsfl_off = off; if (flp->nfsfl_off + retlen < flp->nfsfl_off) flp->nfsfl_end = UINT64_MAX - flp->nfsfl_off; @@ -8119,43 +8197,45 @@ nfsrv_parselayoutget(struct nfsmount *nmp, struct nfsrv_descript *nd, for (j = 0; j < mirrorcnt; j++) { NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); k = fxdr_unsigned(int, *tl); - if (k < 1 || k > 128) { + if (k < 1 || k > NFSDEV_MAXSTRIPE || + (k != 1 && flp->nfsfl_stripeunit == 0)) { error = NFSERR_BADXDR; goto nfsmout; } - NFSCL_DEBUG(4, "servercnt=%d\n", k); - for (l = 0; l < k; l++) { + NFSCL_DEBUG(4, "stripecnt=%d\n", k); + flp->nfsfl_ffm[j].stripecnt = k; + if (k > 1) + flp->nfsfl_ffm[j].stripep = sp = + malloc(k * sizeof(*sp), + M_NFSFLAYOUT, M_WAITOK); + else + flp->nfsfl_ffm[j].stripep = sp = + &flp->nfsfl_ffm[j].nonstriped; + for (l = 0; l < k; l++, sp++) { + sp->devp = NULL; + sp->fhcnt = 0; + for (m = 0; m < NFSDEV_MAXVERS; m++) + sp->fh[m] = NULL; + } + sp = flp->nfsfl_ffm[j].stripep; + for (l = 0; l < k; l++, sp++) { NFSM_DISSECT(tl, uint32_t *, NFSX_V4DEVICEID + NFSX_STATEID + 2 * NFSX_UNSIGNED); - if (l == 0) { - /* Just use the first server. */ - NFSBCOPY(tl, - flp->nfsfl_ffm[j].dev, - NFSX_V4DEVICEID); - tl += (NFSX_V4DEVICEID / - NFSX_UNSIGNED); - tl++; - flp->nfsfl_ffm[j].st.seqid = - *tl++; - flp->nfsfl_ffm[j].st.other[0] = - *tl++; - flp->nfsfl_ffm[j].st.other[1] = - *tl++; - flp->nfsfl_ffm[j].st.other[2] = - *tl++; - NFSCL_DEBUG(4, "st.seqid=%u " - "st.o0=0x%x st.o1=0x%x " - "st.o2=0x%x\n", - flp->nfsfl_ffm[j].st.seqid, - flp->nfsfl_ffm[j].st.other[0], - flp->nfsfl_ffm[j].st.other[1], - flp->nfsfl_ffm[j].st.other[2]); - } else - tl += ((NFSX_V4DEVICEID + - NFSX_STATEID + - NFSX_UNSIGNED) / - NFSX_UNSIGNED); + NFSBCOPY(tl, sp->dev, NFSX_V4DEVICEID); + tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); + tl++; + sp->st.seqid = *tl++; + sp->st.other[0] = *tl++; + sp->st.other[1] = *tl++; + sp->st.other[2] = *tl++; + NFSCL_DEBUG(4, "st.seqid=%u " + "st.o0=0x%x st.o1=0x%x " + "st.o2=0x%x\n", + sp->st.seqid, + sp->st.other[0], + sp->st.other[1], + sp->st.other[2]); fhcnt = fxdr_unsigned(int, *tl); NFSCL_DEBUG(4, "fhcnt=%d\n", fhcnt); if (fhcnt < 1 || @@ -8177,22 +8257,15 @@ nfsrv_parselayoutget(struct nfsmount *nmp, struct nfsrv_descript *nd, } NFSM_DISSECT(cp, uint8_t *, NFSM_RNDUP(nfhlen)); - if (l == 0) { - flp->nfsfl_ffm[j].fhcnt - = fhcnt; - nfhp = malloc( - sizeof(*nfhp) + - nfhlen - 1, M_NFSFH, - M_WAITOK); - flp->nfsfl_ffm[j].fh[m] - = nfhp; - nfhp->nfh_len = nfhlen; - NFSBCOPY(cp, - nfhp->nfh_fh, - nfhlen); - NFSCL_DEBUG(4, - "got fh\n"); - } + nfhp = malloc(sizeof(*nfhp) + + nfhlen - 1, M_NFSFH, + M_WAITOK); + sp->fh[m] = nfhp; + sp->fhcnt++; + nfhp->nfh_len = nfhlen; + NFSBCOPY(cp, nfhp->nfh_fh, + nfhlen); + NFSCL_DEBUG(4, "got fh\n"); } /* Now, get the ffsd_user/ffds_group. */ error = nfsrv_parseug(nd, 0, &user, @@ -8208,13 +8281,10 @@ nfsrv_parselayoutget(struct nfsmount *nmp, struct nfsrv_descript *nd, goto nfsmout; NFSCL_DEBUG(4, "user=%d group=%d\n", user, grp); - if (l == 0) { - flp->nfsfl_ffm[j].user = user; - flp->nfsfl_ffm[j].group = grp; - NFSCL_DEBUG(4, - "usr=%d grp=%d\n", user, - grp); - } + sp->user = user; + sp->group = grp; + NFSCL_DEBUG(4, "usr=%d grp=%d\n", user, + grp); } } NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); @@ -8905,8 +8975,8 @@ nfsrpc_layoutgetres(struct nfsmount *nmp, vnode_t vp, uint8_t *newfhp, { struct nfsclflayout *tflp; struct nfscldevinfo *dip; - uint8_t *dev; - int i, mirrorcnt; + struct nfsffs *sp; + int i, j; if (laystat == NFSERR_UNKNLAYOUTTYPE) { NFSLOCKMNT(nmp); @@ -8923,27 +8993,54 @@ nfsrpc_layoutgetres(struct nfsmount *nmp, vnode_t vp, uint8_t *newfhp, if (laystat == 0) { NFSCL_DEBUG(4, "nfsrpc_layoutgetres at FOREACH\n"); LIST_FOREACH(tflp, flhp, nfsfl_list) { - if (layouttype == NFSLAYOUT_FLEXFILE) - mirrorcnt = tflp->nfsfl_mirrorcnt; - else - mirrorcnt = 1; - for (i = 0; i < mirrorcnt; i++) { - laystat = nfscl_adddevinfo(nmp, NULL, i, tflp); + if (layouttype == NFSLAYOUT_FLEXFILE) { + for (i = 0; i < tflp->nfsfl_mirrorcnt; i++) { + sp = tflp->nfsfl_ffm[i].stripep; + for (j = 0; sp != NULL && j < + tflp->nfsfl_ffm[i].stripecnt; j++, + sp++) { + laystat = nfscl_adddevinfo(nmp, + NULL, i, j, tflp); + NFSCL_DEBUG(4, "aft adddev=%d" + "\n", laystat); + if (laystat != 0) { + laystat = + nfsrpc_getdeviceinfo( + nmp, sp->dev, + layouttype, notifybit, + &dip, cred, p); + NFSCL_DEBUG(4, + "aft nfsrpc_gdi=%d\n", + laystat); + if (laystat != 0) + goto out; + laystat = + nfscl_adddevinfo( + nmp, dip, i, j, + tflp); + if (laystat != 0) + printf("nfsrpc" + "_layoutget" + "resout" + ": cannot " + "add\n"); + } + } + } + } else { + laystat = nfscl_adddevinfo(nmp, NULL, 0, 0, + tflp); NFSCL_DEBUG(4, "aft adddev=%d\n", laystat); if (laystat != 0) { - if (layouttype == NFSLAYOUT_FLEXFILE) - dev = tflp->nfsfl_ffm[i].dev; - else - dev = tflp->nfsfl_dev; - laystat = nfsrpc_getdeviceinfo(nmp, dev, - layouttype, notifybit, &dip, cred, - p); + laystat = nfsrpc_getdeviceinfo(nmp, + tflp->nfsfl_dev, layouttype, + notifybit, &dip, cred, p); NFSCL_DEBUG(4, "aft nfsrpc_gdi=%d\n", laystat); if (laystat != 0) goto out; - laystat = nfscl_adddevinfo(nmp, dip, i, - tflp); + laystat = nfscl_adddevinfo(nmp, dip, 0, + 0, tflp); if (laystat != 0) printf("nfsrpc_layoutgetresout" ": cannot add\n"); diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index a511c31d5202..1931964ed62e 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -5667,11 +5667,12 @@ nfscl_mergeflayouts(struct nfsclflayouthead *fhlp, * This function consumes the structure pointed at by dip, if not NULL. */ int -nfscl_adddevinfo(struct nfsmount *nmp, struct nfscldevinfo *dip, int ind, - struct nfsclflayout *flp) +nfscl_adddevinfo(struct nfsmount *nmp, struct nfscldevinfo *dip, int mirror, + int stripe, struct nfsclflayout *flp) { struct nfsclclient *clp; struct nfscldevinfo *tdip; + struct nfsffs *sp; uint8_t *dev; NFSLOCKCLSTATE(); @@ -5684,15 +5685,18 @@ nfscl_adddevinfo(struct nfsmount *nmp, struct nfscldevinfo *dip, int ind, } if ((flp->nfsfl_flags & NFSFL_FILE) != 0) dev = flp->nfsfl_dev; - else - dev = flp->nfsfl_ffm[ind].dev; + else { + sp = flp->nfsfl_ffm[mirror].stripep; + sp += stripe; + dev = sp->dev; + } tdip = nfscl_finddevinfo(clp, dev); if (tdip != NULL) { tdip->nfsdi_layoutrefs++; if ((flp->nfsfl_flags & NFSFL_FILE) != 0) flp->nfsfl_devp = tdip; else - flp->nfsfl_ffm[ind].devp = tdip; + sp->devp = tdip; nfscl_reldevinfo_locked(tdip); NFSUNLOCKCLSTATE(); if (dip != NULL) @@ -5705,7 +5709,7 @@ nfscl_adddevinfo(struct nfsmount *nmp, struct nfscldevinfo *dip, int ind, if ((flp->nfsfl_flags & NFSFL_FILE) != 0) flp->nfsfl_devp = dip; else - flp->nfsfl_ffm[ind].devp = dip; + sp->devp = dip; } NFSUNLOCKCLSTATE(); if (dip == NULL) @@ -5745,7 +5749,8 @@ nfscl_freelayout(struct nfscllayout *layp) void nfscl_freeflayout(struct nfsclflayout *flp) { - int i, j; + struct nfsffs *sp; + int i, j, k; if ((flp->nfsfl_flags & NFSFL_FILE) != 0) { for (i = 0; i < flp->nfsfl_fhcnt; i++) @@ -5753,13 +5758,20 @@ nfscl_freeflayout(struct nfsclflayout *flp) if (flp->nfsfl_devp != NULL) flp->nfsfl_devp->nfsdi_layoutrefs--; } - if ((flp->nfsfl_flags & NFSFL_FLEXFILE) != 0) + if ((flp->nfsfl_flags & NFSFL_FLEXFILE) != 0) { for (i = 0; i < flp->nfsfl_mirrorcnt; i++) { - for (j = 0; j < flp->nfsfl_ffm[i].fhcnt; j++) - free(flp->nfsfl_ffm[i].fh[j], M_NFSFH); - if (flp->nfsfl_ffm[i].devp != NULL) - flp->nfsfl_ffm[i].devp->nfsdi_layoutrefs--; + sp = flp->nfsfl_ffm[i].stripep; + for (j = 0; j < flp->nfsfl_ffm[i].stripecnt && + sp != NULL; j++, sp++) { + for (k = 0; k < sp->fhcnt; k++) + free(sp->fh[k], M_NFSFH); + if (sp->devp != NULL) + sp->devp->nfsdi_layoutrefs--; + } + if (flp->nfsfl_ffm[i].stripecnt > 1) + free(flp->nfsfl_ffm[i].stripep, M_NFSFLAYOUT); } + } free(flp, M_NFSFLAYOUT); }