diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index a66c4521977d..984b92f54f5f 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -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 */ diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 4e9bd1080bad..b017c73ccfd3 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -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; diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 574cf226f0fe..96aa36ceb084 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -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. diff --git a/sys/vm/vnode_pager.h b/sys/vm/vnode_pager.h index 45fb0671ee7a..aa9be03c17ba 100644 --- a/sys/vm/vnode_pager.h +++ b/sys/vm/vnode_pager.h @@ -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); /*