Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/lfs Changes to stabilize LFS. The first two of thes...
details: https://anonhg.NetBSD.org/src/rev/a588e66ddd60
branches: trunk
changeset: 480735:a588e66ddd60
user: perseant <perseant%NetBSD.org@localhost>
date: Wed Jan 19 00:03:04 2000 +0000
description:
Changes to stabilize LFS. The first two of these should also apply to the
1.4 branch.
* Use a separate per-fs lock, instead of ufs_hashlock, to protect the Inode
free list. This seems to prevent the "lockmgr: %d, not exclusive lock holder
%d, unlocking" message I was mis-attributing last night to an unlocked vnode
being passed to vrele.
* Change calling semantics of lfs_ifind, to give better error reporting:
If fed a struct buf, it can report the block number of the offending inode
block as well as the inode number.
* Back out rev 1.10 of lfs_subr.c, since the replacement code was slightly
uglier while being functionally identical.
* Make lfs_vunref use the same free list convention as vrele/vput, so that
vget does not remove vnodes from a hash list they are not on.
diffstat:
sys/ufs/lfs/lfs.h | 3 ++-
sys/ufs/lfs/lfs_alloc.c | 24 ++++++++++--------------
sys/ufs/lfs/lfs_extern.h | 4 ++--
sys/ufs/lfs/lfs_inode.c | 9 ++++++---
sys/ufs/lfs/lfs_segment.c | 7 +++++--
sys/ufs/lfs/lfs_subr.c | 9 ++++-----
sys/ufs/lfs/lfs_syscalls.c | 4 ++--
sys/ufs/lfs/lfs_vfsops.c | 5 +++--
8 files changed, 34 insertions(+), 31 deletions(-)
diffs (248 lines):
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs.h
--- a/sys/ufs/lfs/lfs.h Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs.h Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs.h,v 1.19 1999/12/15 07:10:34 perseant Exp $ */
+/* $NetBSD: lfs.h,v 1.20 2000/01/19 00:03:04 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -314,6 +314,7 @@
#endif
struct vnode *lfs_flushvp; /* vnode being flushed */
u_int32_t lfs_diropwait; /* # procs waiting on dirop flush */
+ struct lock lfs_freelock;
};
/*
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_alloc.c
--- a/sys/ufs/lfs/lfs_alloc.c Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_alloc.c Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_alloc.c,v 1.30 1999/12/15 07:19:07 perseant Exp $ */
+/* $NetBSD: lfs_alloc.c,v 1.31 2000/01/19 00:03:04 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -122,11 +122,9 @@
fs = VTOI(ap->a_pvp)->i_lfs;
/*
- * Prevent a race getting lfs_free. We use
- * the ufs_hashlock here because we need that anyway for
- * the hash insertion later.
+ * Prevent a race getting lfs_free.
*/
- lockmgr(&ufs_hashlock, LK_EXCLUSIVE, 0);
+ lockmgr(&fs->lfs_freelock, LK_EXCLUSIVE, 0);
/* Get the head of the freelist. */
new_ino = fs->lfs_free;
@@ -164,8 +162,9 @@
ip = VTOI(vp);
blkno = lblkno(fs, ip->i_ffs_size);
if ((error = VOP_BALLOC(vp, ip->i_ffs_size, fs->lfs_bsize,
- NULL, 0, &bp)) != 0)
+ NULL, 0, &bp)) != 0) {
return (error);
+ }
ip->i_ffs_size += fs->lfs_bsize;
uvm_vnp_setsize(vp, ip->i_ffs_size);
(void)uvm_vnp_uncache(vp);
@@ -187,16 +186,17 @@
ifp->if_nextfree = LFS_UNUSED_INUM;
VOP_UNLOCK(vp,0);
if ((error = VOP_BWRITE(bp)) != 0) {
- lockmgr(&ufs_hashlock, LK_RELEASE, 0);
return (error);
}
}
-
#ifdef DIAGNOSTIC
if(fs->lfs_free == LFS_UNUSED_INUM)
panic("inode 0 allocated [3]");
#endif /* DIAGNOSTIC */
+ lockmgr(&fs->lfs_freelock, LK_RELEASE, 0);
+
+ lockmgr(&ufs_hashlock, LK_EXCLUSIVE, 0);
/* Create a vnode to associate with the inode. */
if ((error = lfs_vcreate(ap->a_pvp->v_mount, new_ino, &vp)) != 0) {
lockmgr(&ufs_hashlock, LK_RELEASE, 0);
@@ -301,7 +301,6 @@
struct lfs *fs;
ufs_daddr_t old_iaddr;
ino_t ino;
- int already_locked;
extern int lfs_dirvcount;
/* Get the inode number and file system. */
@@ -310,11 +309,9 @@
fs = ip->i_lfs;
ino = ip->i_number;
- /* If we already hold ufs_hashlock, don't panic, just do it anyway */
- already_locked = lockstatus(&ufs_hashlock) && ufs_hashlock.lk_lockholder == curproc->p_pid;
while(WRITEINPROG(vp)
|| fs->lfs_seglock
- || (!already_locked && lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0)))
+ || lockmgr(&fs->lfs_freelock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0))
{
if (WRITEINPROG(vp)) {
tsleep(vp, (PRIBIO+1), "lfs_vfree", 0);
@@ -376,8 +373,7 @@
sup->su_nbytes -= DINODE_SIZE;
(void) VOP_BWRITE(bp);
}
- if(!already_locked)
- lockmgr(&ufs_hashlock, LK_RELEASE, 0);
+ lockmgr(&fs->lfs_freelock, LK_RELEASE, 0);
/* Set superblock modified bit and decrement file count. */
fs->lfs_fmod = 1;
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_extern.h
--- a/sys/ufs/lfs/lfs_extern.h Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_extern.h Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_extern.h,v 1.15 1999/11/15 18:49:14 fvdl Exp $ */
+/* $NetBSD: lfs_extern.h,v 1.16 2000/01/19 00:03:04 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
/* lfs_inode.c */
void lfs_init __P((void));
-struct dinode *lfs_ifind __P((struct lfs *, ino_t, struct dinode *));
+struct dinode *lfs_ifind __P((struct lfs *, ino_t, struct buf *));
/* lfs_segment.c */
void lfs_imtime __P((struct lfs *));
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_inode.c
--- a/sys/ufs/lfs/lfs_inode.c Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_inode.c Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_inode.c,v 1.29 2000/01/16 05:56:14 perseant Exp $ */
+/* $NetBSD: lfs_inode.c,v 1.30 2000/01/19 00:03:04 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -98,18 +98,21 @@
/* Search a block for a specific dinode. */
struct dinode *
-lfs_ifind(fs, ino, dip)
+lfs_ifind(fs, ino, bp)
struct lfs *fs;
ino_t ino;
- register struct dinode *dip;
+ struct buf *bp;
{
register int cnt;
+ register struct dinode *dip = (struct dinode *)bp->b_data;
register struct dinode *ldip;
for (cnt = INOPB(fs), ldip = dip + (cnt - 1); cnt--; --ldip)
if (ldip->di_inumber == ino)
return (ldip);
+ printf("offset is %d (seg %d)\n", fs->lfs_offset, datosn(fs,fs->lfs_offset));
+ printf("block is %d (seg %d)\n", bp->b_blkno, datosn(fs,bp->b_blkno));
panic("lfs_ifind: dinode %u not found", ino);
/* NOTREACHED */
}
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_segment.c
--- a/sys/ufs/lfs/lfs_segment.c Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_segment.c Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_segment.c,v 1.39 2000/01/16 05:56:14 perseant Exp $ */
+/* $NetBSD: lfs_segment.c,v 1.40 2000/01/19 00:03:04 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -1679,7 +1679,10 @@
* insert at tail of LRU list
*/
simple_lock(&vnode_free_list_slock);
- TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
+ if (vp->v_holdcnt > 0)
+ TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
+ else
+ TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
simple_unlock(&vnode_free_list_slock);
simple_unlock(&vp->v_interlock);
}
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_subr.c
--- a/sys/ufs/lfs/lfs_subr.c Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_subr.c Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_subr.c,v 1.11 2000/01/16 09:15:51 perseant Exp $ */
+/* $NetBSD: lfs_subr.c,v 1.12 2000/01/19 00:03:05 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -203,7 +203,7 @@
for (; vp && vp != BEG_OF_VLIST; vp = BACK_VP(vp)) {
#else
loop:
- for (vp = mp->mnt_vnodelist.lh_first;
+ for (vp = mp->mnt_vnodelist.lh_first;
vp != NULL;
vp = vp->v_mntvnodes.le_next) {
#endif
@@ -217,9 +217,8 @@
vp->v_flag &= ~VDIROP;
wakeup(&lfs_dirvcount);
if(vp->v_usecount == 1) {
- /* vput will VOP_INACTIVE */
- VOP_LOCK(vp,LK_EXCLUSIVE);
- vput(vp);
+ /* vrele may call VOP_INACTIVE */
+ vrele(vp);
} else
lfs_vunref(vp);
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_syscalls.c
--- a/sys/ufs/lfs/lfs_syscalls.c Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_syscalls.c Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_syscalls.c,v 1.39 2000/01/16 04:57:08 perseant Exp $ */
+/* $NetBSD: lfs_syscalls.c,v 1.40 2000/01/19 00:03:05 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -993,7 +993,7 @@
return (error);
}
ip->i_din.ffs_din =
- *lfs_ifind(ump->um_lfs, ino, (struct dinode *)bp->b_data);
+ *lfs_ifind(ump->um_lfs, ino, bp);
brelse(bp);
}
ip->i_ffs_effnlink = ip->i_ffs_nlink;
diff -r c6802a7373c6 -r a588e66ddd60 sys/ufs/lfs/lfs_vfsops.c
--- a/sys/ufs/lfs/lfs_vfsops.c Tue Jan 18 22:43:23 2000 +0000
+++ b/sys/ufs/lfs/lfs_vfsops.c Wed Jan 19 00:03:04 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_vfsops.c,v 1.45 1999/11/21 19:25:32 perseant Exp $ */
+/* $NetBSD: lfs_vfsops.c,v 1.46 2000/01/19 00:03:05 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -417,6 +417,7 @@
fs->lfs_writer = 0;
fs->lfs_dirops = 0;
fs->lfs_seglock = 0;
+ lockinit(&fs->lfs_freelock, PINOD, "lfs_freelock", 0, 0);
/* Set the file system readonly/modify bits. */
fs->lfs_ronly = ronly;
@@ -716,7 +717,7 @@
*vpp = NULL;
return (error);
}
- ip->i_din.ffs_din = *lfs_ifind(fs, ino, (struct dinode *)bp->b_data);
+ ip->i_din.ffs_din = *lfs_ifind(fs, ino, bp);
ip->i_ffs_effnlink = ip->i_ffs_nlink;
#ifdef LFS_ATIME_IFILE
ip->i_ffs_atime = ts.tv_sec;
Home |
Main Index |
Thread Index |
Old Index