Index: head/sys/ufs/ffs/ffs_alloc.c =================================================================== --- head/sys/ufs/ffs/ffs_alloc.c +++ head/sys/ufs/ffs/ffs_alloc.c @@ -1137,10 +1137,15 @@ (allocfcn_t *)ffs_nodealloccg); if (ino == 0) goto noinodes; - error = ffs_vget(pvp->v_mount, ino, LK_EXCLUSIVE, vpp); + + /* + * Get rid of the cached old vnode, force allocation of a new vnode + * for this inode. + */ + error = ffs_vgetf(pvp->v_mount, ino, LK_EXCLUSIVE, vpp, FFSV_REPLACE); if (error) { error1 = ffs_vgetf(pvp->v_mount, ino, LK_EXCLUSIVE, vpp, - FFSV_FORCEINSMQ); + FFSV_FORCEINSMQ | FFSV_REPLACE); ffs_vfree(pvp, ino, mode); if (error1 == 0) { ip = VTOI(*vpp); @@ -1176,7 +1181,6 @@ ip->i_din2->di_birthtime = ts.tv_sec; ip->i_din2->di_birthnsec = ts.tv_nsec; } - ufs_prepare_reclaim(*vpp); ip->i_flag = 0; (*vpp)->v_vflag = 0; (*vpp)->v_type = VNON; Index: head/sys/ufs/ffs/ffs_extern.h =================================================================== --- head/sys/ufs/ffs/ffs_extern.h +++ head/sys/ufs/ffs/ffs_extern.h @@ -121,6 +121,7 @@ * Flags to ffs_vgetf */ #define FFSV_FORCEINSMQ 0x0001 +#define FFSV_REPLACE 0x0002 /* * Flags to ffs_reload Index: head/sys/ufs/ffs/ffs_vfsops.c =================================================================== --- head/sys/ufs/ffs/ffs_vfsops.c +++ head/sys/ufs/ffs/ffs_vfsops.c @@ -1671,9 +1671,17 @@ struct vnode *vp; int error; + MPASS((ffs_flags & FFSV_REPLACE) == 0 || (flags & LK_EXCLUSIVE) != 0); + error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); - if (error || *vpp != NULL) + if (error != 0) return (error); + if (*vpp != NULL) { + if ((ffs_flags & FFSV_REPLACE) == 0) + return (0); + vgone(*vpp); + vput(*vpp); + } /* * We must promote to an exclusive lock for vnode creation. This @@ -1735,8 +1743,19 @@ } vp->v_vflag &= ~VV_FORCEINSMQ; error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL); - if (error || *vpp != NULL) + if (error != 0) return (error); + if (*vpp != NULL) { + /* + * Calls from ffs_valloc() (i.e. FFSV_REPLACE set) + * operate on empty inode, which must not be found by + * other threads until fully filled. Vnode for empty + * inode must be not re-inserted on the hash by other + * thread, after removal by us at the beginning. + */ + MPASS((ffs_flags & FFSV_REPLACE) == 0); + return (0); + } /* Read in the disk contents for the inode, copy into the inode. */ error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),