diff options
author | bp <bp@FreeBSD.org> | 2000-09-12 09:49:08 +0000 |
---|---|---|
committer | bp <bp@FreeBSD.org> | 2000-09-12 09:49:08 +0000 |
commit | a7bc78c86d1b25efbea8d9ad3e7354ef3a302e90 (patch) | |
tree | ae6a2a75d2b0d94e115a73fd536dca86dba92ac4 /sys/kern/vfs_subr.c | |
parent | 7893328799a796677510cba9c7bbb8e52d8ce56c (diff) | |
download | FreeBSD-src-a7bc78c86d1b25efbea8d9ad3e7354ef3a302e90.zip FreeBSD-src-a7bc78c86d1b25efbea8d9ad3e7354ef3a302e90.tar.gz |
Add three new VOPs: VOP_CREATEVOBJECT, VOP_DESTROYVOBJECT and VOP_GETVOBJECT.
They will be used by nullfs and other stacked filesystems to support full
cache coherency.
Reviewed in general by: mckusick, dillon
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r-- | sys/kern/vfs_subr.c | 82 |
1 files changed, 11 insertions, 71 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 52ad0ef..bebc3c9 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -484,10 +484,9 @@ getnewvnode(tag, mp, vops, vpp) * if it still has cached pages or we cannot get * its interlock. */ - object = vp->v_object; if (LIST_FIRST(&vp->v_cache_src) != NULL || - (object && (object->resident_page_count || - object->ref_count)) || + (VOP_GETVOBJECT(vp, &object) == 0 && + (object->resident_page_count || object->ref_count)) || !simple_lock_try(&vp->v_interlock)) { TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist); vp = NULL; @@ -711,8 +710,7 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo) * Destroy the copy in the VM cache, too. */ simple_lock(&vp->v_interlock); - object = vp->v_object; - if (object != NULL) { + if (VOP_GETVOBJECT(vp, &object) == 0) { vm_object_page_remove(object, 0, 0, (flags & V_SAVE) ? TRUE : FALSE); } @@ -1649,7 +1647,6 @@ vclean(vp, flags, p) struct proc *p; { int active; - vm_object_t obj; /* * Check to see if the vnode is in use. If so we have to reference it @@ -1686,22 +1683,7 @@ vclean(vp, flags, p) vinvalbuf(vp, 0, NOCRED, p, 0, 0); } - if ((obj = vp->v_object) != NULL) { - if (obj->ref_count == 0) { - /* - * vclean() may be called twice. The first time - * removes the primary reference to the object, - * the second time goes one further and is a - * special-case to terminate the object. - */ - vm_object_terminate(obj); - } else { - /* - * Woe to the process that tries to page now :-). - */ - vm_pager_deallocate(obj); - } - } + VOP_DESTROYVOBJECT(vp); /* * If purging an active vnode, it must be closed and @@ -2523,20 +2505,20 @@ loop: continue; if (flags != MNT_WAIT) { - obj = vp->v_object; - if (obj == NULL || (obj->flags & OBJ_MIGHTBEDIRTY) == 0) + if (VOP_GETVOBJECT(vp, &obj) != 0 || + (obj->flags & OBJ_MIGHTBEDIRTY) == 0) continue; if (VOP_ISLOCKED(vp, NULL)) continue; } simple_lock(&vp->v_interlock); - if (vp->v_object && - (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) { + if (VOP_GETVOBJECT(vp, &obj) == 0 && + (obj->flags & OBJ_MIGHTBEDIRTY)) { if (!vget(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) { - if (vp->v_object) { - vm_object_page_clean(vp->v_object, 0, 0, flags == MNT_WAIT ? OBJPC_SYNC : OBJPC_NOSYNC); + if (VOP_GETVOBJECT(vp, &obj) == 0) { + vm_object_page_clean(obj, 0, 0, flags == MNT_WAIT ? OBJPC_SYNC : OBJPC_NOSYNC); anyio = 1; } vput(vp); @@ -2563,49 +2545,7 @@ vfs_object_create(vp, p, cred) struct proc *p; struct ucred *cred; { - struct vattr vat; - vm_object_t object; - int error = 0; - - if (!vn_isdisk(vp, NULL) && vn_canvmio(vp) == FALSE) - return 0; - -retry: - if ((object = vp->v_object) == NULL) { - if (vp->v_type == VREG || vp->v_type == VDIR) { - if ((error = VOP_GETATTR(vp, &vat, cred, p)) != 0) - goto retn; - object = vnode_pager_alloc(vp, vat.va_size, 0, 0); - } else if (devsw(vp->v_rdev) != NULL) { - /* - * This simply allocates the biggest object possible - * for a disk vnode. This should be fixed, but doesn't - * cause any problems (yet). - */ - object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX), 0, 0); - } else { - goto retn; - } - /* - * Dereference the reference we just created. This assumes - * that the object is associated with the vp. - */ - object->ref_count--; - vp->v_usecount--; - } else { - if (object->flags & OBJ_DEAD) { - VOP_UNLOCK(vp, 0, p); - tsleep(object, PVM, "vodead", 0); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); - goto retry; - } - } - - KASSERT(vp->v_object != NULL, ("vfs_object_create: NULL object")); - vp->v_flag |= VOBJBUF; - -retn: - return error; + return (VOP_CREATEVOBJECT(vp, cred, p)); } void |