From owner-svn-src-stable@FreeBSD.ORG Sun Apr 25 01:56:32 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1392F1065674; Sun, 25 Apr 2010 01:56:32 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0231F8FC0A; Sun, 25 Apr 2010 01:56:32 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o3P1uVVb011235; Sun, 25 Apr 2010 01:56:31 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o3P1uVr9011232; Sun, 25 Apr 2010 01:56:31 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <201004250156.o3P1uVr9011232@svn.freebsd.org> From: Rick Macklem Date: Sun, 25 Apr 2010 01:56:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r207180 - in stable/8/sys/fs: nfs nfsclient X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 25 Apr 2010 01:56:32 -0000 Author: rmacklem Date: Sun Apr 25 01:56:31 2010 New Revision: 207180 URL: http://svn.freebsd.org/changeset/base/207180 Log: MFC: r206818 Avoid extraneous recovery cycles in the experimental NFS client when an NFSv4 server reboots, by doing two things. 1 - Make the function that acquires a stateid for I/O operations block until recovery is complete, so that it doesn't acquire out of date stateids. 2 - Only allow a recovery once every 1/2 of a lease duration, since the NFSv4 server must provide a recovery grace period of at least a lease duration. This should avoid recoveries caused by an out of date stateid that was acquired for an I/O op. just before a recovery cycle started. Modified: stable/8/sys/fs/nfs/nfsclstate.h stable/8/sys/fs/nfsclient/nfs_clstate.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) stable/8/sys/geom/sched/ (props changed) Modified: stable/8/sys/fs/nfs/nfsclstate.h ============================================================================== --- stable/8/sys/fs/nfs/nfsclstate.h Sun Apr 25 01:36:46 2010 (r207179) +++ stable/8/sys/fs/nfs/nfsclstate.h Sun Apr 25 01:56:31 2010 (r207180) @@ -74,6 +74,7 @@ struct nfsclclient { #define NFSCLFLAGS_EXPIREIT 0x0040 #define NFSCLFLAGS_FIRSTDELEG 0x0080 #define NFSCLFLAGS_GOTDELEG 0x0100 +#define NFSCLFLAGS_RECVRINPROG 0x0200 struct nfsclowner { LIST_ENTRY(nfsclowner) nfsow_list; Modified: stable/8/sys/fs/nfsclient/nfs_clstate.c ============================================================================== --- stable/8/sys/fs/nfsclient/nfs_clstate.c Sun Apr 25 01:36:46 2010 (r207179) +++ stable/8/sys/fs/nfsclient/nfs_clstate.c Sun Apr 25 01:56:31 2010 (r207180) @@ -481,6 +481,13 @@ nfscl_getstateid(vnode_t vp, u_int8_t *n } /* + * Wait for recovery to complete. + */ + while ((clp->nfsc_flags & NFSCLFLAGS_RECVRINPROG)) + (void) nfsmsleep(&clp->nfsc_flags, NFSCLSTATEMUTEXPTR, + PZERO, "nfsrecvr", NULL); + + /* * First, look for a delegation. */ LIST_FOREACH(dp, NFSCLDELEGHASH(clp, nfhp, fhlen), nfsdl_hash) { @@ -1778,6 +1785,7 @@ nfscl_recover(struct nfsclclient *clp, s * block when trying to use state. */ NFSLOCKCLSTATE(); + clp->nfsc_flags |= NFSCLFLAGS_RECVRINPROG; do { igotlock = nfsv4_lock(&clp->nfsc_lock, 1, NULL, NFSCLSTATEMUTEXPTR); @@ -1794,9 +1802,10 @@ nfscl_recover(struct nfsclclient *clp, s error == NFSERR_STALEDONTRECOVER) && --trycnt > 0); if (error) { nfscl_cleanclient(clp); - clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID | - NFSCLFLAGS_RECOVER); NFSLOCKCLSTATE(); + clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID | + NFSCLFLAGS_RECOVER | NFSCLFLAGS_RECVRINPROG); + wakeup(&clp->nfsc_flags); nfsv4_unlock(&clp->nfsc_lock, 0); NFSUNLOCKCLSTATE(); return; @@ -2057,6 +2066,8 @@ nfscl_recover(struct nfsclclient *clp, s } NFSLOCKCLSTATE(); + clp->nfsc_flags &= ~NFSCLFLAGS_RECVRINPROG; + wakeup(&clp->nfsc_flags); nfsv4_unlock(&clp->nfsc_lock, 0); NFSUNLOCKCLSTATE(); NFSFREECRED(tcred); @@ -2316,6 +2327,7 @@ nfscl_renewthread(struct nfsclclient *cl struct ucred *cred; u_int32_t clidrev; int error, cbpathdown, islept, igotlock, ret, clearok; + uint32_t recover_done_time = 0; cred = newnfs_getcred(); NFSLOCKCLSTATE(); @@ -2324,8 +2336,21 @@ nfscl_renewthread(struct nfsclclient *cl for(;;) { newnfs_setroot(cred); cbpathdown = 0; - if (clp->nfsc_flags & NFSCLFLAGS_RECOVER) - nfscl_recover(clp, cred, p); + if (clp->nfsc_flags & NFSCLFLAGS_RECOVER) { + /* + * Only allow one recover within 1/2 of the lease + * duration (nfsc_renew). + */ + if (recover_done_time < NFSD_MONOSEC) { + recover_done_time = NFSD_MONOSEC + + clp->nfsc_renew; + nfscl_recover(clp, cred, p); + } else { + NFSLOCKCLSTATE(); + clp->nfsc_flags &= ~NFSCLFLAGS_RECOVER; + NFSUNLOCKCLSTATE(); + } + } if (clp->nfsc_expire <= NFSD_MONOSEC && (clp->nfsc_flags & NFSCLFLAGS_HASCLIENTID)) { clp->nfsc_expire = NFSD_MONOSEC + clp->nfsc_renew;