mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 23:28:57 +00:00
Move the body of vop_stdcreatevobject() over to the vnode_pager under
the name Sande^H^H^H^H^Hvnode_create_vobject(). Make the new function take a size argument which removes the need for a VOP_STAT() or a very pessimistic guess for disks. Call that new function from vop_stdcreatevobject(). Make vnode_pager_alloc() private now that its only user came home.
This commit is contained in:
parent
49a152366e
commit
d07a6d3f61
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=140767
@ -370,57 +370,8 @@ vop_stdcreatevobject(ap)
|
||||
struct thread *td;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct ucred *cred = ap->a_cred;
|
||||
struct thread *td = ap->a_td;
|
||||
struct vattr vat;
|
||||
vm_object_t object;
|
||||
int error = 0;
|
||||
vm_ooffset_t size;
|
||||
|
||||
if (!vn_isdisk(vp, NULL) && vn_canvmio(vp) == FALSE)
|
||||
return (0);
|
||||
|
||||
while ((object = vp->v_object) != NULL) {
|
||||
VM_OBJECT_LOCK(object);
|
||||
if (!(object->flags & OBJ_DEAD)) {
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
break;
|
||||
}
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
vm_object_set_flag(object, OBJ_DISCONNECTWNT);
|
||||
msleep(object, VM_OBJECT_MTX(object), PDROP | PVM, "vodead", 0);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
}
|
||||
|
||||
if (object == NULL) {
|
||||
if (vn_isdisk(vp, NULL)) {
|
||||
/*
|
||||
* This simply allocates the biggest object possible
|
||||
* for a disk vnode. This should be fixed, but doesn't
|
||||
* cause any problems (yet).
|
||||
*/
|
||||
size = IDX_TO_OFF(INT_MAX);
|
||||
} else {
|
||||
if ((error = VOP_GETATTR(vp, &vat, cred, td)) != 0)
|
||||
return (error);
|
||||
size = vat.va_size;
|
||||
}
|
||||
|
||||
object = vnode_pager_alloc(vp, size, 0, 0);
|
||||
/*
|
||||
* Dereference the reference we just created. This assumes
|
||||
* that the object is associated with the vp.
|
||||
*/
|
||||
VM_OBJECT_LOCK(object);
|
||||
object->ref_count--;
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
vrele(vp);
|
||||
}
|
||||
|
||||
KASSERT(vp->v_object != NULL, ("vop_stdcreatevobject: NULL object"));
|
||||
|
||||
return (error);
|
||||
return (vnode_create_vobject(ap->a_vp, 0, ap->a_td));
|
||||
}
|
||||
|
||||
/* Destroy the VM system object associated with this vnode */
|
||||
|
@ -688,6 +688,7 @@ int vrefcnt(struct vnode *vp);
|
||||
void vbusy(struct vnode *vp);
|
||||
void v_addpollinfo(struct vnode *vp);
|
||||
|
||||
int vnode_create_vobject(struct vnode *vp, size_t size, struct thread *td);
|
||||
|
||||
extern struct vop_vector fifo_specops;
|
||||
extern struct vop_vector dead_vnodeops;
|
||||
|
@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/sf_buf.h>
|
||||
|
||||
@ -81,6 +82,7 @@ static void vnode_pager_dealloc(vm_object_t);
|
||||
static int vnode_pager_getpages(vm_object_t, vm_page_t *, int, int);
|
||||
static void vnode_pager_putpages(vm_object_t, vm_page_t *, int, boolean_t, int *);
|
||||
static boolean_t vnode_pager_haspage(vm_object_t, vm_pindex_t, int *, int *);
|
||||
static vm_object_t vnode_pager_alloc(void *, vm_ooffset_t, vm_prot_t, vm_ooffset_t);
|
||||
|
||||
struct pagerops vnodepagerops = {
|
||||
.pgo_init = vnode_pager_init,
|
||||
@ -100,6 +102,54 @@ vnode_pager_init(void)
|
||||
vnode_pbuf_freecnt = nswbuf / 2 + 1;
|
||||
}
|
||||
|
||||
/* Create the VM system backing object for this vnode */
|
||||
int
|
||||
vnode_create_vobject(struct vnode *vp, size_t isize, struct thread *td)
|
||||
{
|
||||
vm_object_t object;
|
||||
vm_ooffset_t size = isize;
|
||||
struct vattr va;
|
||||
|
||||
if (!vn_isdisk(vp, NULL) && vn_canvmio(vp) == FALSE)
|
||||
return (0);
|
||||
|
||||
while ((object = vp->v_object) != NULL) {
|
||||
VM_OBJECT_LOCK(object);
|
||||
if (!(object->flags & OBJ_DEAD)) {
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
return (0);
|
||||
}
|
||||
VOP_UNLOCK(vp, 0, td);
|
||||
vm_object_set_flag(object, OBJ_DISCONNECTWNT);
|
||||
msleep(object, VM_OBJECT_MTX(object), PDROP | PVM, "vodead", 0);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
if (vn_isdisk(vp, NULL)) {
|
||||
size = IDX_TO_OFF(INT_MAX);
|
||||
} else {
|
||||
if (VOP_GETATTR(vp, &va, td->td_ucred, td) != 0)
|
||||
return (0);
|
||||
size = va.va_size;
|
||||
}
|
||||
}
|
||||
|
||||
object = vnode_pager_alloc(vp, size, 0, 0);
|
||||
/*
|
||||
* Dereference the reference we just created. This assumes
|
||||
* that the object is associated with the vp.
|
||||
*/
|
||||
VM_OBJECT_LOCK(object);
|
||||
object->ref_count--;
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
vrele(vp);
|
||||
|
||||
KASSERT(vp->v_object != NULL, ("vnode_create_vobject: NULL object"));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate (or lookup) pager for a vnode.
|
||||
* Handle is a vnode pointer.
|
||||
|
@ -39,7 +39,6 @@
|
||||
#define _VNODE_PAGER_ 1
|
||||
|
||||
#ifdef _KERNEL
|
||||
vm_object_t vnode_pager_alloc(void *, vm_ooffset_t, vm_prot_t, vm_ooffset_t);
|
||||
struct vnode *vnode_pager_lock(vm_object_t);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user