Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 May 2012 22:20:55 +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: r235381 - head/sys/fs/nfsserver
Message-ID:  <201205122220.q4CMKt7n055102@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Sat May 12 22:20:55 2012
New Revision: 235381
URL: http://svn.freebsd.org/changeset/base/235381

Log:
  Fix two cases in the new NFS server where a tsleep() is
  used, when the code should actually protect the tested
  variable with a mutex. Since the tsleep()s had a 10sec
  timeout, the race would have only delayed the allocation
  of a new clientid for a client. The sleeps will also
  rarely occur, since having a callback in progress when
  a client acquires a new clientid, is unlikely.
  in practice, since having a callback in progress when
  a fresh clientid is being acquired by a client is unlikely.
  
  MFC after:	1 month

Modified:
  head/sys/fs/nfsserver/nfs_nfsdstate.c

Modified: head/sys/fs/nfsserver/nfs_nfsdstate.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdstate.c	Sat May 12 21:25:48 2012	(r235380)
+++ head/sys/fs/nfsserver/nfs_nfsdstate.c	Sat May 12 22:20:55 2012	(r235381)
@@ -331,11 +331,13 @@ nfsrv_setclient(struct nfsrv_descript *n
 		 * Must wait until any outstanding callback on the old clp
 		 * completes.
 		 */
+		NFSLOCKSTATE();
 		while (clp->lc_cbref) {
 			clp->lc_flags |= LCL_WAKEUPWANTED;
-			(void) tsleep((caddr_t)clp, PZERO - 1,
+			(void)mtx_sleep(clp, NFSSTATEMUTEXPTR, PZERO - 1,
 			    "nfsd clp", 10 * hz);
 		}
+		NFSUNLOCKSTATE();
 		nfsrv_zapclient(clp, p);
 		*new_clpp = NULL;
 		goto out;
@@ -385,10 +387,13 @@ nfsrv_setclient(struct nfsrv_descript *n
 	 * Must wait until any outstanding callback on the old clp
 	 * completes.
 	 */
+	NFSLOCKSTATE();
 	while (clp->lc_cbref) {
 		clp->lc_flags |= LCL_WAKEUPWANTED;
-		(void) tsleep((caddr_t)clp, PZERO - 1, "nfsd clp", 10 * hz);
+		(void)mtx_sleep(clp, NFSSTATEMUTEXPTR, PZERO - 1, "nfsd clp",
+		    10 * hz);
 	}
+	NFSUNLOCKSTATE();
 	nfsrv_zapclient(clp, p);
 	*new_clpp = NULL;
 
@@ -3816,11 +3821,9 @@ nfsrv_docallback(struct nfsclient *clp, 
 	clp->lc_cbref--;
 	if ((clp->lc_flags & LCL_WAKEUPWANTED) && clp->lc_cbref == 0) {
 		clp->lc_flags &= ~LCL_WAKEUPWANTED;
-		NFSUNLOCKSTATE();
-		wakeup((caddr_t)clp);
-	} else {
-		NFSUNLOCKSTATE();
+		wakeup(clp);
 	}
+	NFSUNLOCKSTATE();
 
 	NFSEXITCODE(error);
 	return (error);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205122220.q4CMKt7n055102>