Exemplo n.º 1
0
/*ARGSUSED*/
static void
socket_vop_inactive(struct vnode *vp, struct cred *cr, caller_context_t *ct)
{
	struct sonode *so = VTOSO(vp);

	ASSERT(vp->v_type == VSOCK);

	mutex_enter(&vp->v_lock);
	/*
	 * If no one has reclaimed the vnode, remove from the
	 * cache now.
	 */
	if (vp->v_count < 1)
		cmn_err(CE_PANIC, "socket_inactive: Bad v_count");

	VN_RELE_LOCKED(vp);
	if (vp->v_count != 0) {
		mutex_exit(&vp->v_lock);
		return;
	}
	mutex_exit(&vp->v_lock);


	ASSERT(!vn_has_cached_data(vp));

	/* socket specfic clean-up */
	socket_destroy_internal(so, cr);
}
Exemplo n.º 2
0
/*ARGSUSED*/
int
spec_sync(struct vfs *vfsp,
	short	flag,
	struct cred *cr)
{
	struct snode *sync_list;
	register struct snode **spp, *sp, *spnext;
	register struct vnode *vp;

	if (mutex_tryenter(&spec_syncbusy) == 0)
		return (0);

	if (flag & SYNC_ATTR) {
		mutex_exit(&spec_syncbusy);
		return (0);
	}
	mutex_enter(&stable_lock);
	sync_list = NULL;
	/*
	 * Find all the snodes that are dirty and add them to the sync_list
	 */
	for (spp = stable; spp < &stable[STABLESIZE]; spp++) {
		for (sp = *spp; sp != NULL; sp = sp->s_next) {
			vp = STOV(sp);
			/*
			 * Don't bother sync'ing a vp if it's
			 * part of a virtual swap device.
			 */
			if (IS_SWAPVP(vp))
				continue;

			if (vp->v_type == VBLK && vn_has_cached_data(vp)) {
				/*
				 * Prevent vp from going away before we
				 * we get a chance to do a VOP_PUTPAGE
				 * via sync_list processing
				 */
				VN_HOLD(vp);
				sp->s_list = sync_list;
				sync_list = sp;
			}
		}
	}
	mutex_exit(&stable_lock);
	/*
	 * Now write out all the snodes we marked asynchronously.
	 */
	for (sp = sync_list; sp != NULL; sp = spnext) {
		spnext = sp->s_list;
		vp = STOV(sp);
		(void) VOP_PUTPAGE(vp, (offset_t)0, (uint_t)0, B_ASYNC, cr);
		VN_RELE(vp);		/* Release our hold on vnode */
	}
	mutex_exit(&spec_syncbusy);
	return (0);
}
Exemplo n.º 3
0
int
syncpcp(struct pcnode *pcp, int flags)
{
	int err;
	if (!vn_has_cached_data(PCTOV(pcp)))
		err = 0;
	else
		err = VOP_PUTPAGE(PCTOV(pcp), 0, 0, flags,
		    kcred, NULL);

	return (err);
}
Exemplo n.º 4
0
void
pc_rele(struct pcnode *pcp)
{
	struct pcfs *fsp;
	struct vnode *vp;
	int err;

	vp = PCTOV(pcp);
	PC_DPRINTF1(8, "pc_rele vp=0x%p\n", (void *)vp);

	fsp = VFSTOPCFS(vp->v_vfsp);
	ASSERT(fsp->pcfs_flags & PCFS_LOCKED);

	rw_enter(&pcnodes_lock, RW_WRITER);
	pcp->pc_flags |= PC_RELEHOLD;

retry:
	if (vp->v_type != VDIR && (pcp->pc_flags & PC_INVAL) == 0) {
		/*
		 * If the file was removed while active it may be safely
		 * truncated now.
		 */

		if (pcp->pc_entry.pcd_filename[0] == PCD_ERASED) {
			(void) pc_truncate(pcp, 0);
		} else if (pcp->pc_flags & PC_CHG) {
			(void) pc_nodeupdate(pcp);
		}
		err = syncpcp(pcp, B_INVAL);
		if (err) {
			(void) syncpcp(pcp, B_INVAL | B_FORCE);
		}
	}
	if (vn_has_cached_data(vp)) {
		/*
		 * pvn_vplist_dirty will abort all old pages
		 */
		(void) pvn_vplist_dirty(vp, (u_offset_t)0,
		    pcfs_putapage, B_INVAL, (struct cred *)NULL);
	}

	(void) pc_syncfat(fsp);
	mutex_enter(&vp->v_lock);
	if (vn_has_cached_data(vp)) {
		mutex_exit(&vp->v_lock);
		goto retry;
	}
	ASSERT(!vn_has_cached_data(vp));

	vp->v_count--;  /* release our hold from vn_rele */
	if (vp->v_count > 0) { /* Is this check still needed? */
		PC_DPRINTF1(3, "pc_rele: pcp=0x%p HELD AGAIN!\n", (void *)pcp);
		mutex_exit(&vp->v_lock);
		pcp->pc_flags &= ~PC_RELEHOLD;
		rw_exit(&pcnodes_lock);
		return;
	}

	remque(pcp);
	rw_exit(&pcnodes_lock);
	/*
	 * XXX - old code had a check for !(pcp->pc_flags & PC_INVAL)
	 * here. Seems superfluous/incorrect, but then earlier on PC_INVAL
	 * was never set anywhere in PCFS. Now it is, and we _have_ to drop
	 * the file reference here. Else, we'd screw up umount/modunload.
	 */
	if ((vp->v_type == VREG)) {
		fsp->pcfs_frefs--;
	}
	fsp->pcfs_nrefs--;
	VFS_RELE(vp->v_vfsp);

	if (fsp->pcfs_nrefs < 0) {
		panic("pc_rele: nrefs count");
	}
	if (fsp->pcfs_frefs < 0) {
		panic("pc_rele: frefs count");
	}

	mutex_exit(&vp->v_lock);
	vn_invalid(vp);
	vn_free(vp);
	kmem_free(pcp, sizeof (struct pcnode));
}
Exemplo n.º 5
0
/************************************************************************
 * iumfs_free_node()
 *
 *   指定された vnode および iumnode を解放する
 *
 *     1. iumnode に関連づいたリソースを解放
 *     2. iumnode 構造体を解放
 *     3. vnode 構造体を解放
 *
 *   これが呼ばれるのは、iumfs_inactive() もしくは iumfs_unmount() 経由の
 *   iumfs_free_all_node() だけ。つまり、v_count が 1(未参照状態)である
 *   事が確かな場合だけ。
 *
 * 引数:
 *
 *     vp: 解放する vnode 構造体のポインタ
 *     cr    : システムコールを呼び出したユーザのクレデンシャル
 *
 * 戻り値:
 *     無し
 *
 ************************************************************************/
