--- src/sys/ufs/ffs/softdep.h 2000/06/22 19:27:42 1.7.2.1 +++ src/sys/ufs/ffs/softdep.h 2005/08/31 17:53:53 1.7.2.2 @@ -396,6 +396,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 fs *fb_fs; /* addr of superblock */ --- src/sys/ufs/ffs/ffs_softdep.c 2005/08/26 20:40:14 1.57.2.14 +++ src/sys/ufs/ffs/ffs_softdep.c 2005/08/31 17:53:53 1.57.2.15 @@ -1749,6 +1749,7 @@ softdep_setup_freeblocks(ip, length) M_FREEBLKS, M_SOFTDEP_FLAGS); bzero(freeblks, sizeof(struct freeblks)); freeblks->fb_list.wk_type = D_FREEBLKS; + freeblks->fb_state = ATTACHED; freeblks->fb_uid = ip->i_uid; freeblks->fb_previousinum = ip->i_number; freeblks->fb_devvp = ip->i_devvp; @@ -1828,6 +1829,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 here 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), @@ -3572,6 +3587,10 @@ handle_written_inodeblock(inodedep, bp) continue; case D_FREEBLKS: + wk->wk_state |= COMPLETE; + if ((wk->wk_state & ALLCOMPLETE) != ALLCOMPLETE) + continue; + /* -- fall through -- */ case D_FREEFRAG: case D_DIRREM: add_to_worklist(wk);