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 /sys/ufs | |
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
Diffstat (limited to 'sys/ufs')
-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 */ |