Index: sys/ufs/ffs/ffs_softdep.c =================================================================== --- sys/ufs/ffs/ffs_softdep.c +++ sys/ufs/ffs/ffs_softdep.c @@ -9250,6 +9250,13 @@ dvp = ITOV(dp); ump = ITOUMP(dp); + /* + * Acquire an extra reference so that the end-of-life truncate + * will not happen until after the directory page is written. + * The reference is released in handle_workitem_remove. + */ + vref(ITOV(ip)); + /* * If the system is over its limit and our filesystem is * responsible for more than our share of that usage and @@ -9882,11 +9889,13 @@ struct vnode *vp; struct inode *ip; ino_t oldinum; + bool isparent; if (dirrem->dm_state & ONWORKLIST) panic("handle_workitem_remove: dirrem %p still on worklist", dirrem); oldinum = dirrem->dm_oldinum; + isparent = dirrem->dm_oldinum == dirrem->dm_dirinum; mp = dirrem->dm_list.wk_mp; ump = VFSTOUFS(mp); flags |= LK_EXCLUSIVE; @@ -10003,6 +10012,9 @@ UFS_INODE_SET_FLAG(ip, IN_CHANGE); out: ffs_update(vp, 0); + /* Drop the extra reference acquired in newdirrem. */ + if (!isparent) + vunref(vp); vput(vp); return (0); }