Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys When unmounting a file system, acquire the syncer_lock b...



details:   https://anonhg.NetBSD.org/src/rev/2bc8bd96ae21
branches:  trunk
changeset: 508656:2bc8bd96ae21
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Mon Apr 16 22:41:09 2001 +0000

description:
When unmounting a file system, acquire the syncer_lock before
vfs_busy'ing just before the dounmount() call.  This is to avoid
sleeping with the mountlist_slock held -- but we must acquire
syncer_lock before vfs_busy because the syncer itself uses
syncer_lock -> vfs_busy locking order.

diffstat:

 sys/coda/coda_psdev.c    |  13 +++++++++++--
 sys/kern/vfs_subr.c      |  11 +++++++++--
 sys/kern/vfs_syscalls.c  |  32 ++++++++++++++++++++++++--------
 sys/nfs/nfs_nqlease.c    |  14 +++++++++++---
 sys/ufs/mfs/mfs_vfsops.c |  14 +++++++++++---
 5 files changed, 66 insertions(+), 18 deletions(-)

diffs (187 lines):

diff -r ee209edd9858 -r 2bc8bd96ae21 sys/coda/coda_psdev.c
--- a/sys/coda/coda_psdev.c     Mon Apr 16 21:36:58 2001 +0000
+++ b/sys/coda/coda_psdev.c     Mon Apr 16 22:41:09 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: coda_psdev.c,v 1.15 2000/12/27 22:06:07 jdolecek Exp $ */
+/*     $NetBSD: coda_psdev.c,v 1.16 2001/04/16 22:41:09 thorpej Exp $  */
 
 /*
  * 
@@ -70,6 +70,8 @@
 #include <sys/poll.h>
 #include <sys/select.h>
 
+#include <miscfs/syncfs/syncfs.h>
+
 #include <coda/coda.h>
 #include <coda/cnode.h>
 #include <coda/coda_namecache.h>
@@ -184,9 +186,16 @@
     }
 
     /* Let unmount know this is for real */
+    /*
+     * XXX Freeze syncer.  Must do this before locking the
+     * mount point.  See dounmount for details().
+     */
+    lockmgr(&syncer_lock, LK_EXCLUSIVE, NULL);
     VTOC(mi->mi_rootvp)->c_flags |= C_UNMOUNTING;
-    if (vfs_busy(mi->mi_vfsp, 0, 0))
+    if (vfs_busy(mi->mi_vfsp, 0, 0)) {
+       lockmgr(&syncer_lock, LK_RELEASE, NULL);
        return (EBUSY);
+    }
     coda_unmounting(mi->mi_vfsp);
     
     /* Wakeup clients so they can return. */
diff -r ee209edd9858 -r 2bc8bd96ae21 sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c       Mon Apr 16 21:36:58 2001 +0000
+++ b/sys/kern/vfs_subr.c       Mon Apr 16 22:41:09 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_subr.c,v 1.148 2001/04/09 14:14:10 enami Exp $     */
+/*     $NetBSD: vfs_subr.c,v 1.149 2001/04/16 22:41:10 thorpej Exp $   */
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -2394,8 +2394,15 @@
                printf("unmounting %s (%s)...\n",
                    mp->mnt_stat.f_mntonname, mp->mnt_stat.f_mntfromname);
 #endif
-               if (vfs_busy(mp, 0, 0))
+               /*
+                * XXX Freeze syncer.  Must do this before locking the
+                * mount point.  See dounmount() for details.
+                */
+               lockmgr(&syncer_lock, LK_EXCLUSIVE, NULL);
+               if (vfs_busy(mp, 0, 0)) {
+                       lockmgr(&syncer_lock, LK_RELEASE, NULL);
                        continue;
+               }
                if ((error = dounmount(mp, MNT_FORCE, p)) != 0) {
                        printf("unmount of %s failed with error %d\n",
                            mp->mnt_stat.f_mntonname, error);
diff -r ee209edd9858 -r 2bc8bd96ae21 sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c   Mon Apr 16 21:36:58 2001 +0000
+++ b/sys/kern/vfs_syscalls.c   Mon Apr 16 22:41:09 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_syscalls.c,v 1.164 2000/11/27 08:39:44 chs Exp $   */
+/*     $NetBSD: vfs_syscalls.c,v 1.165 2001/04/16 22:41:11 thorpej Exp $       */
 
 /*
  * Copyright (c) 1989, 1993
@@ -459,8 +459,16 @@
        }
        vput(vp);
 
-       if (vfs_busy(mp, 0, 0))
+       /*
+        * XXX Freeze syncer.  Must do this before locking the
+        * mount point.  See dounmount() for details.
+        */
+       lockmgr(&syncer_lock, LK_EXCLUSIVE, NULL);
+
+       if (vfs_busy(mp, 0, 0)) {
+               lockmgr(&syncer_lock, LK_RELEASE, NULL);
                return (EBUSY);
+       }
 
        return (dounmount(mp, SCARG(uap, flags), p));
 }
