1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

Add vm object locking to vnode_pager_lock(). (This triggers the movement

of a VM_OBJECT_LOCK() in vm_fault().)
This commit is contained in:
Alan Cox 2003-09-18 02:26:03 +00:00
parent 598345da4b
commit 417a26a154
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=120183
2 changed files with 32 additions and 14 deletions

View File

@ -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;

View File

@ -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 */
struct vnode *vp;
vm_object_t backing_object, object;
GIANT_REQUIRED;
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;
}