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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to