Instead of having lfs muck directly about with vnode free lists,
introduce vrele2(), which allows to release vnodes the way lfs sometimes wants it: + without calling inactive + inserting the vnode at the head of the freelist (this is a very questionable optimization that isn't even enabled by default, but I went along with the same semantics for now)
This commit is contained in:
parent
dfeea3487b
commit
3de9f5d391
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vfs_subr.c,v 1.297 2007/08/06 17:09:11 pooka Exp $ */
|
||||
/* $NetBSD: vfs_subr.c,v 1.298 2007/08/09 08:51:21 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 2004, 2005 The NetBSD Foundation, Inc.
|
||||
@ -84,7 +84,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.297 2007/08/06 17:09:11 pooka Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.298 2007/08/09 08:51:21 pooka Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ddb.h"
|
||||
@ -1129,8 +1129,8 @@ vput(struct vnode *vp)
|
||||
* Vnode release.
|
||||
* If count drops to zero, call inactive routine and return to freelist.
|
||||
*/
|
||||
void
|
||||
vrele(struct vnode *vp)
|
||||
static void
|
||||
do_vrele(struct vnode *vp, int doinactive, int onhead)
|
||||
{
|
||||
struct lwp *l = curlwp; /* XXX */
|
||||
|
||||
@ -1154,18 +1154,41 @@ vrele(struct vnode *vp)
|
||||
* Insert at tail of LRU list.
|
||||
*/
|
||||
simple_lock(&vnode_free_list_slock);
|
||||
if (vp->v_holdcnt > 0)
|
||||
if (vp->v_holdcnt > 0) {
|
||||
TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
|
||||
} else {
|
||||
if (onhead)
|
||||
TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
|
||||
else
|
||||
TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
|
||||
}
|
||||
simple_unlock(&vnode_free_list_slock);
|
||||
if (vp->v_flag & VEXECMAP) {
|
||||
uvmexp.execpages -= vp->v_uobj.uo_npages;
|
||||
uvmexp.filepages += vp->v_uobj.uo_npages;
|
||||
}
|
||||
vp->v_flag &= ~(VTEXT|VEXECMAP|VWRITEMAP|VMAPPED);
|
||||
|
||||
if (doinactive) {
|
||||
if (vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK) == 0)
|
||||
VOP_INACTIVE(vp, l);
|
||||
} else {
|
||||
simple_unlock(&vp->v_interlock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vrele(struct vnode *vp)
|
||||
{
|
||||
|
||||
do_vrele(vp, 1, 0);
|
||||
}
|
||||
|
||||
void
|
||||
vrele2(struct vnode *vp, int onhead)
|
||||
{
|
||||
|
||||
do_vrele(vp, 0, onhead);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vnode.h,v 1.170 2007/06/29 23:30:32 rumble Exp $ */
|
||||
/* $NetBSD: vnode.h,v 1.171 2007/08/09 08:51:21 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -533,6 +533,7 @@ void vprint(const char *, struct vnode *);
|
||||
void vput(struct vnode *);
|
||||
int vrecycle(struct vnode *, struct simplelock *, struct lwp *);
|
||||
void vrele(struct vnode *);
|
||||
void vrele2(struct vnode *, int);
|
||||
int vtruncbuf(struct vnode *, daddr_t, int, int);
|
||||
void vwakeup(struct buf *);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lfs_segment.c,v 1.203 2007/07/29 13:31:14 ad Exp $ */
|
||||
/* $NetBSD: lfs_segment.c,v 1.204 2007/08/09 08:51:21 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
|
||||
@ -67,7 +67,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.203 2007/07/29 13:31:14 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.204 2007/08/09 08:51:21 pooka Exp $");
|
||||
|
||||
#ifdef DEBUG
|
||||
# define vndebug(vp, str) do { \
|
||||
@ -2742,31 +2742,8 @@ lfs_vunref(struct vnode *vp)
|
||||
return;
|
||||
}
|
||||
|
||||
simple_lock(&vp->v_interlock);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (vp->v_usecount <= 0) {
|
||||
printf("lfs_vunref: inum is %llu\n", (unsigned long long)
|
||||
VTOI(vp)->i_number);
|
||||
printf("lfs_vunref: flags are 0x%lx\n", (u_long)vp->v_flag);
|
||||
printf("lfs_vunref: usecount = %ld\n", (long)vp->v_usecount);
|
||||
panic("lfs_vunref: v_usecount < 0");
|
||||
}
|
||||
#endif
|
||||
vp->v_usecount--;
|
||||
if (vp->v_usecount > 0) {
|
||||
simple_unlock(&vp->v_interlock);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* insert at tail of LRU list
|
||||
*/
|
||||
simple_lock(&vnode_free_list_slock);
|
||||
if (vp->v_holdcnt > 0)
|
||||
TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
|
||||
else
|
||||
TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_freelist);
|
||||
simple_unlock(&vnode_free_list_slock);
|
||||
simple_unlock(&vp->v_interlock);
|
||||
/* does not call inactive */
|
||||
vrele2(vp, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2782,27 +2759,9 @@ lfs_vunref_head(struct vnode *vp)
|
||||
{
|
||||
|
||||
ASSERT_SEGLOCK(VTOI(vp)->i_lfs);
|
||||
simple_lock(&vp->v_interlock);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (vp->v_usecount == 0) {
|
||||
panic("lfs_vunref: v_usecount<0");
|
||||
}
|
||||
#endif
|
||||
vp->v_usecount--;
|
||||
if (vp->v_usecount > 0) {
|
||||
simple_unlock(&vp->v_interlock);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* insert at head of LRU list
|
||||
*/
|
||||
simple_lock(&vnode_free_list_slock);
|
||||
if (vp->v_holdcnt > 0)
|
||||
TAILQ_INSERT_TAIL(&vnode_hold_list, vp, v_freelist);
|
||||
else
|
||||
TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
|
||||
simple_unlock(&vnode_free_list_slock);
|
||||
simple_unlock(&vp->v_interlock);
|
||||
|
||||
/* does not call inactive, inserts non-held vnode at head of freelist */
|
||||
vrele2(vp, 1);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user