Index: vfs_vnops.c =================================================================== RCS file: /zoo/pjd/repo/src/sys/kern/vfs_vnops.c,v retrieving revision 1.250 diff -u -p -r1.250 vfs_vnops.c --- vfs_vnops.c 18 May 2007 13:02:13 -0000 1.250 +++ vfs_vnops.c 27 May 2007 10:00:17 -0000 @@ -278,13 +278,23 @@ vn_close(vp, flags, file_cred, td) struct ucred *file_cred; struct thread *td; { - struct mount *mp; + struct mount *mp = NULL; int error; VFS_ASSERT_GIANT(vp->v_mount); - vn_start_write(vp, &mp, V_WAIT); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); + if (vp->v_vflag & VV_DELETED) { + /* + * File is deleted, but still open. We may want to free + * blocks on last close, so we need to call vn_start_write() + * on the file system. To do it, we first need to drop + * vnode lock to avoid LOR. + */ + VOP_UNLOCK(vp, 0, td); + vn_start_write(vp, &mp, V_WAIT); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); + } if (flags & FWRITE) { VNASSERT(vp->v_writecount > 0, vp, ("vn_close: negative writecount")); @@ -292,7 +302,8 @@ vn_close(vp, flags, file_cred, td) } error = VOP_CLOSE(vp, flags, file_cred, td); vput(vp); - vn_finished_write(mp); + if (mp != NULL) + vn_finished_write(mp); return (error); }