Index: ufs/ffs/ffs_softdep.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/ufs/ffs/ffs_softdep.c,v retrieving revision 1.204 diff -u -r1.204 ffs_softdep.c --- ufs/ffs/ffs_softdep.c 23 Feb 2007 20:23:35 -0000 1.204 +++ ufs/ffs/ffs_softdep.c 23 Mar 2007 18:09:20 -0000 @@ -5009,7 +5009,7 @@ struct buf *bp; struct fs *fs; struct thread *td = curthread; - int error, flushparent; + int error, flushparent, pagedep_new_block; ino_t parentino; ufs_lbn_t lbn; @@ -5062,6 +5062,7 @@ */ if (vp->v_iflag & VI_DOOMED) break; + /* * We prevent deadlock by always fetching inodes from the * root, moving down the directory tree. Thus, when fetching @@ -5087,15 +5088,36 @@ * then we do the slower ffs_syncvnode of the directory. */ if (flushparent) { + int locked; + if ((error = ffs_update(pvp, 1)) != 0) { vput(pvp); return (error); } - if ((pagedep->pd_state & NEWBLOCK) && - (error = ffs_syncvnode(pvp, MNT_WAIT))) { - vput(pvp); - return (error); + ACQUIRE_LOCK(&lk); + locked = 1; + if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) != 0) { + if ((wk = LIST_FIRST(&inodedep->id_pendinghd)) != NULL) { + if (wk->wk_type != D_DIRADD) + panic("softdep_fsync: Unexpected type %s", + TYPENAME(wk->wk_type)); + dap = WK_DIRADD(wk); + if (dap->da_state & DIRCHG) + pagedep = dap->da_previous->dm_pagedep; + else + pagedep = dap->da_pagedep; + pagedep_new_block = pagedep->pd_state & NEWBLOCK; + FREE_LOCK(&lk); + locked = 0; + if (pagedep_new_block && + (error = ffs_syncvnode(pvp, MNT_WAIT))) { + vput(pvp); + return (error); + } + } } + if (locked) + FREE_LOCK(&lk); } /* * Flush directory page containing the inode's name.