Source-Changes-HG archive

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

[src/trunk]: src/sys/fs/smbfs Don't try to reacquire root vnode if vflush() i...



details:   https://anonhg.NetBSD.org/src/rev/6a06796dc77d
branches:  trunk
changeset: 543500:6a06796dc77d
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Wed Feb 26 20:21:40 2003 +0000

description:
Don't try to reacquire root vnode if vflush() in smbfs_unmount() fails.
This is potentially fragile, since the vnode may have been reclaimed
in vflush(), and used by different filesystem. This wouldn't actually
happen due to n_parent link to parent directory, but better safe
than sorry.

Since sm_root is only and strictly cache to speed up VFS_ROOT(),
it can be acquired/dropped any time. Rearrange code to not
require sm_root set, and change smbfs_root() back to set
sm_root if it's not set yet. smbfs_unmount() now only vrele()s
the root vnode if sm_root is set, and doesn't try reacquire it
if vflush() fails.

problem with vref() after vflush() pointed out by Bill Studenmund

diffstat:

 sys/fs/smbfs/smbfs_vfsops.c |  44 +++++++++++++++++++++++++++-----------------
 1 files changed, 27 insertions(+), 17 deletions(-)

diffs (97 lines):

diff -r 09678ce91a0c -r 6a06796dc77d sys/fs/smbfs/smbfs_vfsops.c
--- a/sys/fs/smbfs/smbfs_vfsops.c       Wed Feb 26 19:31:33 2003 +0000
+++ b/sys/fs/smbfs/smbfs_vfsops.c       Wed Feb 26 20:21:40 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: smbfs_vfsops.c,v 1.21 2003/02/26 18:16:37 jdolecek Exp $       */
+/*     $NetBSD: smbfs_vfsops.c,v 1.22 2003/02/26 20:21:40 jdolecek Exp $       */
 
 /*
  * Copyright (c) 2000-2001, Boris Popov
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.21 2003/02/26 18:16:37 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.22 2003/02/26 20:21:40 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -184,10 +184,6 @@
                ssp->ss_name);
 
        vfs_getnewfsid(mp);
-       error = smbfs_setroot(mp);
-       if (error)
-               goto bad;
-
        return (0);
 
 bad:
@@ -223,14 +219,14 @@
 #ifdef QUOTA
 #endif
        /* Drop the extra reference to root vnode. */
-       KASSERT(smp->sm_root != NULL && SMBTOV(smp->sm_root) != NULL);
-       vrele(SMBTOV(smp->sm_root));
+       if (smp->sm_root) {
+               vrele(SMBTOV(smp->sm_root));
+               smp->sm_root = NULL;
+       }
 
        /* Flush all vnodes. */
-       if ((error = vflush(mp, NULLVP, flags)) != 0) {
-               vref(SMBTOV(smp->sm_root));
+       if ((error = vflush(mp, NULLVP, flags)) != 0)
                return error;
-       }
 
        smb_makescred(&scred, p, p->p_ucred);
        smb_share_lock(smp->sm_share, 0);
@@ -270,11 +266,20 @@
        error = smbfs_nget(mp, NULL, "TheRooT", 7, &fattr, &vp);
        if (error)
                return error;
-       vp->v_flag |= VROOT;
-       smp->sm_root = VTOSMB(vp);
 
-       /* Keep reference, but unlock */
-       VOP_UNLOCK(vp, 0);
+       /*
+        * Someone might have already set sm_root while we slept
+        * in smb_lookup or malloc/getnewvnode.
+        */
+       if (smp->sm_root)
+               vput(vp);
+       else {
+               vp->v_flag |= VROOT;
+               smp->sm_root = VTOSMB(vp);
+
+               /* Keep reference, but unlock */
+               VOP_UNLOCK(vp, 0);
+       }
 
        return (0);
 }
@@ -287,6 +292,13 @@
 {
        struct smbmount *smp = VFSTOSMBFS(mp);
 
+       if (__predict_false(!smp->sm_root)) {
+               int error = smbfs_setroot(mp);
+               if (error)
+                       return (error);
+               /* fallthrough */
+       }
+
        KASSERT(smp->sm_root != NULL && SMBTOV(smp->sm_root) != NULL);
        *vpp = SMBTOV(smp->sm_root);
        return vget(*vpp, LK_EXCLUSIVE | LK_RETRY);
@@ -358,8 +370,6 @@
        struct smb_cred scred;
        int error = 0;
 
-       KASSERT(smp->sm_root != NULL);
-       
        sbp->f_iosize = SSTOVC(ssp)->vc_txmax;          /* optimal transfer block size */
        smb_makescred(&scred, p, p->p_ucred);
 



Home | Main Index | Thread Index | Old Index