summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2005-01-24 21:21:59 +0000
committerphk <phk@FreeBSD.org>2005-01-24 21:21:59 +0000
commitba85bee696d6a33157d344e44d2daa40fb97d1ce (patch)
tree80a0f152ec73d01cf5ba4fbcc7e5412b3905b22a
parente0b285228ae30d4d239447d3dd54918c144d7959 (diff)
downloadFreeBSD-src-ba85bee696d6a33157d344e44d2daa40fb97d1ce.zip
FreeBSD-src-ba85bee696d6a33157d344e44d2daa40fb97d1ce.tar.gz
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.
-rw-r--r--sys/kern/vfs_default.c51
-rw-r--r--sys/sys/vnode.h1
-rw-r--r--sys/vm/vnode_pager.c50
-rw-r--r--sys/vm/vnode_pager.h1
4 files changed, 52 insertions, 51 deletions
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index a66c452..984b92f 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 4e9bd10..b017c73 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 574cf22..96aa36c 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -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.
diff --git a/sys/vm/vnode_pager.h b/sys/vm/vnode_pager.h
index 45fb067..aa9be03 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);
/*
OpenPOWER on IntegriCloud