diff options
author | Pedro Martelletto <pedro@cvs.openbsd.org> | 2005-09-26 21:11:10 +0000 |
---|---|---|
committer | Pedro Martelletto <pedro@cvs.openbsd.org> | 2005-09-26 21:11:10 +0000 |
commit | 9dacd3671602823d74986348365933214a7f6168 (patch) | |
tree | eaa4320ca1b141ca645d7f1ca57e9ac328ca5feb | |
parent | bf3d09833861afd8ec9f911ca5b767841069a234 (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.c | 23 | ||||
-rw-r--r-- | sys/ufs/ffs/softdep.h | 3 |
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 */ |