Author: rmacklem Date: Fri Jun 22 21:25:27 2018 New Revision: 335567 URL: https://svnweb.freebsd.org/changeset/base/335567
Log: Change the NFSv4.1 pNFS client so that it returns the DS error in layoutreturn. When the NFSv4.1 pNFS client gets an error for a DS I/O operation using a Flexible File layout, it returns the layout with an error. This patch changes the code slightly, so that it returns the layout for all errors except EACCES and lets the MDS decide what to do based on the error. It also makes a couple of changes to nfscl_layoutrecall() to ensure that the first layoutreturn(s) will have the error in the reply. Plus, the patch adds a wakeup() so that the "nfscl" thread won't wait 1sec before doing the LayoutReturn. Tested against the pNFS service. This patch should not affect non-pNFS use of the client. The unused "dsp" argument will be used by a future patch that disables the connection to the DS when possible. MFC after: 2 weeks Modified: head/sys/fs/nfs/nfs_var.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 Fri Jun 22 20:58:51 2018 (r335566) +++ head/sys/fs/nfs/nfs_var.h Fri Jun 22 21:25:27 2018 (r335567) @@ -601,7 +601,8 @@ 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_dserr(uint32_t, uint32_t, struct nfscldevinfo *, + struct nfscllayout *, struct nfsclds *); void nfscl_rellayout(struct nfscllayout *, int); struct nfscldevinfo *nfscl_getdevinfo(struct nfsclclient *, uint8_t *, struct nfscldevinfo *); Modified: head/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clrpcops.c Fri Jun 22 20:58:51 2018 (r335566) +++ head/sys/fs/nfsclient/nfs_clrpcops.c Fri Jun 22 21:25:27 2018 (r335567) @@ -6040,10 +6040,11 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int * *dspp, fhp, dp->nfsdi_vers, dp->nfsdi_minorvers, tcred, p); NFSCL_DEBUG(4, "commitds=%d\n", error); - if (nfsds_failerr(error)) { + if (error != 0 && error != EACCES) { NFSCL_DEBUG(4, "DS layreterr for commit\n"); - nfscl_dserr(NFSV4OP_COMMIT, dp, lyp); + nfscl_dserr(NFSV4OP_COMMIT, error, dp, + lyp, *dspp); } } NFSCL_DEBUG(4, "aft nfsio_commitds=%d\n", error); @@ -6064,9 +6065,10 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int * off, xfer, fhp, 1, dp->nfsdi_vers, dp->nfsdi_minorvers, tcred, p); NFSCL_DEBUG(4, "readds=%d\n", error); - if (nfsds_failerr(error)) { + if (error != 0 && error != EACCES) { NFSCL_DEBUG(4, "DS layreterr for read\n"); - nfscl_dserr(NFSV4OP_READ, dp, lyp); + nfscl_dserr(NFSV4OP_READ, error, dp, lyp, + *dspp); } } else { if (flp->nfsfl_mirrorcnt == 1) { @@ -6099,10 +6101,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)) { + if (error != 0 && error != EACCES) { NFSCL_DEBUG(4, "DS layreterr for write\n"); - nfscl_dserr(NFSV4OP_WRITE, dp, lyp); + nfscl_dserr(NFSV4OP_WRITE, error, dp, + lyp, *dspp); } } } Modified: head/sys/fs/nfsclient/nfs_clstate.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clstate.c Fri Jun 22 20:58:51 2018 (r335566) +++ head/sys/fs/nfsclient/nfs_clstate.c Fri Jun 22 21:25:27 2018 (r335567) @@ -4973,11 +4973,13 @@ nfscl_retoncloselayout(vnode_t vp, struct nfsclclient * Mark the layout to be recalled and with an error. */ void -nfscl_dserr(uint32_t op, struct nfscldevinfo *dp, struct nfscllayout *lyp) +nfscl_dserr(uint32_t op, uint32_t stat, struct nfscldevinfo *dp, + struct nfscllayout *lyp, __unused struct nfsclds *dsp) { struct nfsclrecalllayout *recallp; uint32_t iomode; + /* Set up the return of the layout. */ recallp = malloc(sizeof(*recallp), M_NFSLAYRECALL, M_WAITOK); iomode = 0; NFSLOCKCLSTATE(); @@ -4987,10 +4989,10 @@ nfscl_dserr(uint32_t op, struct nfscldevinfo *dp, stru 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, + 0, UINT64_MAX, lyp->nfsly_stateid.seqid, stat, op, dp->nfsdi_deviceid, recallp); NFSUNLOCKCLSTATE(); - NFSCL_DEBUG(4, "retoncls recall iomode=%d\n", iomode); + NFSCL_DEBUG(4, "nfscl_dserr recall iomode=%d\n", iomode); } else { NFSUNLOCKCLSTATE(); free(recallp, M_NFSLAYRECALL); @@ -5247,6 +5249,19 @@ nfscl_layoutrecall(int recalltype, struct nfscllayout LIST_INSERT_BEFORE(rp, recallp, nfsrecly_list); break; } + + /* + * Put any error return on all the file returns that will + * preceed this one. + */ + if (rp->nfsrecly_recalltype == NFSLAYOUTRETURN_FILE && + stat != 0 && rp->nfsrecly_stat == 0) { + rp->nfsrecly_stat = stat; + rp->nfsrecly_op = op; + if (devid != NULL) + NFSBCOPY(devid, rp->nfsrecly_devid, + NFSX_V4DEVICEID); + } } if (rp == NULL) { if (orp == NULL) @@ -5256,6 +5271,7 @@ nfscl_layoutrecall(int recalltype, struct nfscllayout LIST_INSERT_AFTER(orp, recallp, nfsrecly_list); } lyp->nfsly_flags |= NFSLY_RECALL; + wakeup(lyp->nfsly_clp); return (0); } _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"