Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Fixes to the softdep code from Ethan Solomita <ethan@geocast...
details: https://anonhg.NetBSD.org/src/rev/9a811d22dd25
branches: trunk
changeset: 482127:9a811d22dd25
user: fvdl <fvdl%NetBSD.org@localhost>
date: Mon Feb 14 22:00:21 2000 +0000
description:
Fixes to the softdep code from Ethan Solomita <ethan%geocast.com@localhost>.
* Fix buffer ordering when it has dependencies.
* Alleviate memory problems.
* Deal with some recursive vnode locks (sigh).
* Fix other bugs.
diffstat:
gnu/sys/ufs/ffs/ffs_softdep.c | 672 ++++++++++++++++++++++++++--------------
sys/kern/vfs_vnops.c | 30 +-
sys/sys/buf.h | 4 +-
sys/sys/vnode.h | 4 +-
sys/ufs/ffs/ffs_alloc.c | 4 +-
sys/ufs/ffs/ffs_balloc.c | 11 +-
sys/ufs/ffs/ffs_extern.h | 7 +-
sys/ufs/ffs/ffs_softdep.stub.c | 13 +-
sys/ufs/ffs/ffs_vfsops.c | 10 +-
sys/ufs/ufs/ufs_extern.h | 4 +-
sys/ufs/ufs/ufs_lookup.c | 27 +-
sys/ufs/ufs/ufs_vnops.c | 74 +++-
12 files changed, 570 insertions(+), 290 deletions(-)
diffs (truncated from 1767 to 300 lines):
diff -r afaf393d418b -r 9a811d22dd25 gnu/sys/ufs/ffs/ffs_softdep.c
--- a/gnu/sys/ufs/ffs/ffs_softdep.c Mon Feb 14 21:46:26 2000 +0000
+++ b/gnu/sys/ufs/ffs/ffs_softdep.c Mon Feb 14 22:00:21 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_softdep.c,v 1.5 1999/12/05 20:34:40 fvdl Exp $ */
+/* $NetBSD: ffs_softdep.c,v 1.6 2000/02/14 22:01:38 fvdl Exp $ */
/*
* Copyright 1998 Marshall Kirk McKusick. All Rights Reserved.
@@ -54,7 +54,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * from: @(#)ffs_softdep.c 9.40 (McKusick) 6/15/99
+ * from: @(#)ffs_softdep.c 9.56 (McKusick) 1/17/00
*/
/*
@@ -117,6 +117,7 @@
* Finding the current process.
*/
#define CURPROC curproc
+#define CURPROC_PID (curproc ? curproc->p_pid : 0)
/*
* End system adaptaion definitions.
*/
@@ -143,7 +144,7 @@
static void handle_workitem_freefile __P((struct freefile *));
static void handle_workitem_remove __P((struct dirrem *));
static struct dirrem *newdirrem __P((struct buf *, struct inode *,
- struct inode *, int));
+ struct inode *, int, struct dirrem **));
static void free_diradd __P((struct diradd *));
static void free_allocindir __P((struct allocindir *, struct inodedep *));
static int indir_trunc __P((struct inode *, ufs_daddr_t, int, ufs_lbn_t,
@@ -151,6 +152,7 @@
static void deallocate_dependencies __P((struct buf *, struct inodedep *));
static void free_allocdirect __P((struct allocdirectlst *,
struct allocdirect *, int));
+static int check_inode_unwritten __P((struct inodedep *));
static int free_inodedep __P((struct inodedep *));
static void handle_workitem_freeblocks __P((struct freeblks *));
static void merge_inode_lists __P((struct inodedep *));
@@ -175,12 +177,22 @@
/*
* Exported softdep operations.
*/
+static void softdep_disk_io_initiation __P((struct buf *));
+static void softdep_disk_write_complete __P((struct buf *));
+static void softdep_deallocate_dependencies __P((struct buf *));
+static int softdep_fsync __P((struct vnode *));
+static int softdep_process_worklist __P((struct mount *));
+static void softdep_move_dependencies __P((struct buf *, struct buf *));
+static int softdep_count_dependencies __P((struct buf *bp, int));
+
struct bio_ops bioops = {
softdep_disk_io_initiation, /* io_start */
softdep_disk_write_complete, /* io_complete */
softdep_deallocate_dependencies, /* io_deallocate */
softdep_fsync, /* io_fsync */
softdep_process_worklist, /* io_sync */
+ softdep_move_dependencies, /* io_movedeps */
+ softdep_count_dependencies, /* io_countdeps */
};
/*
@@ -204,8 +216,8 @@
} lk = { 0 };
#define ACQUIRE_LOCK(lk) (lk)->lkt_spl = splbio()
#define FREE_LOCK(lk) splx((lk)->lkt_spl)
-#define ACQUIRE_LOCK_INTERLOCKED(lk)
-#define FREE_LOCK_INTERLOCKED(lk)
+#define ACQUIRE_LOCK_INTERLOCKED(lk, s) (lk)->lkt_spl = s
+#define FREE_LOCK_INTERLOCKED(lk) (lk)->lkt_spl
#else /* DEBUG */
static struct lockit {
@@ -216,27 +228,26 @@
static void acquire_lock __P((struct lockit *));
static void free_lock __P((struct lockit *));
-static void acquire_lock_interlocked __P((struct lockit *));
-static void free_lock_interlocked __P((struct lockit *));
+static void acquire_lock_interlocked __P((struct lockit *, int));
+static int free_lock_interlocked __P((struct lockit *));
#define ACQUIRE_LOCK(lk) acquire_lock(lk)
#define FREE_LOCK(lk) free_lock(lk)
-#define ACQUIRE_LOCK_INTERLOCKED(lk) acquire_lock_interlocked(lk)
+#define ACQUIRE_LOCK_INTERLOCKED(lk, s) acquire_lock_interlocked(lk, s)
#define FREE_LOCK_INTERLOCKED(lk) free_lock_interlocked(lk)
static void
acquire_lock(lk)
struct lockit *lk;
{
-
if (lk->lkt_held != -1) {
- if (lk->lkt_held == CURPROC->p_pid)
+ if (lk->lkt_held == CURPROC_PID)
panic("softdep_lock: locking against myself");
else
panic("softdep_lock: lock held by %d", lk->lkt_held);
}
lk->lkt_spl = splbio();
- lk->lkt_held = CURPROC->p_pid;
+ lk->lkt_held = CURPROC_PID;
lockcnt++;
}
@@ -252,29 +263,30 @@
}
static void
-acquire_lock_interlocked(lk)
+acquire_lock_interlocked(lk, s)
struct lockit *lk;
+ int s;
{
-
if (lk->lkt_held != -1) {
- if (lk->lkt_held == CURPROC->p_pid)
+ if (lk->lkt_held == CURPROC_PID)
panic("softdep_lock_interlocked: locking against self");
else
panic("softdep_lock_interlocked: lock held by %d",
lk->lkt_held);
}
- lk->lkt_held = CURPROC->p_pid;
+ lk->lkt_spl = s;
+ lk->lkt_held = CURPROC_PID;
lockcnt++;
}
-static void
+static int
free_lock_interlocked(lk)
struct lockit *lk;
{
-
if (lk->lkt_held == -1)
panic("softdep_unlock_interlocked: lock not held");
lk->lkt_held = -1;
+ return lk->lkt_spl;
}
#endif /* DEBUG */
@@ -311,18 +323,19 @@
struct sema *semap;
struct lockit *interlock;
{
-
+ int s;
+
if (semap->value++ > 0) {
if (interlock != NULL)
- FREE_LOCK_INTERLOCKED(interlock);
+ s = FREE_LOCK_INTERLOCKED(interlock);
tsleep((caddr_t)semap, semap->prio, semap->name, semap->timo);
if (interlock != NULL) {
- ACQUIRE_LOCK_INTERLOCKED(interlock);
+ ACQUIRE_LOCK_INTERLOCKED(interlock, s);
FREE_LOCK(interlock);
}
return (0);
}
- semap->holder = CURPROC->p_pid;
+ semap->holder = CURPROC_PID;
if (interlock != NULL)
FREE_LOCK(interlock);
return (1);
@@ -333,7 +346,7 @@
struct sema *semap;
{
- if (semap->value <= 0 || semap->holder != CURPROC->p_pid)
+ if (semap->value <= 0 || semap->holder != CURPROC_PID)
panic("sema_release: not held");
if (--semap->value > 0) {
semap->value = 0;
@@ -478,7 +491,7 @@
* ordering ensures that no new <vfsid, inum, lbn> triples will be generated
* until all the old ones have been purged from the dependency lists.
*/
-int
+static int
softdep_process_worklist(matchmnt)
struct mount *matchmnt;
{
@@ -486,7 +499,6 @@
struct worklist *wk;
struct fs *matchfs;
int matchcnt;
-
/*
* Record the process identifier of our caller so that we can give
* this process preferential treatment in request_cleanup below.
@@ -578,6 +590,31 @@
}
/*
+ * Move dependencies from one buffer to another.
+ */
+static void
+softdep_move_dependencies(oldbp, newbp)
+ struct buf *oldbp;
+ struct buf *newbp;
+{
+ struct worklist *wk, *wktail;
+
+ if (LIST_FIRST(&newbp->b_dep) != NULL)
+ panic("softdep_move_dependencies: need merge code");
+ wktail = 0;
+ ACQUIRE_LOCK(&lk);
+ while ((wk = LIST_FIRST(&oldbp->b_dep)) != NULL) {
+ LIST_REMOVE(wk, wk_list);
+ if (wktail == 0)
+ LIST_INSERT_HEAD(&newbp->b_dep, wk, wk_list);
+ else
+ LIST_INSERT_AFTER(wktail, wk, wk_list);
+ wktail = wk;
+ }
+ FREE_LOCK(&lk);
+}
+
+/*
* Purge the work list of all items associated with a particular mount point.
*/
int
@@ -606,8 +643,9 @@
* but we give it a few extra just to be sure.
*/
devvp = VFSTOUFS(oldmnt)->um_devvp;
- for (loopcnt = 10; loopcnt > 0; loopcnt--) {
+ for (loopcnt = 10; loopcnt > 0; ) {
if (softdep_process_worklist(oldmnt) == 0) {
+ loopcnt--;
/*
* Do another flush in case any vnodes were brought in
* as part of the cleanup operations.
@@ -1492,6 +1530,7 @@
}
newindirdep->ir_savebp =
getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0);
+ newindirdep->ir_savebp->b_flags |= B_ASYNC;
bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount);
}
}
@@ -1525,7 +1564,6 @@
* later release and zero the inode so that the calling routine
* can release it.
*/
-static long num_freeblks; /* number of freeblks allocated */
void
softdep_setup_freeblocks(ip, length)
struct inode *ip; /* The inode whose length is to be reduced */
@@ -1542,12 +1580,6 @@
if (length != 0)
panic("softdep_setup_freeblocks: non-zero length");
- /*
- * If we are over our limit, try to improve the situation.
- */
- if (num_freeblks > max_softdeps / 2 && speedup_syncer() == 0)
- (void) request_cleanup(FLUSH_REMOVE, 0);
- num_freeblks += 1;
MALLOC(freeblks, struct freeblks *, sizeof(struct freeblks),
M_FREEBLKS, M_WAITOK);
bzero(freeblks, sizeof(struct freeblks));
@@ -1592,11 +1624,6 @@
if ((inodedep->id_state & IOSTARTED) != 0)
panic("softdep_setup_freeblocks: inode busy");
/*
- * Add the freeblks structure to the list of operations that
- * must await the zero'ed inode being written to disk.
- */
- WORKLIST_INSERT(&inodedep->id_bufwait, &freeblks->fb_list);
- /*
* Because the file length has been truncated to zero, any
* pending block allocation dependency structures associated
* with this inode are obsolete and can simply be de-allocated.
@@ -1627,11 +1654,22 @@
ACQUIRE_LOCK(&lk);
}
/*
- * Try freeing the inodedep in case that was the last dependency.
+ * Add the freeblks structure to the list of operations that
+ * must await the zero'ed inode being written to disk. If we
+ * still have a bitmap dependency, then the inode has never been
+ * written to disk, so we can process the freeblks immediately.
+ * If the inodedep does not exist, then the zero'ed inode has
+ * been written and we can also proceed.
*/
- if ((inodedep_lookup(fs, ip->i_number, 0, &inodedep)) != 0)
- (void) free_inodedep(inodedep);
- FREE_LOCK(&lk);
+ if (inodedep_lookup(fs, ip->i_number, 0, &inodedep) == 0 ||
+ free_inodedep(inodedep) ||
+ (inodedep->id_state & DEPCOMPLETE) == 0) {
+ FREE_LOCK(&lk);
Home |
Main Index |
Thread Index |
Old Index