Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_subr.c
Show First 20 Lines • Show All 3,458 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* vgone, with the vp interlock held. | * vgone, with the vp interlock held. | ||||
*/ | */ | ||||
static void | static void | ||||
vgonel(struct vnode *vp) | vgonel(struct vnode *vp) | ||||
{ | { | ||||
struct thread *td; | struct thread *td; | ||||
int oweinact; | |||||
int active; | |||||
struct mount *mp; | struct mount *mp; | ||||
vm_object_t object; | |||||
bool active, oweinact; | |||||
ASSERT_VOP_ELOCKED(vp, "vgonel"); | ASSERT_VOP_ELOCKED(vp, "vgonel"); | ||||
ASSERT_VI_LOCKED(vp, "vgonel"); | ASSERT_VI_LOCKED(vp, "vgonel"); | ||||
VNASSERT(vp->v_holdcnt, vp, | VNASSERT(vp->v_holdcnt, vp, | ||||
("vgonel: vp %p has no reference.", vp)); | ("vgonel: vp %p has no reference.", vp)); | ||||
CTR2(KTR_VFS, "%s: vp %p", __func__, vp); | CTR2(KTR_VFS, "%s: vp %p", __func__, vp); | ||||
td = curthread; | td = curthread; | ||||
/* | /* | ||||
* Don't vgonel if we're already doomed. | * Don't vgonel if we're already doomed. | ||||
*/ | */ | ||||
if (vp->v_iflag & VI_DOOMED) | if (vp->v_iflag & VI_DOOMED) | ||||
return; | return; | ||||
vp->v_iflag |= VI_DOOMED; | vp->v_iflag |= VI_DOOMED; | ||||
/* | /* | ||||
* Check to see if the vnode is in use. If so, we have to call | * Check to see if the vnode is in use. If so, we have to call | ||||
* VOP_CLOSE() and VOP_INACTIVE(). | * VOP_CLOSE() and VOP_INACTIVE(). | ||||
*/ | */ | ||||
active = vp->v_usecount; | active = vp->v_usecount > 0; | ||||
oweinact = (vp->v_iflag & VI_OWEINACT); | oweinact = (vp->v_iflag & VI_OWEINACT) != 0; | ||||
VI_UNLOCK(vp); | VI_UNLOCK(vp); | ||||
vfs_notify_upper(vp, VFS_NOTIFY_UPPER_RECLAIM); | vfs_notify_upper(vp, VFS_NOTIFY_UPPER_RECLAIM); | ||||
/* | /* | ||||
* If purging an active vnode, it must be closed and | * If purging an active vnode, it must be closed and | ||||
* deactivated before being reclaimed. | * deactivated before being reclaimed. | ||||
*/ | */ | ||||
if (active) | if (active) | ||||
Show All 22 Lines | vgonel(struct vnode *vp) | ||||
BO_LOCK(&vp->v_bufobj); | BO_LOCK(&vp->v_bufobj); | ||||
KASSERT(TAILQ_EMPTY(&vp->v_bufobj.bo_dirty.bv_hd) && | KASSERT(TAILQ_EMPTY(&vp->v_bufobj.bo_dirty.bv_hd) && | ||||
vp->v_bufobj.bo_dirty.bv_cnt == 0 && | vp->v_bufobj.bo_dirty.bv_cnt == 0 && | ||||
TAILQ_EMPTY(&vp->v_bufobj.bo_clean.bv_hd) && | TAILQ_EMPTY(&vp->v_bufobj.bo_clean.bv_hd) && | ||||
vp->v_bufobj.bo_clean.bv_cnt == 0, | vp->v_bufobj.bo_clean.bv_cnt == 0, | ||||
("vp %p bufobj not invalidated", vp)); | ("vp %p bufobj not invalidated", vp)); | ||||
/* | /* | ||||
* For VMIO bufobj, BO_DEAD is set in vm_object_terminate() | * For VMIO bufobj, BO_DEAD is set later, or in | ||||
* after the object's page queue is flushed. | * vm_object_terminate() after the object's page queue is | ||||
* flushed. | |||||
*/ | */ | ||||
if (vp->v_bufobj.bo_object == NULL) | object = vp->v_bufobj.bo_object; | ||||
if (object == NULL) | |||||
vp->v_bufobj.bo_flag |= BO_DEAD; | vp->v_bufobj.bo_flag |= BO_DEAD; | ||||
BO_UNLOCK(&vp->v_bufobj); | BO_UNLOCK(&vp->v_bufobj); | ||||
/* | |||||
* Handle the VM part. Tmpfs handles v_object on its own (the | |||||
* OBJT_VNODE check). Nullfs or other bypassing filesystems | |||||
* should not touch the object borrowed from the lower vnode | |||||
* (the handle check). | |||||
*/ | |||||
if (object != NULL && object->type == OBJT_VNODE && | |||||
object->handle == vp) | |||||
vnode_destroy_vobject(vp); | |||||
/* | /* | ||||
* Reclaim the vnode. | * Reclaim the vnode. | ||||
*/ | */ | ||||
if (VOP_RECLAIM(vp, td)) | if (VOP_RECLAIM(vp, td)) | ||||
panic("vgone: cannot reclaim"); | panic("vgone: cannot reclaim"); | ||||
if (mp != NULL) | if (mp != NULL) | ||||
vn_finished_secondary_write(mp); | vn_finished_secondary_write(mp); | ||||
▲ Show 20 Lines • Show All 2,177 Lines • Show Last 20 Lines |