summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2001-11-09 21:34:45 +0000
committerdillon <dillon@FreeBSD.org>2001-11-09 21:34:45 +0000
commite8b10885954a7544259a4f3f0f6aadaa3b235400 (patch)
treee10a0653bc0339aef9d58536278b973f140021cf /sys/vm
parentbaaedd4ccbf0bfa2f0a96320f9748cc3034ea7bb (diff)
downloadFreeBSD-src-e8b10885954a7544259a4f3f0f6aadaa3b235400.zip
FreeBSD-src-e8b10885954a7544259a4f3f0f6aadaa3b235400.tar.gz
Fix deadlock introduced in 1.73 (Jan 1998). The paging-in-progress count
on a vnode-backed object must be incremented *after* obtaining the vnode lock. If it is bumped before obtaining the vnode lock we can deadlock against vtruncbuf(). Submitted by: peter, ps MFC after: 3 days
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_fault.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 8814ae5..79e1224 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -269,11 +269,15 @@ RetryFault:;
* are messing with it. Once we have the reference, the map is free
* to be diddled. Since objects reference their shadows (and copies),
* they will stay around as well.
+ *
+ * Bump the paging-in-progress count to prevent size changes (e.g.
+ * truncation operations) during I/O. This must be done after
+ * obtaining the vnode lock in order to avoid possible deadlocks.
*/
vm_object_reference(fs.first_object);
+ fs.vp = vnode_pager_lock(fs.first_object);
vm_object_pip_add(fs.first_object, 1);
- fs.vp = vnode_pager_lock(fs.first_object);
if ((fault_type & VM_PROT_WRITE) &&
(fs.first_object->type == OBJT_VNODE)) {
vm_freeze_copyopts(fs.first_object,
OpenPOWER on IntegriCloud