summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Martelletto <pedro@cvs.openbsd.org>2005-09-26 21:11:10 +0000
committerPedro Martelletto <pedro@cvs.openbsd.org>2005-09-26 21:11:10 +0000
commit9dacd3671602823d74986348365933214a7f6168 (patch)
treeeaa4320ca1b141ca645d7f1ca57e9ac328ca5feb
parentbf3d09833861afd8ec9f911ca5b767841069a234 (diff)
bring in two changes from freebsd:
- keep track of free blocks dependencies, and only tell the syncer to release the blocks when there are no more dirty buffers associated - don't mark the inode dependency as done if we had to rollback its allocation due to the bitmap being inconsistent testing by krw, jsg, jmc and sturm, okay deraadt
-rw-r--r--sys/ufs/ffs/ffs_softdep.c23
-rw-r--r--sys/ufs/ffs/softdep.h3
2 files changed, 23 insertions, 3 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 98ad7456455..a0e65ebe638 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_softdep.c,v 1.62 2005/09/06 17:02:09 pedro Exp $ */
+/* $OpenBSD: ffs_softdep.c,v 1.63 2005/09/26 21:11:09 pedro Exp $ */
/*
* Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved.
*
@@ -1921,6 +1921,7 @@ softdep_setup_freeblocks(ip, length)
freeblks = pool_get(&freeblks_pool, PR_WAITOK);
bzero(freeblks, sizeof(struct freeblks));
freeblks->fb_list.wk_type = D_FREEBLKS;
+ freeblks->fb_state = ATTACHED;
freeblks->fb_uid = ip->i_ffs_uid;
freeblks->fb_previousinum = ip->i_number;
freeblks->fb_devvp = ip->i_devvp;
@@ -2002,6 +2003,20 @@ softdep_setup_freeblocks(ip, length)
}
if (inodedep_lookup(fs, ip->i_number, 0, &inodedep) != 0)
(void) free_inodedep(inodedep);
+
+ if (delay) {
+ freeblks->fb_state |= DEPCOMPLETE;
+ /*
+ * If the inode with zeroed block pointers is now on disk we
+ * can start freeing blocks. Add freeblks to the worklist
+ * instead of calling handle_workitem_freeblocks() directly as
+ * it is more likely that additional IO is needed to complete
+ * the request than in the !delay case.
+ */
+ if ((freeblks->fb_state & ALLCOMPLETE) == ALLCOMPLETE)
+ add_to_worklist(&freeblks->fb_list);
+ }
+
FREE_LOCK(&lk);
/*
* If the inode has never been written to disk (delay == 0),
@@ -3765,7 +3780,6 @@ handle_written_inodeblock(inodedep, bp)
if ((inodedep->id_state & IOSTARTED) == 0)
panic("handle_written_inodeblock: not started");
inodedep->id_state &= ~IOSTARTED;
- inodedep->id_state |= COMPLETE;
dp = (struct ufs1_dinode *)bp->b_data +
ino_to_fsbo(inodedep->id_fs, inodedep->id_ino);
/*
@@ -3784,6 +3798,7 @@ handle_written_inodeblock(inodedep, bp)
buf_dirty(bp);
return (1);
}
+ inodedep->id_state |= COMPLETE;
/*
* Roll forward anything that had to be rolled back before
* the inode could be updated.
@@ -3869,6 +3884,10 @@ handle_written_inodeblock(inodedep, bp)
continue;
case D_FREEBLKS:
+ wk->wk_state |= COMPLETE;
+ if ((wk->wk_state & ALLCOMPLETE) != ALLCOMPLETE)
+ continue;
+ /* FALLTHROUGH */
case D_FREEFRAG:
case D_DIRREM:
add_to_worklist(wk);
diff --git a/sys/ufs/ffs/softdep.h b/sys/ufs/ffs/softdep.h
index 309dbb5e25d..4e5e1136c95 100644
--- a/sys/ufs/ffs/softdep.h
+++ b/sys/ufs/ffs/softdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: softdep.h,v 1.9 2005/07/20 16:30:35 pedro Exp $ */
+/* $OpenBSD: softdep.h,v 1.10 2005/09/26 21:11:09 pedro Exp $ */
/*
* Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved.
*
@@ -416,6 +416,7 @@ struct freefrag {
*/
struct freeblks {
struct worklist fb_list; /* id_inowait or delayed worklist */
+# define fb_state fb_list.wk_state /* inode and dirty block state */
ino_t fb_previousinum; /* inode of previous owner of blocks */
struct vnode *fb_devvp; /* filesystem device vnode */
struct mount *fb_mnt; /* associated mount point */