Make more sense out of vop_stdcreatevobject()

This commit is contained in:
Poul-Henning Kamp 2004-11-18 07:55:05 +00:00
parent 9a4f1a4dd4
commit c31e6a8dc8

View File

@ -391,28 +391,40 @@ vop_stdcreatevobject(ap)
struct vattr vat; struct vattr vat;
vm_object_t object; vm_object_t object;
int error = 0; int error = 0;
vm_ooffset_t size;
GIANT_REQUIRED; GIANT_REQUIRED;
if (!vn_isdisk(vp, NULL) && vn_canvmio(vp) == FALSE) if (!vn_isdisk(vp, NULL) && vn_canvmio(vp) == FALSE)
return (0); return (0);
retry: while ((object = vp->v_object) != NULL) {
if ((object = vp->v_object) == NULL) { VM_OBJECT_LOCK(object);
if (vp->v_type == VREG || vp->v_type == VDIR) { if (!(object->flags & OBJ_DEAD)) {
if ((error = VOP_GETATTR(vp, &vat, cred, td)) != 0) VM_OBJECT_UNLOCK(object);
goto retn; break;
object = vnode_pager_alloc(vp, vat.va_size, 0, 0); }
} else if (vn_isdisk(vp, NULL)) { 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 * This simply allocates the biggest object possible
* for a disk vnode. This should be fixed, but doesn't * for a disk vnode. This should be fixed, but doesn't
* cause any problems (yet). * cause any problems (yet).
*/ */
object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX), 0, 0); size = IDX_TO_OFF(INT_MAX);
} else { } else {
goto retn; 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 * Dereference the reference we just created. This assumes
* that the object is associated with the vp. * that the object is associated with the vp.
@ -421,23 +433,11 @@ retry:
object->ref_count--; object->ref_count--;
VM_OBJECT_UNLOCK(object); VM_OBJECT_UNLOCK(object);
vrele(vp); vrele(vp);
} else {
VM_OBJECT_LOCK(object);
if (object->flags & OBJ_DEAD) {
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);
goto retry;
}
VM_OBJECT_UNLOCK(object);
} }
KASSERT(vp->v_object != NULL, ("vfs_object_create: NULL object")); KASSERT(vp->v_object != NULL, ("vfs_object_create: NULL object"));
vp->v_vflag |= VV_OBJBUF; vp->v_vflag |= VV_OBJBUF;
retn:
return (error); return (error);
} }