Example #1
0
/*
 *	Routine:	macx_swapoff
 *	Function:
 *		Syscall interface to remove a file from backing store
 */
int
macx_swapoff(
	struct macx_swapoff_args *args)
{
	__unused int	flags = args->flags;
	kern_return_t	kr;
	mach_port_t	backing_store;

	struct vnode		*vp = 0; 
	struct nameidata 	nd, *ndp;
	struct proc		*p =  current_proc();
	int			i;
	int			error;
	boolean_t		funnel_state;
	vfs_context_t ctx = vfs_context_current();

	AUDIT_MACH_SYSCALL_ENTER(AUE_SWAPOFF);

	funnel_state = thread_funnel_set(kernel_flock, TRUE);
	backing_store = NULL;
	ndp = &nd;

	if ((error = suser(kauth_cred_get(), 0)))
		goto swapoff_bailout;

	/*
	 * Get the vnode for the paging area.
	 */
	NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNPATH1,
	       ((IS_64BIT_PROCESS(p)) ? UIO_USERSPACE64 : UIO_USERSPACE32),
	       (user_addr_t) args->filename, ctx);

	if ((error = namei(ndp)))
		goto swapoff_bailout;
	nameidone(ndp);
	vp = ndp->ni_vp;

	if (vp->v_type != VREG) {
		error = EINVAL;
		goto swapoff_bailout;
	}
#if CONFIG_MACF
	vnode_lock(vp);
	error = mac_system_check_swapoff(vfs_context_ucred(ctx), vp);
	vnode_unlock(vp);
	if (error)
		goto swapoff_bailout;
#endif

	for(i = 0; i < MAX_BACKING_STORE; i++) {
		if(bs_port_table[i].vp == vp) {
			break;
		}
	}
	if (i == MAX_BACKING_STORE) {
		error = EINVAL;
		goto swapoff_bailout;
	}
	backing_store = (mach_port_t)bs_port_table[i].bs;

	kr = default_pager_backing_store_delete(backing_store);
	switch (kr) {
		case KERN_SUCCESS:
			error = 0;
			bs_port_table[i].vp = 0;
			/* This vnode is no longer used for swapfile */
			vnode_lock_spin(vp);
			CLR(vp->v_flag, VSWAP);
			vnode_unlock(vp);

			/* get rid of macx_swapon() "long term" reference */
			vnode_rele(vp);

			break;
		case KERN_FAILURE:
			error = EAGAIN;
			break;
		default:
			error = EAGAIN;
			break;
	}

swapoff_bailout:
	/* get rid of macx_swapoff() namei() reference */
	if (vp)
		vnode_put(vp);

	(void) thread_funnel_set(kernel_flock, FALSE);
	AUDIT_MACH_SYSCALL_EXIT(error);
	return(error);
}
Example #2
0
/*
 *	Routine:	macx_swapoff
 *	Function:
 *		Syscall interface to remove a file from backing store
 */
int
macx_swapoff(
    char 	*filename,
    int	flags)
{
    kern_return_t	kr;
    mach_port_t	backing_store;

    struct vnode		*vp = 0;
    struct nameidata 	nd, *ndp;
    struct proc		*p =  current_proc();
    int			i;
    int			error;
    boolean_t		funnel_state;

    AUDIT_MACH_SYSCALL_ENTER(AUE_SWAPOFF);
    funnel_state = thread_funnel_set(kernel_flock, TRUE);
    backing_store = NULL;
    ndp = &nd;

    if ((error = suser(p->p_ucred, &p->p_acflag)))
        goto swapoff_bailout;

    /*
     * Get the vnode for the paging area.
     */
    NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNPATH1, UIO_USERSPACE,
           filename, p);

    if ((error = namei(ndp)))
        goto swapoff_bailout;
    vp = ndp->ni_vp;

    if (vp->v_type != VREG) {
        error = EINVAL;
        VOP_UNLOCK(vp, 0, p);
        goto swapoff_bailout;
    }

    for(i = 0; i < MAX_BACKING_STORE; i++) {
        if(bs_port_table[i].vp == vp) {
            backing_store;
            break;
        }
    }
    if (i == MAX_BACKING_STORE) {
        error = EINVAL;
        VOP_UNLOCK(vp, 0, p);
        goto swapoff_bailout;
    }
    backing_store = (mach_port_t)bs_port_table[i].bs;

    VOP_UNLOCK(vp, 0, p);
    kr = default_pager_backing_store_delete(backing_store);
    switch (kr) {
    case KERN_SUCCESS:
        error = 0;
        bs_port_table[i].vp = 0;
        ubc_rele(vp);
        /* This vnode is no longer used for swapfile */
        CLR(vp->v_flag, VSWAP);

        /* get rid of macx_swapon() namei() reference */
        vrele(vp);

        /* get rid of macx_swapon() "extra" reference */
        vrele(vp);
        break;
    case KERN_FAILURE:
        error = EAGAIN;
        break;
    default:
        error = EAGAIN;
        break;
    }

swapoff_bailout:
    /* get rid of macx_swapoff() namei() reference */
    if (vp)
        vrele(vp);

    (void) thread_funnel_set(kernel_flock, FALSE);
    AUDIT_MACH_SYSCALL_EXIT(error);
    return(error);
}