void
iumfs_free_node(vnode_t *vp, struct cred *cr)
{
    iumnode_t *inp; // ファイルシステム型依存のノード情報(iumnode構造体)
    vnode_t *rootvp; // ファイルシステムのルートディレクトリの vnode。
    iumfs_t *iumfsp; // ファイルシステム型依存のプライベートデータ構造体
    vfs_t *vfsp; // ファイルシステム構造体
    int err;

    DEBUG_PRINT((CE_CONT, "iumfs_free_node is called\n"));

    iumfsp = VNODE2IUMFS(vp);
    vfsp = VNODE2VFS(vp);
    inp = VNODE2IUMNODE(vp);

    DEBUG_PRINT((CE_CONT, "iumfs_free_node: vnode=%p, vp->v_count=%d\n", vp, vp->v_count));

    /*
     * 最初にノードリンクリストから iumnode をはずす。誰かが利用中(EBUSY)だったらリターン。
     * 仮にノードリストに入っていなかったとしても、(ありえないはずだが) vnode のフリーは行う。
     */
    if((err = iumfs_remove_node_from_list(vfsp, vp)) != 0){
        if (err == ENOENT)
            cmn_err(CE_CONT, "iumfs_free_node: can't find vnode in the list. Free it anyway.\n");
        else
            return;
    }

    // debug 用
    rootvp = VNODE2ROOT(vp);
    if (rootvp != NULL && VN_CMP(rootvp, vp) != 0) {
        DEBUG_PRINT((CE_CONT, "iumfs_free_node: rootvnode is being freed\n"));
        mutex_enter(&(iumfsp->iumfs_lock));
        iumfsp->rootvnode = NULL;
        mutex_exit(&(iumfsp->iumfs_lock));
    }

    /*
     * もし iumnode にデータ(ディレクトリエントリ等)
     * を含んでいたらそれらも解放する。
     */
    if (inp->data != NULL) {
        kmem_free(inp->data, inp->dlen);
    }

    /*
     * この vnode に関連した page を無効にする
     */
    err = pvn_vplist_dirty(vp, 0, iumfs_putapage, B_INVAL, cr);
    DEBUG_PRINT((CE_CONT, "iumfs_free_node: pvn_vplist_dirty returned with (%d)\n", err));
    if (vn_has_cached_data(vp)) {
        cmn_err(CE_WARN, "iumfs_free_node: vnode still have cached\n");        
    } 

    // iumnode を解放
    mutex_destroy(&(inp)->i_dlock);
    rw_destroy(&(inp)->i_listlock);
    kmem_free(inp, sizeof (iumnode_t));

    // vnode を解放
#ifdef SOL10
    vn_free(vp);
#else
    mutex_destroy(&(vp)->v_lock);
    kmem_free(vp, sizeof (vnode_t));
#endif                
    DEBUG_PRINT((CE_CONT, "iumfs_free_node: return\n"));
    return;
}