Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-5]: src/sys pullup from trunk:
details: https://anonhg.NetBSD.org/src/rev/cb68836d2523
branches: netbsd-1-5
changeset: 488368:cb68836d2523
user: fvdl <fvdl%NetBSD.org@localhost>
date: Mon Jul 03 17:34:49 2000 +0000
description:
pullup from trunk:
Fix a "locking against myself" problem; holding ufs_hashlock
across getnewvnode() could cause a recursive lock if it resulted in
recycling a vnode that was using softdeps.
diffstat:
sys/kern/vfs_subr.c | 32 +++++++++++++++++++++++++++++++-
sys/sys/vnode.h | 3 ++-
sys/ufs/ext2fs/ext2fs_vfsops.c | 18 ++++++++++++------
sys/ufs/ffs/ffs_vfsops.c | 22 ++++++++++++++++------
4 files changed, 61 insertions(+), 14 deletions(-)
diffs (143 lines):
diff -r 85fadb45f10d -r cb68836d2523 sys/kern/vfs_subr.c
--- a/sys/kern/vfs_subr.c Mon Jul 03 08:34:44 2000 +0000
+++ b/sys/kern/vfs_subr.c Mon Jul 03 17:34:49 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_subr.c,v 1.128 2000/06/10 18:44:44 sommerfeld Exp $ */
+/* $NetBSD: vfs_subr.c,v 1.128.2.1 2000/07/03 17:36:02 fvdl Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -542,6 +542,36 @@
}
/*
+ * This is really just the reverse of getnewvnode(). Needed for
+ * VFS_VGET functions who may need to push back a vnode in case
+ * of a locking race.
+ */
+void
+ungetnewvnode(vp)
+ struct vnode *vp;
+{
+#ifdef DIAGNOSTIC
+ if (vp->v_usecount != 1)
+ panic("ungetnewvnode: busy vnode");
+#endif
+ vp->v_usecount--;
+ insmntque(vp, NULL);
+ vp->v_type = VBAD;
+
+ simple_lock(&vp->v_interlock);
+ /*
+ * Insert at head of LRU list
+ */
+ simple_lock(&vnode_free_list_slock);
+ if (vp->v_holdcnt > 0)
+ TAILQ_INSERT_HEAD(&vnode_hold_list, vp, v_freelist);
+ else
+ TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
+ simple_unlock(&vnode_free_list_slock);
+ simple_unlock(&vp->v_interlock);
+}
+
+/*
* Move a vnode from one mount queue to another.
*/
void
diff -r 85fadb45f10d -r cb68836d2523 sys/sys/vnode.h
--- a/sys/sys/vnode.h Mon Jul 03 08:34:44 2000 +0000
+++ b/sys/sys/vnode.h Mon Jul 03 17:34:49 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vnode.h,v 1.77 2000/06/10 18:27:05 assar Exp $ */
+/* $NetBSD: vnode.h,v 1.77.2.1 2000/07/03 17:34:49 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -487,6 +487,7 @@
int cdevvp __P((dev_t dev, struct vnode **vpp));
int getnewvnode __P((enum vtagtype tag, struct mount *mp,
int (**vops) __P((void *)), struct vnode **vpp));
+void ungetnewvnode __P((struct vnode *));
int getvnode __P((struct filedesc *fdp, int fd, struct file **fpp));
void vfs_getnewfsid __P((struct mount *));
int speedup_syncer __P((void));
diff -r 85fadb45f10d -r cb68836d2523 sys/ufs/ext2fs/ext2fs_vfsops.c
--- a/sys/ufs/ext2fs/ext2fs_vfsops.c Mon Jul 03 08:34:44 2000 +0000
+++ b/sys/ufs/ext2fs/ext2fs_vfsops.c Mon Jul 03 17:34:49 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_vfsops.c,v 1.36 2000/05/29 18:34:36 mycroft Exp $ */
+/* $NetBSD: ext2fs_vfsops.c,v 1.36.2.1 2000/07/03 17:44:02 fvdl Exp $ */
/*
* Copyright (c) 1997 Manuel Bouyer.
@@ -836,17 +836,23 @@
ump = VFSTOUFS(mp);
dev = ump->um_dev;
- do {
- if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL)
- return (0);
- } while (lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
+
+ if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL)
+ return (0);
/* Allocate a new vnode/inode. */
if ((error = getnewvnode(VT_EXT2FS, mp, ext2fs_vnodeop_p, &vp)) != 0) {
*vpp = NULL;
- lockmgr(&ufs_hashlock, LK_RELEASE, 0);
return (error);
}
+
+ do {
+ if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL) {
+ ungetnewvnode(vp);
+ return (0);
+ }
+ } while (lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
+
ip = pool_get(&ext2fs_inode_pool, PR_WAITOK);
memset((caddr_t)ip, 0, sizeof(struct inode));
vp->v_data = ip;
diff -r 85fadb45f10d -r cb68836d2523 sys/ufs/ffs/ffs_vfsops.c
--- a/sys/ufs/ffs/ffs_vfsops.c Mon Jul 03 08:34:44 2000 +0000
+++ b/sys/ufs/ffs/ffs_vfsops.c Mon Jul 03 17:34:49 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_vfsops.c,v 1.67 2000/06/16 05:45:14 perseant Exp $ */
+/* $NetBSD: ffs_vfsops.c,v 1.67.2.1 2000/07/03 17:44:03 fvdl Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1994
@@ -1008,17 +1008,27 @@
ump = VFSTOUFS(mp);
dev = ump->um_dev;
- do {
- if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL)
- return (0);
- } while (lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
+
+ if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL)
+ return (0);
/* Allocate a new vnode/inode. */
if ((error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp)) != 0) {
*vpp = NULL;
- lockmgr(&ufs_hashlock, LK_RELEASE, 0);
return (error);
}
+
+ /*
+ * If someone beat us to it while sleeping in getnewvnode(),
+ * push back the freshly allocated vnode we don't need, and return.
+ */
+ do {
+ if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL) {
+ ungetnewvnode(vp);
+ return (0);
+ }
+ } while (lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
+
/*
* XXX MFS ends up here, too, to allocate an inode. Should we
* XXX create another pool for MFS inodes?
Home |
Main Index |
Thread Index |
Old Index