Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/lfs Fixes to make dirops and lfs_vflush play togethe...
details: https://anonhg.NetBSD.org/src/rev/c2f674fb52e5
branches: trunk
changeset: 467553:c2f674fb52e5
user: perseant <perseant%NetBSD.org@localhost>
date: Thu Mar 25 22:26:52 1999 +0000
description:
Fixes to make dirops and lfs_vflush play together well. In particular,
if we are short on vnodes, lfs_vflush from another process can grab a
vnode that lfs_markv has already processed but not yet written; but
lfs_markv holds the seglock. When lfs_vflush gets around to writing it,
the context for copyin is gone. So, now lfs_markv calls copyin itself,
rather than having lfs_writeseg do it.
diffstat:
sys/ufs/lfs/lfs_bio.c | 7 ++--
sys/ufs/lfs/lfs_segment.c | 69 ++++++++++++++++++++++++---------------------
sys/ufs/lfs/lfs_syscalls.c | 25 ++++++++--------
3 files changed, 54 insertions(+), 47 deletions(-)
diffs (201 lines):
diff -r 48c03d94e0cb -r c2f674fb52e5 sys/ufs/lfs/lfs_bio.c
--- a/sys/ufs/lfs/lfs_bio.c Thu Mar 25 22:21:09 1999 +0000
+++ b/sys/ufs/lfs/lfs_bio.c Thu Mar 25 22:26:52 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_bio.c,v 1.8 1999/03/25 21:39:18 perseant Exp $ */
+/* $NetBSD: lfs_bio.c,v 1.9 1999/03/25 22:26:52 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -228,7 +228,7 @@
}
ip = VTOI(bp->b_vp);
- if ((bp->b_flags & (B_CALL|B_INVAL)) == (B_CALL|B_INVAL))
+ if (bp->b_flags & B_CALL)
{
if(!(ip->i_flag & IN_CLEANING))
++fs->lfs_uinodes;
@@ -256,9 +256,10 @@
s = splbio();
reassignbuf(bp, bp->b_vp);
splx(s);
+
}
- if((bp->b_flags & (B_CALL|B_INVAL)) == (B_CALL|B_INVAL))
+ if(bp->b_flags & B_CALL)
bp->b_flags &= ~B_BUSY;
else
brelse(bp);
diff -r 48c03d94e0cb -r c2f674fb52e5 sys/ufs/lfs/lfs_segment.c
--- a/sys/ufs/lfs/lfs_segment.c Thu Mar 25 22:21:09 1999 +0000
+++ b/sys/ufs/lfs/lfs_segment.c Thu Mar 25 22:26:52 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_segment.c,v 1.18 1999/03/25 22:02:36 perseant Exp $ */
+/* $NetBSD: lfs_segment.c,v 1.19 1999/03/25 22:26:52 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -186,7 +186,25 @@
struct lfs *fs;
struct segment *sp;
int error;
- struct buf *bp;
+
+ if(ip->i_flag & IN_CLEANING) {
+#ifdef DEBUG_LFS
+ ivndebug(vp,"vflush/in_cleaning");
+#endif
+ ip->i_flag &= ~IN_CLEANING;
+ if(ip->i_flag & IN_MODIFIED) {
+ fs->lfs_uinodes--;
+ } else
+ ip->i_flag |= IN_MODIFIED;
+ }
+
+ /* If the node is being written, wait until that is done */
+ if(WRITEINPROG(vp)) {
+#ifdef DEBUG_LFS
+ ivndebug(vp,"vflush/writeinprog");
+#endif
+ tsleep(vp, PRIBIO+1, "lfs_vw", 0);
+ }
/* Protect against VXLOCK deadlock in vinvalbuf() */
fs = VFSTOUFS(vp->v_mount)->um_lfs;
@@ -203,44 +221,29 @@
ip = VTOI(vp);
if (vp->v_dirtyblkhd.lh_first == NULL) {
lfs_writevnodes(fs, vp->v_mount, sp, VN_EMPTY);
+ } else if((ip->i_flag & IN_CLEANING) && (fs->lfs_sp->seg_flags & SEGM_CLEAN)) {
+#ifdef DEBUG_LFS
+ ivndebug(vp,"vflush/clean");
+#endif
+ lfs_writevnodes(fs, vp->v_mount, sp, VN_CLEAN);
}
else if(lfs_dostats) {
if(vp->v_dirtyblkhd.lh_first || (VTOI(vp)->i_flag & (IN_MODIFIED|IN_UPDATE|IN_ACCESS|IN_CHANGE|IN_CLEANING)))
++lfs_stats.vflush_invoked;
#ifdef DEBUG_LFS
- printf("V");
+ ivndebug(vp,"vflush");
#endif
}
- /* XXX KS - can this ever happen? I think so.... */
- if(ip->i_flag & IN_CLEANING) {
-#ifdef DEBUG_LFS
- printf("C");
+#ifdef DIAGNOSTIC
+ if(vp->v_flag & VDIROP) {
+ panic("VDIROP being freed...this can\'t happen");
+ }
+ if(vp->v_usecount<0) {
+ printf("usecount=%d\n",vp->v_usecount);
+ panic("lfs_vflush: usecount<0");
+ }
#endif
- ip->i_flag &= ~IN_CLEANING;
- /*
- * XXX Copyin all of the fake buffers *now* to avoid
- * a later panic; and take off B_INVAL.
- */
- for(bp=vp->v_dirtyblkhd.lh_first; bp; bp=bp->b_vnbufs.le_next) {
- if((bp->b_flags & (B_CALL|B_INVAL))==(B_CALL|B_INVAL)) {
- bp->b_data = malloc(bp->b_bufsize, M_SEGMENT, M_WAITOK);
- copyin(bp->b_saveaddr, bp->b_data, bp->b_bcount);
- bp->b_flags &= ~B_INVAL;
- }
- }
-
- if(ip->i_flag & IN_MODIFIED) {
- fs->lfs_uinodes--;
-#ifdef DEBUG_LFS
- if((int32_t)fs->lfs_uinodes<0) {
- printf("U4");
- fs->lfs_uinodes=0;
- }
-#endif
- } else
- ip->i_flag |= IN_MODIFIED;
- }
do {
do {
@@ -1248,6 +1251,8 @@
bp->b_flags &= ~B_NEEDCOMMIT;
wakeup(bp);
}
+ /* if(vn->v_dirtyblkhd.lh_first == NULL) */
+ wakeup(vn);
bpp++;
}
++cbp->b_vp->v_numoutput;
@@ -1347,7 +1352,7 @@
struct lfs *fs;
struct buf *bp;
{
- return (bp->b_flags & (B_CALL|B_INVAL))==(B_CALL|B_INVAL);
+ return (bp->b_flags & B_CALL);
}
int
diff -r 48c03d94e0cb -r c2f674fb52e5 sys/ufs/lfs/lfs_syscalls.c
--- a/sys/ufs/lfs/lfs_syscalls.c Thu Mar 25 22:21:09 1999 +0000
+++ b/sys/ufs/lfs/lfs_syscalls.c Thu Mar 25 22:26:52 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lfs_syscalls.c,v 1.24 1999/03/25 21:54:10 perseant Exp $ */
+/* $NetBSD: lfs_syscalls.c,v 1.25 1999/03/25 22:26:52 perseant Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -101,7 +101,6 @@
int clean_vnlocked = 0;
int clean_inlocked = 0;
int verbose_debug = 0;
-int lfs_clean_vnhead = 1;
pid_t lfs_cleaner_pid = 0;
@@ -649,7 +648,7 @@
v_daddr = LFS_UNUSED_DADDR;
need_unlock = 0;
#ifdef DEBUG_LFS
- printf("lfs_bmapv: vget of ino %d failed with %d)",blkp->bi_inode,error);
+ printf("lfs_bmapv: vget of ino %d failed with %d",blkp->bi_inode,error);
#endif
continue;
} else {
@@ -1037,20 +1036,22 @@
caddr_t uaddr;
{
struct buf *bp;
+ int error;
-#ifdef DEBUG
- /* Check for duplicates too */
- if(incore(vp,lbn)) {
- printf("Fake buffer (%d/%d) is in core\n", VTOI(vp)->i_number,
- lbn);
- if(bread(vp, lbn, size, NOCRED, &bp))
- return NULL;
+#ifndef ALLOW_VFLUSH_CORRUPTION
+ bp = lfs_newbuf(vp, lbn, size);
+ error = copyin(uaddr, bp->b_data, size);
+ if(error) {
+ lfs_freebuf(bp);
+ return NULL;
}
-#endif
+#else
bp = lfs_newbuf(vp, lbn, 0);
+ bp->b_flags |= B_INVAL;
bp->b_saveaddr = uaddr;
+#endif
+
bp->b_bufsize = size;
bp->b_bcount = size;
- bp->b_flags |= B_INVAL;
return (bp);
}
Home |
Main Index |
Thread Index |
Old Index