Go back to freeing on disk inodes in the inactive routine. It would be

better not to do this, but it rules out potential side effects with softdep.
This commit is contained in:
ad 2008-01-09 16:15:22 +00:00
parent 00e40eb383
commit 0b52913dee
9 changed files with 67 additions and 75 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_subr.c,v 1.311 2008/01/07 16:12:55 ad Exp $ */
/* $NetBSD: vfs_subr.c,v 1.312 2008/01/09 16:15:22 ad Exp $ */
/*-
* Copyright (c) 1997, 1998, 2004, 2005, 2007 The NetBSD Foundation, Inc.
@ -82,7 +82,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.311 2008/01/07 16:12:55 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.312 2008/01/09 16:15:22 ad Exp $");
#include "opt_inet.h"
#include "opt_ddb.h"
@ -825,15 +825,15 @@ vget(vnode_t *vp, int flags)
/*
* If the vnode is in the process of being cleaned out for
* another use, we wait for the cleaning to finish and then
* return failure. Cleaning is determined by checking that
* the VI_XLOCK flag is set.
* return failure. Cleaning is determined by checking if
* the VI_XLOCK or VI_FREEING flags are set.
*/
if ((vp->v_iflag & VI_XLOCK) != 0) {
if ((vp->v_iflag & (VI_XLOCK | VI_FREEING)) != 0) {
if (flags & LK_NOWAIT) {
mutex_exit(&vp->v_interlock);
return EBUSY;
}
vwait(vp, VI_XLOCK);
vwait(vp, VI_XLOCK | VI_FREEING);
vrelel(vp, 1, 0);
return (ENOENT);
}
@ -954,24 +954,31 @@ vrelel(vnode_t *vp, int doinactive, int onhead)
}
/*
* The vnode may gain another reference while being
* deactivated. Note that VOP_INACTIVE() will drop
* the vnode lock.
* The vnode can gain another reference while being
* deactivated. If VOP_INACTIVE() indicates that
* the described file has been deleted, then recycle
* the vnode irrespective of additional references.
* Another thread may be waiting to re-use the on-disk
* inode.
*
* Note that VOP_INACTIVE() will drop the vnode lock.
*/
VOP_INACTIVE(vp, &recycle);
mutex_enter(&vp->v_interlock);
if (vp->v_usecount > 1) {
vp->v_usecount--;
mutex_exit(&vp->v_interlock);
return;
}
if (!recycle) {
if (vp->v_usecount > 1) {
vp->v_usecount--;
mutex_exit(&vp->v_interlock);
return;
}
/*
* If we grew another reference while VOP_INACTIVE()
* was underway, then retry.
*/
if ((vp->v_iflag & VI_INACTREDO) != 0) {
goto retry;
/*
* If we grew another reference while
* VOP_INACTIVE() was underway, retry.
*/
if ((vp->v_iflag & VI_INACTREDO) != 0) {
goto retry;
}
}
/* Take care of space accounting. */
@ -1377,7 +1384,7 @@ vclean(vnode_t *vp, int flags)
mutex_enter(&vp->v_interlock);
vp->v_vnlock = &vp->v_lock;
VN_KNOTE(vp, NOTE_REVOKE);
vp->v_iflag &= ~VI_XLOCK;
vp->v_iflag &= ~(VI_XLOCK | VI_FREEING);
vp->v_iflag |= VI_CLEAN;
vp->v_vflag &= ~VV_LOCKSWORK;
cv_broadcast(&vp->v_cv);

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_subr2.c,v 1.11 2008/01/07 12:50:38 ad Exp $ */
/* $NetBSD: vfs_subr2.c,v 1.12 2008/01/09 16:15:22 ad Exp $ */
/*-
* Copyright (c) 1997, 1998, 2004, 2005, 2007 The NetBSD Foundation, Inc.
@ -82,7 +82,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_subr2.c,v 1.11 2008/01/07 12:50:38 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_subr2.c,v 1.12 2008/01/09 16:15:22 ad Exp $");
#include "opt_ddb.h"
@ -687,7 +687,7 @@ vprint(const char *label, struct vnode *vp)
if (label != NULL)
printf("%s: ", label);
printf("vnode @ %p, flags (%s)\n\ttag %s(%d), type %s(%d), "
"usecount %d, writecount %ld, holdcount %ld\n"
"usecount %d, writecount %d, holdcount %d\n"
"\tfreelisthd %p, mount %p, data %p\n", vp, bf,
ARRAY_PRINT(vp->v_tag, vnode_tags), vp->v_tag,
ARRAY_PRINT(vp->v_type, vnode_types), vp->v_type,

View File

@ -1,4 +1,4 @@
/* $NetBSD: vnode.h,v 1.183 2008/01/09 08:18:12 elad Exp $ */
/* $NetBSD: vnode.h,v 1.184 2008/01/09 16:15:23 ad Exp $ */
/*
* Copyright (c) 1989, 1993
@ -113,15 +113,15 @@ TAILQ_HEAD(vnodelst, vnode);
struct vnode {
struct uvm_object v_uobj; /* i: the VM object */
kcondvar_t v_cv; /* i: synchronization */
int v_waitcnt; /* i: # waiters for VXLOCK */
voff_t v_size; /* i: size of file */
voff_t v_writesize; /* i: new size after write */
int v_iflag; /* i: VI_* flags */
int v_vflag; /* v: VV_* flags */
int v_uflag; /* u: VU_* flags */
int v_numoutput; /* i: # of pending writes */
long v_writecount; /* i: ref count of writers */
long v_holdcnt; /* i: page & buffer refs */
int v_writecount; /* i: ref count of writers */
int v_holdcnt; /* i: page & buffer refs */
int v_synclist_slot; /* s: synclist slot index */
struct mount *v_mount; /* v: ptr to vfs we are in */
int (**v_op)(void *); /* :: vnode operations vector */
TAILQ_ENTRY(vnode) v_freelist; /* f: vnode freelist */
@ -129,7 +129,6 @@ struct vnode {
TAILQ_ENTRY(vnode) v_mntvnodes; /* m: vnodes for mount point */
struct buflists v_cleanblkhd; /* x: clean blocklist head */
struct buflists v_dirtyblkhd; /* x: dirty blocklist head */
int v_synclist_slot; /* s: synclist slot index */
TAILQ_ENTRY(vnode) v_synclist; /* s: vnodes with dirty bufs */
LIST_HEAD(, namecache) v_dnclist; /* n: namecaches (children) */
LIST_HEAD(, namecache) v_nclist; /* n: namecaches (parent) */
@ -201,6 +200,7 @@ typedef struct vnode vnode_t;
#define VI_CLEAN 0x00080000 /* has been reclaimed */
#define VI_INACTPEND 0x00100000 /* inactivation is pending */
#define VI_INACTREDO 0x00200000 /* need to redo VOP_INACTIVE() */
#define VI_FREEING 0x00400000 /* vnode is being freed */
/*
* The third set are locked by the underlying file system.
@ -211,7 +211,8 @@ typedef struct vnode vnode_t;
#define VNODE_FLAGBITS \
"\20\1ROOT\2SYSTEM\3ISTTY\4MAPPED\5MPSAFE\6LOCKSWORK\11TEXT\12EXECMAP" \
"\13WRMAP\14WRMAPDIRTY\15XLOCK\16ALIASED\17ONWORKLST\20MARKER" \
"\22LAYER\23MAPPED\24CLEAN\25INACTPEND\26INACTREDO\31DIROP\32VU_SOFTDEP"
"\22LAYER\23MAPPED\24CLEAN\25INACTPEND\26INACTREDO\27FREEING" \
"\31DIROP\32SOFTDEP"
#define VSIZENOTSET ((voff_t)-1)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ext2fs_inode.c,v 1.63 2008/01/02 11:49:08 ad Exp $ */
/* $NetBSD: ext2fs_inode.c,v 1.64 2008/01/09 16:15:23 ad Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -65,7 +65,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ext2fs_inode.c,v 1.63 2008/01/02 11:49:08 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: ext2fs_inode.c,v 1.64 2008/01/09 16:15:23 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -160,9 +160,13 @@ ext2fs_inactive(void *v)
error = ext2fs_truncate(vp, (off_t)0, 0, NOCRED);
}
ip->i_e2fs_dtime = time_second;
ip->i_flag |= IN_CHANGE | IN_UPDATE | IN_MODIFIED;
ip->i_omode = 1;
} else if (ip->i_flag & (IN_CHANGE | IN_UPDATE | IN_MODIFIED)) {
ip->i_flag |= IN_CHANGE | IN_UPDATE;
mutex_enter(&vp->v_interlock);
vp->v_iflag |= VI_FREEING;
mutex_exit(&vp->v_interlock);
ext2fs_vfree(vp, ip->i_number, ip->i_e2fs_mode);
}
if (ip->i_flag & (IN_CHANGE | IN_UPDATE | IN_MODIFIED)) {
ext2fs_update(vp, NULL, NULL, 0);
}
out:

View File

@ -1,4 +1,4 @@
/* $NetBSD: ext2fs_vnops.c,v 1.78 2008/01/02 11:49:08 ad Exp $ */
/* $NetBSD: ext2fs_vnops.c,v 1.79 2008/01/09 16:15:23 ad Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.78 2008/01/02 11:49:08 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.79 2008/01/09 16:15:23 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -1487,13 +1487,6 @@ ext2fs_reclaim(void *v)
struct inode *ip = VTOI(vp);
int error;
/*
* The inode must be freed and updated before being removed
* from its hash chain. Other threads trying to gain a hold
* on the inode will be stalled because it is locked (VI_XLOCK).
*/
if (ip->i_omode == 1 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
ext2fs_vfree(vp, ip->i_number, ip->i_e2fs_mode);
if ((error = ufs_reclaim(vp)) != 0)
return (error);
if (ip->i_din.e2fs_din != NULL)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_inode.c,v 1.93 2008/01/02 11:49:09 ad Exp $ */
/* $NetBSD: ffs_inode.c,v 1.94 2008/01/09 16:15:23 ad Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_inode.c,v 1.93 2008/01/02 11:49:09 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_inode.c,v 1.94 2008/01/09 16:15:23 ad Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@ -124,15 +124,6 @@ ffs_update(struct vnode *vp, const struct timespec *acc,
}
ip->i_flag &= ~(IN_MODIFIED | IN_ACCESSED);
if (DOINGSOFTDEP(vp)) {
if (ip->i_omode != 0) {
/*
* XXX If the inode has been unlinked, wait
* for the update (and so dependencies) to
* flush. Ensures that the slate is clean
* when the inode is reused.
*/
waitfor |= UPDATE_WAIT;
}
softdep_update_inodeblock(ip, bp, waitfor);
} else if (ip->i_ffs_effnlink != ip->i_nlink)
panic("ffs_update: bad link cnt");

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_vnops.c,v 1.95 2008/01/03 19:28:49 ad Exp $ */
/* $NetBSD: ffs_vnops.c,v 1.96 2008/01/09 16:15:23 ad Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.95 2008/01/03 19:28:49 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_vnops.c,v 1.96 2008/01/09 16:15:23 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -469,14 +469,6 @@ ffs_reclaim(void *v)
int error;
fstrans_start(mp, FSTRANS_LAZY);
/*
* The inode must be freed and updated before being removed
* from its hash chain. Other threads trying to gain a hold
* on the inode will be stalled because it is locked (VI_XLOCK).
*/
if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
ffs_vfree(vp, ip->i_number, ip->i_omode);
}
if ((error = ufs_reclaim(vp)) != 0) {
fstrans_done(mp);
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: inode.h,v 1.50 2008/01/07 16:56:27 ad Exp $ */
/* $NetBSD: inode.h,v 1.51 2008/01/09 16:15:23 ad Exp $ */
/*
* Copyright (c) 1982, 1989, 1993
@ -128,7 +128,6 @@ struct inode {
int32_t i_gen; /* Generation number. */
u_int32_t i_uid; /* File owner. */
u_int32_t i_gid; /* File group. */
u_int16_t i_omode; /* Old mode, for ufs_reclaim */
struct dirhash *i_dirhash; /* Hashing for large directories */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs_inode.c,v 1.73 2008/01/03 02:23:27 pooka Exp $ */
/* $NetBSD: ufs_inode.c,v 1.74 2008/01/09 16:15:24 ad Exp $ */
/*
* Copyright (c) 1991, 1993
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ufs_inode.c,v 1.73 2008/01/03 02:23:27 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: ufs_inode.c,v 1.74 2008/01/09 16:15:24 ad Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@ -117,15 +117,17 @@ ufs_inactive(void *v)
DIP_ASSIGN(ip, rdev, 0);
mode = ip->i_mode;
ip->i_mode = 0;
ip->i_omode = mode;
DIP_ASSIGN(ip, mode, 0);
ip->i_flag |= IN_CHANGE | IN_UPDATE;
mutex_enter(&vp->v_interlock);
vp->v_iflag |= VI_FREEING;
mutex_exit(&vp->v_interlock);
if (DOINGSOFTDEP(vp))
softdep_change_linkcnt(ip);
/*
* Defer final inode free and update to ufs_reclaim().
*/
} else if (ip->i_flag & (IN_CHANGE | IN_UPDATE | IN_MODIFIED)) {
UFS_VFREE(vp, ip->i_number, mode);
}
if (ip->i_flag & (IN_CHANGE | IN_UPDATE | IN_MODIFIED)) {
UFS_UPDATE(vp, NULL, NULL, 0);
}
out:
@ -151,8 +153,11 @@ ufs_reclaim(struct vnode *vp)
vprint("ufs_reclaim: pushing active", vp);
UFS_UPDATE(vp, NULL, NULL, UPDATE_CLOSE);
ufs_ihashrem(ip);
/*
* Remove the inode from its hash chain.
*/
ufs_ihashrem(ip);
/*
* Purge old data structures associated with the inode.
*/