@@ -485,13 +493,21 @@
        used_syncer = (mp->mnt_syncer != NULL);
 
        /*
-        * XXX Freeze syncer. This should really be done on a mountpoint
-        * basis, but especially the softdep code possibly called from
-        * the syncer doesn't exactly work on a per-mountpoint basis,
-        * so the softdep code would become a maze of vfs_busy calls.
+        * XXX Syncer must be frozen when we get here.  This should really
+        * be done on a per-mountpoint basis, but especially the softdep
+        * code possibly called from the syncer doens't exactly work on a
+        * per-mountpoint basis, so the softdep code would become a maze
+        * of vfs_busy() calls.
+        *
+        * The caller of dounmount() must acquire syncer_lock because
+        * the syncer itself acquires locks in syncer_lock -> vfs_busy
+        * order, and we must preserve that order to avoid deadlock.
+        *
+        * So, if the file system did not use the syncer, now is
+        * the time to release the syncer_lock.
         */
-       if (used_syncer)
-               lockmgr(&syncer_lock, LK_EXCLUSIVE, NULL);
+       if (used_syncer == 0)
+               lockmgr(&syncer_lock, LK_RELEASE, NULL);
 
        mp->mnt_flag |= MNT_UNMOUNT;
        mp->mnt_unmounter = p;
diff -r ee209edd9858 -r 2bc8bd96ae21 sys/nfs/nfs_nqlease.c
--- a/sys/nfs/nfs_nqlease.c     Mon Apr 16 21:36:58 2001 +0000
+++ b/sys/nfs/nfs_nqlease.c     Mon Apr 16 22:41:09 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfs_nqlease.c,v 1.37 2001/02/21 21:39:57 jdolecek Exp $        */
+/*     $NetBSD: nfs_nqlease.c,v 1.38 2001/04/16 22:41:11 thorpej Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -73,6 +73,8 @@
 #include <sys/protosw.h>
 #include <sys/signalvar.h>
 
+#include <miscfs/syncfs/syncfs.h>
+
 #include <netinet/in.h>
 #include <nfs/rpcv2.h>
 #include <nfs/nfsproto.h>
@@ -1049,8 +1051,14 @@
        sleepreturn = 0;
        while ((nmp->nm_iflag & NFSMNT_DISMNT) == 0) {
            if (sleepreturn == EINTR || sleepreturn == ERESTART) {
-               if (vfs_busy(nmp->nm_mountp, LK_NOWAIT, 0) == 0 &&
-                   dounmount(nmp->nm_mountp, 0, p) != 0)
+               /*
+                * XXX Freeze syncer.  Must do this before locking
+                * the mount point.  See dounmount() for details.
+                */
+               lockmgr(&syncer_lock, LK_EXCLUSIVE, NULL);
+               if (vfs_busy(nmp->nm_mountp, LK_NOWAIT, 0) != 0)
+                       lockmgr(&syncer_lock, LK_EXCLUSIVE, NULL);
+               else if (dounmount(nmp->nm_mountp, 0, p) != 0)
                        CLRSIG(p, CURSIG(p));
                sleepreturn = 0;
                continue;
diff -r ee209edd9858 -r 2bc8bd96ae21 sys/ufs/mfs/mfs_vfsops.c
--- a/sys/ufs/mfs/mfs_vfsops.c  Mon Apr 16 21:36:58 2001 +0000
+++ b/sys/ufs/mfs/mfs_vfsops.c  Mon Apr 16 22:41:09 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mfs_vfsops.c,v 1.32 2001/02/24 00:05:22 cgd Exp $      */
+/*     $NetBSD: mfs_vfsops.c,v 1.33 2001/04/16 22:41:12 thorpej Exp $  */
 
 /*
  * Copyright (c) 1989, 1990, 1993, 1994
@@ -50,6 +50,8 @@
 #include <sys/vnode.h>
 #include <sys/malloc.h>
 
+#include <miscfs/syncfs/syncfs.h>
+
 #include <ufs/ufs/quota.h>
 #include <ufs/ufs/inode.h>
 #include <ufs/ufs/ufsmount.h>
@@ -317,8 +319,14 @@
                 * will always return EINTR/ERESTART.
                 */
                if (sleepreturn != 0) {
-                       if (vfs_busy(mp, LK_NOWAIT, 0) ||
-                           dounmount(mp, 0, p) != 0)
+                       /*
+                        * XXX Freeze syncer.  Must do this before locking
+                        * the mount point.  See dounmount() for details.
+                        */
+                       lockmgr(&syncer_lock, LK_EXCLUSIVE, NULL);
+                       if (vfs_busy(mp, LK_NOWAIT, 0) != 0)
+                               lockmgr(&syncer_lock, LK_RELEASE, NULL);
+                       else if (dounmount(mp, 0, p) != 0)
                                CLRSIG(p, CURSIG(p));
                        sleepreturn = 0;
                        continue;



Home | Main Index | Thread Index | Old Index