diff options
author | tegge <tegge@FreeBSD.org> | 2006-03-02 22:13:28 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 2006-03-02 22:13:28 +0000 |
commit | 774f51ad2c9890088551e2fef8c7c2ec8bc1e446 (patch) | |
tree | a136dfc347b9ef7b044439ec33fe997d02fb4061 /sys/vm/vm_object.c | |
parent | 29fc266dddf27264a642495e94c044465289b437 (diff) | |
download | FreeBSD-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.c | 3 |
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 || |