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