summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_object.c
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>2006-03-02 22:13:28 +0000
committertegge <tegge@FreeBSD.org>2006-03-02 22:13:28 +0000
commit774f51ad2c9890088551e2fef8c7c2ec8bc1e446 (patch)
treea136dfc347b9ef7b044439ec33fe997d02fb4061 /sys/vm/vm_object.c
parent29fc266dddf27264a642495e94c044465289b437 (diff)
downloadFreeBSD-src-774f51ad2c9890088551e2fef8c7c2ec8bc1e446.zip
FreeBSD-src-774f51ad2c9890088551e2fef8c7c2ec8bc1e446.tar.gz
Eliminate a deadlock when creating snapshots. Blocking vn_start_write() must
be called without any vnode locks held. Remove calls to vn_start_write() and vn_finished_write() in vnode_pager_putpages() and add these calls before the vnode lock is obtained to most of the callers that don't already have them.
Diffstat (limited to 'sys/vm/vm_object.c')
-rw-r--r--sys/vm/vm_object.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 5321b53..8457529 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -993,6 +993,7 @@ vm_object_sync(vm_object_t object, vm_ooffset_t offset, vm_size_t size,
{
vm_object_t backing_object;
struct vnode *vp;
+ struct mount *mp;
int flags;
if (object == NULL)
@@ -1023,6 +1024,7 @@ vm_object_sync(vm_object_t object, vm_ooffset_t offset, vm_size_t size,
int vfslocked;
vp = object->handle;
VM_OBJECT_UNLOCK(object);
+ (void) vn_start_write(vp, &mp, V_WAIT);
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
flags = (syncio || invalidate) ? OBJPC_SYNC : 0;
@@ -1035,6 +1037,7 @@ vm_object_sync(vm_object_t object, vm_ooffset_t offset, vm_size_t size,
VM_OBJECT_UNLOCK(object);
VOP_UNLOCK(vp, 0, curthread);
VFS_UNLOCK_GIANT(vfslocked);
+ vn_finished_write(mp);
VM_OBJECT_LOCK(object);
}
if ((object->type == OBJT_VNODE ||
OpenPOWER on IntegriCloud