Source-Changes-HG archive

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

[src/fvdl-softdep]: src/sys Add workaround hacks to enable the softdep code t...



details:   https://anonhg.NetBSD.org/src/rev/5a3bb2b324a1
branches:  fvdl-softdep
changeset: 477508:5a3bb2b324a1
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Thu Oct 21 19:21:29 1999 +0000

description:
Add workaround hacks to enable the softdep code to call getnewvnode()
when a filesystem is being unmounted. The problem is that the softdep
code stored inode numbers in the worklist structures, and does not
use vnodes. So VFS_VGET must be used to get a vnode during the final
flush stages, and this can call getnewvnode(), resulting in
a vfs_busy() + MNT_UNMOUNT hang.

I've tried to make the softdep code use vnodes, but that's a pain,
since it gets called at points were vnode ops are dangerous (i.e.
interrupt context, and uncertainty whether a vnode is locked, etc).

This is all icky stuff, but it does get things much closer to a
working state..

diffstat:

 sys/kern/vfs_subr.c       |  20 +++++++++++++-------
 sys/kern/vfs_syscalls.c   |   5 ++++-
 sys/sys/mount.h           |   3 ++-
 sys/ufs/ffs/ffs_softdep.c |   4 ----
 4 files changed, 19 insertions(+), 13 deletions(-)

diffs (133 lines):

diff -r c5a5b7a3d683 -r 5a3bb2b324a1 sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c       Tue Oct 19 20:04:03 1999 +0000
+++ b/sys/kern/vfs_subr.c       Thu Oct 21 19:21:29 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_subr.c,v 1.112.4.1 1999/10/19 12:50:07 fvdl Exp $  */
+/*     $NetBSD: vfs_subr.c,v 1.112.4.2 1999/10/21 19:21:29 fvdl Exp $  */
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -212,6 +212,9 @@
                
                if (flags & LK_NOWAIT)
                        return (ENOENT);
+               if ((flags & LK_RECURSEFAIL) && mp->mnt_unmounter != NULL
+                   && mp->mnt_unmounter == curproc)
+                       return (EDEADLK);
                if (interlkp)
                        simple_unlock(interlkp);
                /*
@@ -416,7 +419,7 @@
        struct freelst *listhd;
        static int toggle;
        struct vnode *vp;
-       int error;
+       int error = 0;
 #ifdef DIAGNOSTIC
        int s;
 #endif
@@ -430,8 +433,8 @@
                 * (This puts the per-mount vnode list logically under
                 * the protection of the vfs_busy lock).
                 */
-               error = vfs_busy(mp, 0, 0);
-               if (error)
+               error = vfs_busy(mp, LK_RECURSEFAIL, 0);
+               if (error && error != EDEADLK)
                        return error;
        }
 
@@ -483,7 +486,8 @@
                 */
                if (vp == NULLVP) {
                        simple_unlock(&vnode_free_list_slock);
-                       if (mp) vfs_unbusy(mp);
+                       if (mp && error != EDEADLK)
+                               vfs_unbusy(mp);
                        tablefull("vnode");
                        *vpp = 0;
                        return (ENFILE);
@@ -528,7 +532,8 @@
        vp->v_usecount = 1;
        vp->v_data = 0;
        simple_lock_init(&vp->v_uvm.u_obj.vmobjlock);
-       if (mp) vfs_unbusy(mp);
+       if (mp && error != EDEADLK)
+               vfs_unbusy(mp);
        return (0);
 }
 
@@ -543,7 +548,8 @@
 
 #ifdef DIAGNOSTIC
        if ((mp != NULL) &&
-           (mp->mnt_flag & MNT_UNMOUNT)) {
+           (mp->mnt_flag & MNT_UNMOUNT) &&
+           !(mp->mnt_flag & MNT_SOFTDEP)) {
                panic("insmntque into dying filesystem");
        }
 #endif
diff -r c5a5b7a3d683 -r 5a3bb2b324a1 sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c   Tue Oct 19 20:04:03 1999 +0000
+++ b/sys/kern/vfs_syscalls.c   Thu Oct 21 19:21:29 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_syscalls.c,v 1.147.4.1 1999/10/19 12:50:08 fvdl Exp $      */
+/*     $NetBSD: vfs_syscalls.c,v 1.147.4.2 1999/10/21 19:21:30 fvdl Exp $      */
 
 /*
  * Copyright (c) 1989, 1993
@@ -294,6 +294,7 @@
        vfs->vfs_refcount++;
        mp->mnt_vnodecovered = vp;
        mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
+       mp->mnt_unmounter = NULL;
 update:
        /*
         * Set the mount level flags.
@@ -476,6 +477,7 @@
 
        simple_lock(&mountlist_slock);
        mp->mnt_flag |= MNT_UNMOUNT;
+       mp->mnt_unmounter = p;
        vfs_unbusy(mp);
        lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK, &mountlist_slock);
        if (mp->mnt_flag & MNT_EXPUBLIC)
@@ -494,6 +496,7 @@
                if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL)
                        (void) vfs_allocate_syncvnode(mp);
                mp->mnt_flag &= ~MNT_UNMOUNT;
+               mp->mnt_unmounter = NULL;
                mp->mnt_flag |= async;
                lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE,
                    &mountlist_slock);
diff -r c5a5b7a3d683 -r 5a3bb2b324a1 sys/sys/mount.h
--- a/sys/sys/mount.h   Tue Oct 19 20:04:03 1999 +0000
+++ b/sys/sys/mount.h   Thu Oct 21 19:21:29 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: mount.h,v 1.77.4.1 1999/10/19 12:50:29 fvdl Exp $      */
+/*     $NetBSD: mount.h,v 1.77.4.2 1999/10/21 19:21:31 fvdl Exp $      */
 
 /*
  * Copyright (c) 1989, 1991, 1993
@@ -132,6 +132,7 @@
        struct statfs   mnt_stat;               /* cache of filesystem stats */
        qaddr_t         mnt_data;               /* private data */
        int             mnt_wcnt;               /* count of vfs_busy waiters */
+       struct proc     *mnt_unmounter;         /* who is unmounting */
 };
 
 /*
diff -r c5a5b7a3d683 -r 5a3bb2b324a1 sys/ufs/ffs/ffs_softdep.c
--- a/sys/ufs/ffs/ffs_softdep.c Tue Oct 19 20:04:03 1999 +0000
+++ b/sys/ufs/ffs/ffs_softdep.c Thu Oct 21 19:21:29 1999 +0000
@@ -918,10 +918,6 @@
        int needswap = UFS_FSNEEDSWAP(fs);
 #endif
 
-#if 1
-       printf("%s: enabling softupdates\n", fs->fs_fsmnt);
-#endif
-
        mp->mnt_flag |= MNT_SOFTDEP;
        /*
         * When doing soft updates, the counters in the



Home | Main Index | Thread Index | Old Index