Date: Sun, 17 Jun 2018 16:30:06 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r335286 - in head/sys/fs: nfs nfsclient Message-ID: <201806171630.w5HGU6u3091331@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Sun Jun 17 16:30:06 2018 New Revision: 335286 URL: https://svnweb.freebsd.org/changeset/base/335286 Log: Make the pNFS NFSv4.1 client return a Flexible File layout upon error. The Flexible File layout LayoutReturn operation has argument fields where an I/O error encountered when attempting I/O on a DS can be reported back to the MDS. This patch adds code to the client to do this for the Flexible File layout mirrored case. This patch should only affect mounts using the "pnfs" option against servers that support the Flexible File layout. MFC after: 2 weeks Modified: head/sys/fs/nfs/nfs_var.h head/sys/fs/nfs/nfsclstate.h head/sys/fs/nfsclient/nfs_clrpcops.c head/sys/fs/nfsclient/nfs_clstate.c Modified: head/sys/fs/nfs/nfs_var.h ============================================================================== --- head/sys/fs/nfs/nfs_var.h Sun Jun 17 16:24:46 2018 (r335285) +++ head/sys/fs/nfs/nfs_var.h Sun Jun 17 16:30:06 2018 (r335286) @@ -528,7 +528,7 @@ int nfsrpc_layoutcommit(struct nfsmount *, uint8_t *, NFSPROC_T *, void *); int nfsrpc_layoutreturn(struct nfsmount *, uint8_t *, int, int, int, uint32_t, int, uint64_t, uint64_t, nfsv4stateid_t *, struct ucred *, NFSPROC_T *, - void *); + uint32_t, uint32_t, char *); int nfsrpc_reclaimcomplete(struct nfsmount *, struct ucred *, NFSPROC_T *); int nfscl_doiods(vnode_t, struct uio *, int *, int *, uint32_t, int, struct ucred *, NFSPROC_T *); @@ -601,6 +601,7 @@ int nfscl_layout(struct nfsmount *, vnode_t, u_int8_t NFSPROC_T *); struct nfscllayout *nfscl_getlayout(struct nfsclclient *, uint8_t *, int, uint64_t, struct nfsclflayout **, int *); +void nfscl_dserr(uint32_t, struct nfscldevinfo *, struct nfscllayout *); void nfscl_rellayout(struct nfscllayout *, int); struct nfscldevinfo *nfscl_getdevinfo(struct nfsclclient *, uint8_t *, struct nfscldevinfo *); Modified: head/sys/fs/nfs/nfsclstate.h ============================================================================== --- head/sys/fs/nfs/nfsclstate.h Sun Jun 17 16:24:46 2018 (r335285) +++ head/sys/fs/nfs/nfsclstate.h Sun Jun 17 16:30:06 2018 (r335286) @@ -340,6 +340,9 @@ struct nfsclrecalllayout { int nfsrecly_recalltype; uint32_t nfsrecly_iomode; uint32_t nfsrecly_stateseqid; + uint32_t nfsrecly_stat; + uint32_t nfsrecly_op; + char nfsrecly_devid[NFSX_V4DEVICEID]; }; /* Modified: head/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clrpcops.c Sun Jun 17 16:24:46 2018 (r335285) +++ head/sys/fs/nfsclient/nfs_clrpcops.c Sun Jun 17 16:30:06 2018 (r335286) @@ -5203,10 +5203,11 @@ int nfsrpc_layoutreturn(struct nfsmount *nmp, uint8_t *fh, int fhlen, int reclaim, int layouttype, uint32_t iomode, int layoutreturn, uint64_t offset, uint64_t len, nfsv4stateid_t *stateidp, struct ucred *cred, NFSPROC_T *p, - void *stuff) + uint32_t stat, uint32_t op, char *devid) { uint32_t *tl; struct nfsrv_descript nfsd, *nd = &nfsd; + uint64_t tu64; int error; nfscl_reqstart(nd, NFSPROC_LAYOUTRETURN, nmp, fh, fhlen, NULL, NULL, @@ -5234,11 +5235,32 @@ nfsrpc_layoutreturn(struct nfsmount *nmp, uint8_t *fh, if (layouttype == NFSLAYOUT_NFSV4_1_FILES) *tl = txdr_unsigned(0); else if (layouttype == NFSLAYOUT_FLEXFILE) { - *tl = txdr_unsigned(2 * NFSX_UNSIGNED); - NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); - /* No ioerrs or stats yet. */ - *tl++ = 0; - *tl = 0; + if (stat != 0) { + *tl = txdr_unsigned(2 * NFSX_HYPER + + NFSX_STATEID + NFSX_V4DEVICEID + 5 * + NFSX_UNSIGNED); + NFSM_BUILD(tl, uint32_t *, 2 * NFSX_HYPER + + NFSX_STATEID + NFSX_V4DEVICEID + 5 * + NFSX_UNSIGNED); + *tl++ = txdr_unsigned(1); /* One error. */ + tu64 = 0; /* Offset. */ + txdr_hyper(tu64, tl); tl += 2; + tu64 = UINT64_MAX; /* Length. */ + txdr_hyper(tu64, tl); tl += 2; + NFSBCOPY(stateidp, tl, NFSX_STATEID); + tl += (NFSX_STATEID / NFSX_UNSIGNED); + *tl++ = txdr_unsigned(1); /* One error. */ + NFSBCOPY(devid, tl, NFSX_V4DEVICEID); + tl += (NFSX_V4DEVICEID / NFSX_UNSIGNED); + *tl++ = txdr_unsigned(stat); + *tl++ = txdr_unsigned(op); + } else { + *tl = txdr_unsigned(2 * NFSX_UNSIGNED); + NFSM_BUILD(tl, uint32_t *, 2 * NFSX_UNSIGNED); + /* No ioerrs. */ + *tl++ = 0; + } + *tl = 0; /* No stats yet. */ } } nd->nd_flag |= ND_USEGSSNAME; @@ -6017,6 +6039,12 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int * error = nfsrpc_commitds(vp, off, xfer, *dspp, fhp, dp->nfsdi_vers, dp->nfsdi_minorvers, tcred, p); + NFSCL_DEBUG(4, "commitds=%d\n", error); + if (nfsds_failerr(error)) { + NFSCL_DEBUG(4, + "DS layreterr for commit\n"); + nfscl_dserr(NFSV4OP_COMMIT, dp, lyp); + } } NFSCL_DEBUG(4, "aft nfsio_commitds=%d\n", error); if (error == 0) { @@ -6031,11 +6059,16 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int * np->n_flag &= ~NDSCOMMIT; mtx_unlock(&np->n_mtx); } - } else if (rwflag == NFSV4OPEN_ACCESSREAD) + } else if (rwflag == NFSV4OPEN_ACCESSREAD) { error = nfsrpc_readds(vp, uiop, stateidp, eofp, *dspp, off, xfer, fhp, 1, dp->nfsdi_vers, dp->nfsdi_minorvers, tcred, p); - else { + NFSCL_DEBUG(4, "readds=%d\n", error); + if (nfsds_failerr(error)) { + NFSCL_DEBUG(4, "DS layreterr for read\n"); + nfscl_dserr(NFSV4OP_READ, dp, lyp); + } + } else { if (flp->nfsfl_mirrorcnt == 1) { error = nfsrpc_writeds(vp, uiop, iomode, must_commit, stateidp, *dspp, off, xfer, @@ -6066,6 +6099,11 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int * xfer, fhp, m, dp->nfsdi_vers, dp->nfsdi_minorvers, tcred, p); NFSCL_DEBUG(4, "nfsio_writedsmir=%d\n", error); + if (nfsds_failerr(error)) { + NFSCL_DEBUG(4, + "DS layreterr for write\n"); + nfscl_dserr(NFSV4OP_WRITE, dp, lyp); + } } } NFSCL_DEBUG(4, "aft read/writeds=%d\n", error); Modified: head/sys/fs/nfsclient/nfs_clstate.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clstate.c Sun Jun 17 16:24:46 2018 (r335285) +++ head/sys/fs/nfsclient/nfs_clstate.c Sun Jun 17 16:30:06 2018 (r335286) @@ -164,7 +164,7 @@ static void nfscl_emptylockowner(struct nfscllockowner static void nfscl_mergeflayouts(struct nfsclflayouthead *, struct nfsclflayouthead *); static int nfscl_layoutrecall(int, struct nfscllayout *, uint32_t, uint64_t, - uint64_t, uint32_t, struct nfsclrecalllayout *); + uint64_t, uint32_t, uint32_t, uint32_t, char *, struct nfsclrecalllayout *); static int nfscl_seq(uint32_t, uint32_t); static void nfscl_layoutreturn(struct nfsmount *, struct nfscllayout *, struct ucred *, NFSPROC_T *); @@ -2762,7 +2762,8 @@ tryagain2: break; (void)nfscl_layoutrecall(NFSLAYOUTRETURN_FILE, lyp, NFSLAYOUTIOMODE_ANY, 0, UINT64_MAX, - lyp->nfsly_stateid.seqid, recallp); + lyp->nfsly_stateid.seqid, 0, 0, NULL, + recallp); } lyp = nlyp; } @@ -3469,6 +3470,7 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p) recalltype, lyp, iomode, off, len, stateid.seqid, + 0, 0, NULL, recallp); recallp = NULL; wakeup(clp); @@ -3503,6 +3505,7 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p) lyp, iomode, 0, UINT64_MAX, lyp->nfsly_stateid.seqid, + 0, 0, NULL, recallp); recallp = NULL; gotone = 1; @@ -3526,7 +3529,7 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p) recalltype, lyp, iomode, 0, UINT64_MAX, lyp->nfsly_stateid.seqid, - recallp); + 0, 0, NULL, recallp); recallp = NULL; gotone = 1; } @@ -4959,13 +4962,42 @@ nfscl_retoncloselayout(vnode_t vp, struct nfsclclient if (!LIST_EMPTY(&lyp->nfsly_flayrw)) iomode |= NFSLAYOUTIOMODE_RW; (void)nfscl_layoutrecall(NFSLAYOUTRETURN_FILE, lyp, iomode, - 0, UINT64_MAX, lyp->nfsly_stateid.seqid, *recallpp); + 0, UINT64_MAX, lyp->nfsly_stateid.seqid, 0, 0, NULL, + *recallpp); NFSCL_DEBUG(4, "retoncls recall iomode=%d\n", iomode); *recallpp = NULL; } } /* + * Mark the layout to be recalled and with an error. + */ +void +nfscl_dserr(uint32_t op, struct nfscldevinfo *dp, struct nfscllayout *lyp) +{ + struct nfsclrecalllayout *recallp; + uint32_t iomode; + + recallp = malloc(sizeof(*recallp), M_NFSLAYRECALL, M_WAITOK); + iomode = 0; + NFSLOCKCLSTATE(); + if ((lyp->nfsly_flags & NFSLY_RECALL) == 0) { + if (!LIST_EMPTY(&lyp->nfsly_flayread)) + iomode |= NFSLAYOUTIOMODE_READ; + if (!LIST_EMPTY(&lyp->nfsly_flayrw)) + iomode |= NFSLAYOUTIOMODE_RW; + (void)nfscl_layoutrecall(NFSLAYOUTRETURN_FILE, lyp, iomode, + 0, UINT64_MAX, lyp->nfsly_stateid.seqid, NFSERR_IO, op, + dp->nfsdi_deviceid, recallp); + NFSUNLOCKCLSTATE(); + NFSCL_DEBUG(4, "retoncls recall iomode=%d\n", iomode); + } else { + NFSUNLOCKCLSTATE(); + free(recallp, M_NFSLAYRECALL); + } +} + +/* * Dereference a layout. */ void @@ -5182,8 +5214,8 @@ nfscl_freedevinfo(struct nfscldevinfo *dip) */ static int nfscl_layoutrecall(int recalltype, struct nfscllayout *lyp, uint32_t iomode, - uint64_t off, uint64_t len, uint32_t stateseqid, - struct nfsclrecalllayout *recallp) + uint64_t off, uint64_t len, uint32_t stateseqid, uint32_t stat, uint32_t op, + char *devid, struct nfsclrecalllayout *recallp) { struct nfsclrecalllayout *rp, *orp; @@ -5192,6 +5224,10 @@ nfscl_layoutrecall(int recalltype, struct nfscllayout recallp->nfsrecly_stateseqid = stateseqid; recallp->nfsrecly_off = off; recallp->nfsrecly_len = len; + recallp->nfsrecly_stat = stat; + recallp->nfsrecly_op = op; + if (devid != NULL) + NFSBCOPY(devid, recallp->nfsrecly_devid, NFSX_V4DEVICEID); /* * Order the list as file returns first, followed by fsid and any * returns, both in increasing stateseqid order. @@ -5266,7 +5302,8 @@ nfscl_layoutreturn(struct nfsmount *nmp, struct nfscll lyp->nfsly_fhlen, 0, layouttype, rp->nfsrecly_iomode, rp->nfsrecly_recalltype, rp->nfsrecly_off, rp->nfsrecly_len, - &stateid, cred, p, NULL); + &stateid, cred, p, rp->nfsrecly_stat, rp->nfsrecly_op, + rp->nfsrecly_devid); } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201806171630.w5HGU6u3091331>