Add pgo_getvp method
This eliminates the staircase of conditions in vm_map_entry_set_vnode_text(). Reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D30070
This commit is contained in:
parent
c23c555bc1
commit
192112b74f
@ -435,6 +435,8 @@ static void swap_pager_release_writecount(vm_object_t object,
|
||||
vm_offset_t start, vm_offset_t end);
|
||||
static void swap_pager_set_writeable_dirty(vm_object_t object);
|
||||
static bool swap_pager_mightbedirty(vm_object_t object);
|
||||
static void swap_pager_getvp(vm_object_t object, struct vnode **vpp,
|
||||
bool *vp_heldp);
|
||||
|
||||
struct pagerops swappagerops = {
|
||||
.pgo_init = swap_pager_init, /* early system initialization of pager */
|
||||
@ -449,6 +451,7 @@ struct pagerops swappagerops = {
|
||||
.pgo_release_writecount = swap_pager_release_writecount,
|
||||
.pgo_set_writeable_dirty = swap_pager_set_writeable_dirty,
|
||||
.pgo_mightbedirty = swap_pager_mightbedirty,
|
||||
.pgo_getvp = swap_pager_getvp,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -3142,3 +3145,28 @@ swap_pager_mightbedirty(vm_object_t object)
|
||||
return (vm_object_mightbedirty_(object));
|
||||
return (false);
|
||||
}
|
||||
|
||||
static void
|
||||
swap_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
|
||||
{
|
||||
struct vnode *vp;
|
||||
|
||||
KASSERT((object->flags & OBJ_TMPFS_NODE) != 0,
|
||||
("swap_pager_getvp: swap and !TMPFS obj %p", object));
|
||||
|
||||
/*
|
||||
* Tmpfs VREG node, which was reclaimed, has
|
||||
* OBJ_TMPFS_NODE flag set, but not OBJ_TMPFS. In
|
||||
* this case there is no v_writecount to adjust.
|
||||
*/
|
||||
VM_OBJECT_RLOCK(object);
|
||||
if ((object->flags & OBJ_TMPFS) != 0) {
|
||||
vp = object->un_pager.swp.swp_tmpfs;
|
||||
if (vp != NULL) {
|
||||
vhold(vp);
|
||||
*vpp = vp;
|
||||
*vp_heldp = true;
|
||||
}
|
||||
}
|
||||
VM_OBJECT_RUNLOCK(object);
|
||||
}
|
||||
|
@ -561,38 +561,7 @@ vm_map_entry_set_vnode_text(vm_map_entry_t entry, bool add)
|
||||
* referenced by the entry we are processing, so it cannot go
|
||||
* away.
|
||||
*/
|
||||
vp = NULL;
|
||||
vp_held = false;
|
||||
if (object->type == OBJT_DEAD) {
|
||||
/*
|
||||
* For OBJT_DEAD objects, v_writecount was handled in
|
||||
* vnode_pager_dealloc().
|
||||
*/
|
||||
} else if (object->type == OBJT_VNODE) {
|
||||
vp = object->handle;
|
||||
} else if (object->type == OBJT_SWAP) {
|
||||
KASSERT((object->flags & OBJ_TMPFS_NODE) != 0,
|
||||
("vm_map_entry_set_vnode_text: swap and !TMPFS "
|
||||
"entry %p, object %p, add %d", entry, object, add));
|
||||
/*
|
||||
* Tmpfs VREG node, which was reclaimed, has
|
||||
* OBJ_TMPFS_NODE flag set, but not OBJ_TMPFS. In
|
||||
* this case there is no v_writecount to adjust.
|
||||
*/
|
||||
VM_OBJECT_RLOCK(object);
|
||||
if ((object->flags & OBJ_TMPFS) != 0) {
|
||||
vp = object->un_pager.swp.swp_tmpfs;
|
||||
if (vp != NULL) {
|
||||
vhold(vp);
|
||||
vp_held = true;
|
||||
}
|
||||
}
|
||||
VM_OBJECT_RUNLOCK(object);
|
||||
} else {
|
||||
KASSERT(0,
|
||||
("vm_map_entry_set_vnode_text: wrong object type, "
|
||||
"entry %p, object %p, add %d", entry, object, add));
|
||||
}
|
||||
vm_pager_getvp(object, &vp, &vp_held);
|
||||
if (vp != NULL) {
|
||||
if (add) {
|
||||
VOP_SET_TEXT_CHECKED(vp);
|
||||
|
@ -100,6 +100,7 @@ static vm_object_t dead_pager_alloc(void *, vm_ooffset_t, vm_prot_t,
|
||||
static void dead_pager_putpages(vm_object_t, vm_page_t *, int, int, int *);
|
||||
static boolean_t dead_pager_haspage(vm_object_t, vm_pindex_t, int *, int *);
|
||||
static void dead_pager_dealloc(vm_object_t);
|
||||
static void dead_pager_getvp(vm_object_t, struct vnode **, bool *);
|
||||
|
||||
static int
|
||||
dead_pager_getpages(vm_object_t obj, vm_page_t *ma, int count, int *rbehind,
|
||||
@ -144,12 +145,22 @@ dead_pager_dealloc(vm_object_t object)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
dead_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
|
||||
{
|
||||
/*
|
||||
* For OBJT_DEAD objects, v_writecount was handled in
|
||||
* vnode_pager_dealloc().
|
||||
*/
|
||||
}
|
||||
|
||||
static struct pagerops deadpagerops = {
|
||||
.pgo_alloc = dead_pager_alloc,
|
||||
.pgo_dealloc = dead_pager_dealloc,
|
||||
.pgo_getpages = dead_pager_getpages,
|
||||
.pgo_putpages = dead_pager_putpages,
|
||||
.pgo_haspage = dead_pager_haspage,
|
||||
.pgo_getvp = dead_pager_getvp,
|
||||
};
|
||||
|
||||
struct pagerops *pagertab[] = {
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <sys/queue.h>
|
||||
|
||||
TAILQ_HEAD(pagerlst, vm_object);
|
||||
struct vnode;
|
||||
|
||||
typedef void pgo_init_t(void);
|
||||
typedef vm_object_t pgo_alloc_t(void *, vm_ooffset_t, vm_prot_t, vm_ooffset_t,
|
||||
@ -64,6 +65,8 @@ typedef void pgo_pageunswapped_t(vm_page_t);
|
||||
typedef void pgo_writecount_t(vm_object_t, vm_offset_t, vm_offset_t);
|
||||
typedef void pgo_set_writeable_dirty_t(vm_object_t);
|
||||
typedef bool pgo_mightbedirty_t(vm_object_t);
|
||||
typedef void pgo_getvp_t(vm_object_t object, struct vnode **vpp,
|
||||
bool *vp_heldp);
|
||||
|
||||
struct pagerops {
|
||||
pgo_init_t *pgo_init; /* Initialize pager. */
|
||||
@ -79,6 +82,7 @@ struct pagerops {
|
||||
pgo_writecount_t *pgo_release_writecount;
|
||||
pgo_set_writeable_dirty_t *pgo_set_writeable_dirty;
|
||||
pgo_mightbedirty_t *pgo_mightbedirty;
|
||||
pgo_getvp_t *pgo_getvp;
|
||||
};
|
||||
|
||||
extern struct pagerops defaultpagerops;
|
||||
@ -216,6 +220,22 @@ vm_pager_release_writecount(vm_object_t object, vm_offset_t start,
|
||||
method(object, start, end);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
vm_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
|
||||
{
|
||||
pgo_getvp_t *method;
|
||||
|
||||
*vpp = NULL;
|
||||
*vp_heldp = false;
|
||||
method = pagertab[object->type]->pgo_getvp;
|
||||
if (method != NULL) {
|
||||
method(object, vpp, vp_heldp);
|
||||
} else {
|
||||
KASSERT(0,
|
||||
("vm_pager_getvp: wrong object type obj %p", object));
|
||||
}
|
||||
}
|
||||
|
||||
struct cdev_pager_ops {
|
||||
int (*cdev_pg_fault)(vm_object_t vm_obj, vm_ooffset_t offset,
|
||||
int prot, vm_page_t *mres);
|
||||
|
@ -105,6 +105,7 @@ static void vnode_pager_update_writecount(vm_object_t, vm_offset_t,
|
||||
vm_offset_t);
|
||||
static void vnode_pager_release_writecount(vm_object_t, vm_offset_t,
|
||||
vm_offset_t);
|
||||
static void vnode_pager_getvp(vm_object_t, struct vnode **, bool *);
|
||||
|
||||
struct pagerops vnodepagerops = {
|
||||
.pgo_alloc = vnode_pager_alloc,
|
||||
@ -117,6 +118,7 @@ struct pagerops vnodepagerops = {
|
||||
.pgo_release_writecount = vnode_pager_release_writecount,
|
||||
.pgo_set_writeable_dirty = vm_object_set_writeable_dirty_,
|
||||
.pgo_mightbedirty = vm_object_mightbedirty_,
|
||||
.pgo_getvp = vnode_pager_getvp,
|
||||
};
|
||||
|
||||
static struct domainset *vnode_domainset = NULL;
|
||||
@ -1602,3 +1604,9 @@ vnode_pager_release_writecount(vm_object_t object, vm_offset_t start,
|
||||
if (mp != NULL)
|
||||
vn_finished_write(mp);
|
||||
}
|
||||
|
||||
static void
|
||||
vnode_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
|
||||
{
|
||||
*vpp = object->handle;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user