summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-09-18 02:26:03 +0000
committeralc <alc@FreeBSD.org>2003-09-18 02:26:03 +0000
commit1644dd5fce2192d54736b9824e5a6cd6ec9ef0fa (patch)
tree1410c2003b81bbc19af1d323168d690a78204dd8
parent8e2cce2cfe9c258058e4f193aa6cb50e389a0c1a (diff)
downloadFreeBSD-src-1644dd5fce2192d54736b9824e5a6cd6ec9ef0fa.zip
FreeBSD-src-1644dd5fce2192d54736b9824e5a6cd6ec9ef0fa.tar.gz
Add vm object locking to vnode_pager_lock(). (This triggers the movement
of a VM_OBJECT_LOCK() in vm_fault().)
-rw-r--r--sys/vm/vm_fault.c2
-rw-r--r--sys/vm/vnode_pager.c46
2 files changed, 33 insertions, 15 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 2f87cb7..855ff71 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -282,8 +282,8 @@ RetryFault:;
* XXX vnode_pager_lock() can block without releasing the map lock.
*/
vm_object_reference(fs.first_object);
- fs.vp = vnode_pager_lock(fs.first_object);
VM_OBJECT_LOCK(fs.first_object);
+ fs.vp = vnode_pager_lock(fs.first_object);
vm_object_pip_add(fs.first_object, 1);
fs.lookup_still_valid = TRUE;
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index 2e60cef..e6badfe 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -1079,28 +1079,46 @@ vnode_pager_generic_putpages(vp, m, bytecount, flags, rtvals)
}
struct vnode *
-vnode_pager_lock(object)
- vm_object_t object;
+vnode_pager_lock(vm_object_t first_object)
{
- struct thread *td = curthread; /* XXX */
-
- GIANT_REQUIRED;
-
- for (; object != NULL; object = object->backing_object) {
- if (object->type != OBJT_VNODE)
+ struct vnode *vp;
+ vm_object_t backing_object, object;
+
+ VM_OBJECT_LOCK_ASSERT(first_object, MA_OWNED);
+ for (object = first_object; object != NULL; object = backing_object) {
+ if (object->type != OBJT_VNODE) {
+ if ((backing_object = object->backing_object) != NULL)
+ VM_OBJECT_LOCK(backing_object);
+ if (object != first_object)
+ VM_OBJECT_UNLOCK(object);
continue;
+ }
+ retry:
if (object->flags & OBJ_DEAD) {
+ if (object != first_object)
+ VM_OBJECT_UNLOCK(object);
return NULL;
}
-
- /* XXX; If object->handle can change, we need to cache it. */
- while (vget(object->handle,
- LK_NOPAUSE | LK_SHARED | LK_RETRY | LK_CANRECURSE, td)){
- if ((object->flags & OBJ_DEAD) || (object->type != OBJT_VNODE))
+ vp = object->handle;
+ VI_LOCK(vp);
+ VM_OBJECT_UNLOCK(object);
+ if (first_object != object)
+ VM_OBJECT_UNLOCK(first_object);
+ if (vget(vp, LK_CANRECURSE | LK_INTERLOCK | LK_NOPAUSE |
+ LK_RETRY | LK_SHARED, curthread)) {
+ VM_OBJECT_LOCK(first_object);
+ if (object != first_object)
+ VM_OBJECT_LOCK(object);
+ if (object->type != OBJT_VNODE) {
+ if (object != first_object)
+ VM_OBJECT_UNLOCK(object);
return NULL;
+ }
printf("vnode_pager_lock: retrying\n");
+ goto retry;
}
- return object->handle;
+ VM_OBJECT_LOCK(first_object);
+ return (vp);
}
return NULL;
}
OpenPOWER on IntegriCloud