From owner-svn-src-head@FreeBSD.ORG Sat Nov 9 21:24:57 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 7DE445C1; Sat, 9 Nov 2013 21:24:57 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 6A0402401; Sat, 9 Nov 2013 21:24:57 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rA9LOvn3046657; Sat, 9 Nov 2013 21:24:57 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rA9LOup4046654; Sat, 9 Nov 2013 21:24:56 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <201311092124.rA9LOup4046654@svn.freebsd.org> From: Rick Macklem Date: Sat, 9 Nov 2013 21:24:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r257901 - in head/sys/fs: nfs nfsclient X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 09 Nov 2013 21:24:57 -0000 Author: rmacklem Date: Sat Nov 9 21:24:56 2013 New Revision: 257901 URL: http://svnweb.freebsd.org/changeset/base/257901 Log: Fix an NFSv4.1 client specific case where a forced dismount would hang. The hang occurred in nfsv4_setsequence() when it couldn't find an available session slot and is fixed by checking for a forced dismount in progress and just returning for this case. MFC after: 1 month Modified: head/sys/fs/nfs/nfs_commonsubs.c head/sys/fs/nfs/nfs_var.h head/sys/fs/nfsclient/nfs_clcomsubs.c Modified: head/sys/fs/nfs/nfs_commonsubs.c ============================================================================== --- head/sys/fs/nfs/nfs_commonsubs.c Sat Nov 9 20:36:52 2013 (r257900) +++ head/sys/fs/nfs/nfs_commonsubs.c Sat Nov 9 21:24:56 2013 (r257901) @@ -3693,8 +3693,8 @@ nfsv4_seqsess_cacherep(uint32_t slotid, * Generate the xdr for an NFSv4.1 Sequence Operation. */ APPLESTATIC void -nfsv4_setsequence(struct nfsrv_descript *nd, struct nfsclsession *sep, - int dont_replycache) +nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd, + struct nfsclsession *sep, int dont_replycache) { uint32_t *tl, slotseq = 0; int i, maxslot, slotpos; @@ -3717,9 +3717,21 @@ nfsv4_setsequence(struct nfsrv_descript } bitval <<= 1; } - if (slotpos == -1) + if (slotpos == -1) { + /* + * If a forced dismount is in progress, just return. + * This RPC attempt will fail when it calls + * newnfs_request(). + */ + if ((nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF) + != 0) { + mtx_unlock(&sep->nfsess_mtx); + return; + } + /* Wake up once/sec, to check for a forced dismount. */ (void)mtx_sleep(&sep->nfsess_slots, &sep->nfsess_mtx, - PZERO, "nfsclseq", 0); + PZERO, "nfsclseq", hz); + } } while (slotpos == -1); /* Now, find the highest slot in use. (nfsc_slots is 64bits) */ bitval = 1; Modified: head/sys/fs/nfs/nfs_var.h ============================================================================== --- head/sys/fs/nfs/nfs_var.h Sat Nov 9 20:36:52 2013 (r257900) +++ head/sys/fs/nfs/nfs_var.h Sat Nov 9 21:24:56 2013 (r257901) @@ -265,7 +265,8 @@ int nfsv4_getipaddr(struct nfsrv_descrip int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *, struct mbuf **, uint16_t); void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, struct mbuf *); -void nfsv4_setsequence(struct nfsrv_descript *, struct nfsclsession *, int); +void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *, + struct nfsclsession *, int); void nfsv4_freeslot(struct nfsclsession *, int); /* nfs_clcomsubs.c */ Modified: head/sys/fs/nfsclient/nfs_clcomsubs.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clcomsubs.c Sat Nov 9 20:36:52 2013 (r257900) +++ head/sys/fs/nfsclient/nfs_clcomsubs.c Sat Nov 9 21:24:56 2013 (r257901) @@ -203,10 +203,11 @@ nfscl_reqstart(struct nfsrv_descript *nd NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(NFSV4OP_SEQUENCE); if (sep == NULL) - nfsv4_setsequence(nd, NFSMNT_MDSSESSION(nmp), + nfsv4_setsequence(nmp, nd, + NFSMNT_MDSSESSION(nmp), nfs_bigreply[procnum]); else - nfsv4_setsequence(nd, sep, + nfsv4_setsequence(nmp, nd, sep, nfs_bigreply[procnum]); } if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {