diff options
| author | Alan Cox <alc@FreeBSD.org> | 2003-09-18 02:26:03 +0000 |
|---|---|---|
| committer | Alan Cox <alc@FreeBSD.org> | 2003-09-18 02:26:03 +0000 |
| commit | 417a26a154bbc4e2af6c62b4ce2657289e905784 (patch) | |
| tree | 1410c2003b81bbc19af1d323168d690a78204dd8 | |
| parent | 598345da4bf68e8776c4fd8d7b2a061993dcb4fd (diff) | |
Notes
| -rw-r--r-- | sys/vm/vm_fault.c | 2 | ||||
| -rw-r--r-- | sys/vm/vnode_pager.c | 44 |
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; } |
