Beispiel #1
0
/*
 * Reclaim an inode so that it can be used for other purposes.
 */
int
ffs_reclaim(void *v)
{
	struct vop_reclaim_args /* {
		struct vnode *a_vp;
		struct lwp *a_l;
	} */ *ap = v;
	struct vnode *vp = ap->a_vp;
	struct inode *ip = VTOI(vp);
	struct mount *mp = vp->v_mount;
	struct ufsmount *ump = ip->i_ump;
	void *data;
	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).
	 */
	error = UFS_WAPBL_BEGIN(mp);
	if (error) {
		fstrans_done(mp);
		return error;
	}
	if (ip->i_nlink <= 0 && ip->i_omode != 0 &&
	    (vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
		ffs_vfree(vp, ip->i_number, ip->i_omode);
	UFS_WAPBL_END(mp);
	if ((error = ufs_reclaim(vp)) != 0) {
		fstrans_done(mp);
		return (error);
	}
	if (ip->i_din.ffs1_din != NULL) {
		if (ump->um_fstype == UFS1)
			pool_cache_put(ffs_dinode1_cache, ip->i_din.ffs1_din);
		else
			pool_cache_put(ffs_dinode2_cache, ip->i_din.ffs2_din);
	}
	/*
	 * To interlock with ffs_sync().
	 */
	genfs_node_destroy(vp);
	mutex_enter(vp->v_interlock);
	data = vp->v_data;
	vp->v_data = NULL;
	mutex_exit(vp->v_interlock);

	/*
	 * XXX MFS ends up here, too, to free an inode.  Should we create
	 * XXX a separate pool for MFS inodes?
	 */
	pool_cache_put(ffs_inode_cache, data);
	fstrans_done(mp);
	return (0);
}
Beispiel #2
0
/*
 * Last reference to an inode.  If necessary, write or delete it.
 *
 * ufs_inactive(struct vnode *a_vp)
 */
int
ufs_inactive(struct vop_inactive_args *ap)
{
	struct vnode *vp = ap->a_vp;
	struct inode *ip = VTOI(vp);
	int mode, error = 0;

	if (prtactive && VREFCNT(vp) > 1)
		vprint("ufs_inactive: pushing active", vp);

	/*
	 * Ignore inodes related to stale file handles.
	 */
	if (ip == NULL || ip->i_mode == 0)
		goto out;
	if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
#ifdef QUOTA
		if (!ufs_getinoquota(ip))
			(void)ufs_chkiq(ip, -1, NOCRED, FORCE);
#endif
		/* Must have a VM object to truncate */
		error = ffs_truncate(vp, (off_t)0, 0, NOCRED);
		ip->i_rdev = 0;
		mode = ip->i_mode;
		ip->i_mode = 0;
		ip->i_flag |= IN_CHANGE | IN_UPDATE;
		ffs_vfree(vp, ip->i_number, mode);
	}
	if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE))
		ffs_update(vp, 0);
out:
	/*
	 * If we are done with the inode, reclaim it
	 * so that it can be reused immediately.
	 */
	if (ip == NULL || ip->i_mode == 0)
		vrecycle(vp);
	return (error);
}