aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2003-09-18 02:26:03 +0000
committerAlan Cox <alc@FreeBSD.org>2003-09-18 02:26:03 +0000
commit417a26a154bbc4e2af6c62b4ce2657289e905784 (patch)
tree1410c2003b81bbc19af1d323168d690a78204dd8
parent598345da4bf68e8776c4fd8d7b2a061993dcb4fd (diff)
Notes
-rw-r--r--sys/vm/vm_fault.c2
-rw-r--r--sys/vm/vnode_pager.c44
2 files changed, 32 insertions, 14 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 2f87cb7cdce36..855ff7128c380 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 2e60cef868f8b..e6badfe92f475 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;
+ struct vnode *vp;
+ vm_object_t backing_object, object;
- for (; object != NULL; object = object->backing_object) {
- if (object->type != OBJT_VNODE)
+ 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;
}