Date: Fri, 13 Jul 2018 20:03:05 +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: r336260 - head/sys/fs/nfsclient Message-ID: <201807132003.w6DK35MK095550@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Fri Jul 13 20:03:05 2018 New Revision: 336260 URL: https://svnweb.freebsd.org/changeset/base/336260 Log: Close down the TCP connection to a pNFS DS when it is disabled. So long as the TCP connection to a pNFS DS isn't shared with other DSs, it can be closed down when the DS is being disabled in the pNFS client. This causes any RPCs in progress to fail. This patch only affects the NFSv4.1 pNFS client when errors occur while doing I/O on a DS. MFC after: 2 weeks Modified: head/sys/fs/nfsclient/nfs_clstate.c Modified: head/sys/fs/nfsclient/nfs_clstate.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clstate.c Fri Jul 13 19:54:22 2018 (r336259) +++ head/sys/fs/nfsclient/nfs_clstate.c Fri Jul 13 20:03:05 2018 (r336260) @@ -125,6 +125,7 @@ static struct nfscldeleg *nfscl_finddeleg(struct nfscl static void nfscl_retoncloselayout(vnode_t, struct nfsclclient *, uint8_t *, int, struct nfsclrecalllayout **); static void nfscl_reldevinfo_locked(struct nfscldevinfo *); +static void nfscl_cancelreqs(struct nfsclds *); static struct nfscllayout *nfscl_findlayout(struct nfsclclient *, u_int8_t *, int); static struct nfscldevinfo *nfscl_finddevinfo(struct nfsclclient *, uint8_t *); @@ -4971,14 +4972,16 @@ nfscl_retoncloselayout(vnode_t vp, struct nfsclclient /* * Mark the layout to be recalled and with an error. + * Also, disable the dsp from further use. */ void nfscl_dserr(uint32_t op, uint32_t stat, struct nfscldevinfo *dp, - struct nfscllayout *lyp, __unused struct nfsclds *dsp) + struct nfscllayout *lyp, struct nfsclds *dsp) { struct nfsclrecalllayout *recallp; uint32_t iomode; + printf("DS being disabled, error=%d\n", stat); /* Set up the return of the layout. */ recallp = malloc(sizeof(*recallp), M_NFSLAYRECALL, M_WAITOK); iomode = 0; @@ -4997,6 +5000,39 @@ nfscl_dserr(uint32_t op, uint32_t stat, struct nfsclde NFSUNLOCKCLSTATE(); free(recallp, M_NFSLAYRECALL); } + + /* If the connection isn't used for other DSs, we can shut it down. */ + if ((dsp->nfsclds_flags & NFSCLDS_SAMECONN) == 0) + nfscl_cancelreqs(dsp); +} + +/* + * Cancel all RPCs for this "dsp" by closing the connection. + * Also, mark the session as defunct. + */ +static void +nfscl_cancelreqs(struct nfsclds *dsp) +{ + struct __rpc_client *cl; + static int non_event; + + NFSLOCKDS(dsp); + if ((dsp->nfsclds_flags & (NFSCLDS_CLOSED | NFSCLDS_SAMECONN)) == 0 && + dsp->nfsclds_sockp != NULL && + dsp->nfsclds_sockp->nr_client != NULL) { + dsp->nfsclds_flags |= NFSCLDS_CLOSED; + cl = dsp->nfsclds_sockp->nr_client; + dsp->nfsclds_sess.nfsess_defunct = 1; + NFSUNLOCKDS(dsp); + CLNT_CLOSE(cl); + /* + * This 1sec sleep is done to reduce the number of reconnect + * attempts made on the DS while it has failed. + */ + tsleep(&non_event, PVFS, "ndscls", hz); + return; + } + NFSUNLOCKDS(dsp); } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201807132003.w6DK35MK095550>