diff options
author | dillon <dillon@FreeBSD.org> | 2001-11-09 21:34:45 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2001-11-09 21:34:45 +0000 |
commit | e8b10885954a7544259a4f3f0f6aadaa3b235400 (patch) | |
tree | e10a0653bc0339aef9d58536278b973f140021cf /sys/vm | |
parent | baaedd4ccbf0bfa2f0a96320f9748cc3034ea7bb (diff) | |
download | FreeBSD-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.c | 6 |
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, |