Date: Sun, 10 Jun 2018 22:11:51 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r334934 - in projects/pnfs-planb-server/sys/fs: nfs nfsclient Message-ID: <201806102211.w5AMBp9o091914@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Sun Jun 10 22:11:51 2018 New Revision: 334934 URL: https://svnweb.freebsd.org/changeset/base/334934 Log: Add code that sets the session defunct after a "soft" mount has returned an error without completing the RPC. Without this, if a DS server is down for a long time, RPCs will use up all the session slots and then processes will hang waiting for a slot. Once an RPC has returned error without completion, the state of the session slot is unknown, so setting it defunct seems to be the only option. Also, add EIO to ENXIO for the case where a DS replies NFSERR_IO to report I/O problems on the server. Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs_commonkrpc.c projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clrpcops.c Modified: projects/pnfs-planb-server/sys/fs/nfs/nfs_commonkrpc.c ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfs/nfs_commonkrpc.c Sun Jun 10 21:36:29 2018 (r334933) +++ projects/pnfs-planb-server/sys/fs/nfs/nfs_commonkrpc.c Sun Jun 10 22:11:51 2018 (r334934) @@ -810,6 +810,56 @@ tryagain: error = EINTR; } else if (stat == RPC_CANTSEND || stat == RPC_CANTRECV || stat == RPC_SYSTEMERROR) { + if ((nd->nd_flag & ND_NFSV41) != 0 && nmp != NULL && + nd->nd_procnum != NFSPROC_NULL) { + /* + * The nfsess_defunct field is protected by + * the NFSLOCKMNT()/nm_mtx lock and not the + * nfsess_mtx lock to simplify its handling, + * for the MDS session. This lock is also + * sufficient for nfsess_sessionid, since it + * never changes in the structure. + */ + NFSLOCKCLSTATE(); + NFSLOCKMNT(nmp); + /* The session must be marked defunct. */ + if (dssep == NULL) { + /* + * This is either an MDS proxy operation or + * a client mount with "soft,retrans=N" options. + * Mark the MDS session defunct and initiate + * recovery, as required. + */ + NFSCL_DEBUG(1, "Failed soft proxy RPC\n"); + sep = NFSMNT_MDSSESSION(nmp); + if (bcmp(sep->nfsess_sessionid, nd->nd_sequence, + NFSX_V4SESSIONID) == 0) { + /* Initiate recovery. */ + sep->nfsess_defunct = 1; + NFSCL_DEBUG(1, "Marked defunct\n"); + if (nmp->nm_clp != NULL) { + nmp->nm_clp->nfsc_flags |= + NFSCLFLAGS_RECOVER; + wakeup(nmp->nm_clp); + } + } + } else { + /* + * This is a client side DS RPC. Just mark + * the session defunct. A subsequent LayoutGet + * should get a new session. + */ + NFSCL_DEBUG(1, "Failed client DS RPC\n"); + if (bcmp(dssep->nfsess_sessionid, + nd->nd_sequence, NFSX_V4SESSIONID) == 0) { + /* Mark it defunct. */ + dssep->nfsess_defunct = 1; + NFSCL_DEBUG(1, "Marked defunct\n"); + } + } + NFSUNLOCKMNT(nmp); + NFSUNLOCKCLSTATE(); + } NFSINCRGLOBAL(nfsstatsv1.rpcinvalid); error = ENXIO; } else { Modified: projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clrpcops.c Sun Jun 10 21:36:29 2018 (r334933) +++ projects/pnfs-planb-server/sys/fs/nfsclient/nfs_clrpcops.c Sun Jun 10 22:11:51 2018 (r334934) @@ -6040,8 +6040,14 @@ 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); - /* ENXIO indicates a problem with the DS. */ - if (error == ENXIO) { + /* + * ENXIO indicates that the krpc cannot do + * an RPC on the DS. EIO is returned by the + * RPC as an indication of I/O problems on the + * server. + * Are there other fatal errors? + */ + if (error == ENXIO || error == EIO) { NFSCL_DEBUG(4, "DS layreterr for commit\n"); nfscl_dserr(NFSV4OP_COMMIT, dp, lyp); @@ -6065,8 +6071,14 @@ 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 (error == ENXIO) { - /* ENXIO indicates a problem with the DS. */ + if (error == ENXIO || error == EIO) { + /* + * ENXIO indicates that the krpc cannot do + * an RPC on the DS. EIO is returned by the + * RPC as an indication of I/O problems on the + * server. + * Are there other fatal errors? + */ NFSCL_DEBUG(4, "DS layreterr for read\n"); nfscl_dserr(NFSV4OP_READ, dp, lyp); } @@ -6101,8 +6113,14 @@ 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 (error == ENXIO) { - /* ENXIO indicates a DS problem. */ + if (error == ENXIO || error == EIO) { + /* + * ENXIO indicates that the krpc cannot + * do an RPC on the DS. EIO is returned + * by the RPC as an indication of I/O + * problems on the server. + * Are there other fatal errors? + */ NFSCL_DEBUG(4, "DS layreterr for write\n"); nfscl_dserr(NFSV4OP_WRITE, dp, lyp);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201806102211.w5AMBp9o091914>