예제 #1
0
static void
callreclaim(struct puffs_mount *pmp, puffs_cookie_t ck)
{
    PUFFS_MSG_VARS(vn, reclaim);

    if (!EXISTSOP(pmp, RECLAIM))
        return;

    PUFFS_MSG_ALLOC(vn, reclaim);
    puffs_msg_setfaf(park_reclaim);
    puffs_msg_setinfo(park_reclaim, PUFFSOP_VN, PUFFS_VN_RECLAIM, ck);

    puffs_msg_enqueue(pmp, park_reclaim);
    PUFFS_MSG_RELEASE(reclaim);
}
예제 #2
0
파일: puffs_subr.c 프로젝트: Hooman3/minix
void
puffs_senderr(struct puffs_mount *pmp, int type, int error,
	const char *str, puffs_cookie_t ck)
{
	struct puffs_msgpark *park;
	struct puffs_error *perr;

	puffs_msgmem_alloc(sizeof(struct puffs_error), &park, (void *)&perr, 1);
	puffs_msg_setfaf(park);
	puffs_msg_setinfo(park, PUFFSOP_ERROR, type, ck);

	perr->perr_error = error;
	strlcpy(perr->perr_str, str, sizeof(perr->perr_str));

	puffs_msg_enqueue(pmp, park);
	puffs_msgmem_release(park);
}
예제 #3
0
static int
puffs_vnop_fsync(struct vop_fsync_args *ap)
{
    PUFFS_MSG_VARS(vn, fsync);
    struct vnode *vp = ap->a_vp;
    int waitfor = ap->a_waitfor;
    struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
    struct puffs_node *pn = VPTOPP(vp);
    int error, dofaf;

    error = flushvncache(vp, waitfor);
    if (error)
        return error;

    /*
     * HELLO!  We exit already here if the user server does not
     * support fsync OR if we should call fsync for a node which
     * has references neither in the kernel or the fs server.
     * Otherwise we continue to issue fsync() forward.
     */
    if (!EXISTSOP(pmp, FSYNC) || (pn->pn_stat & PNODE_DYING))
        return 0;

    dofaf = (waitfor & MNT_WAIT) == 0 || (waitfor & MNT_LAZY) != 0;

    PUFFS_MSG_ALLOC(vn, fsync);
    if (dofaf)
        puffs_msg_setfaf(park_fsync);

    fsync_msg->pvnr_flags = ap->a_flags;
    puffs_msg_setinfo(park_fsync, PUFFSOP_VN,
                      PUFFS_VN_FSYNC, VPTOPNC(vp));

    PUFFS_MSG_ENQUEUEWAIT2(pmp, park_fsync, vp->v_data, NULL, error);
    PUFFS_MSG_RELEASE(fsync);

    error = checkerr(pmp, error, __func__);

    return error;
}
예제 #4
0
static int
puffs_vnop_close(struct vop_close_args *ap)
{
    PUFFS_MSG_VARS(vn, close);
    struct vnode *vp = ap->a_vp;
    struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);

    vn_lock(vp, LK_UPGRADE | LK_RETRY);

    if (!EXISTSOP(pmp, CLOSE))
        return vop_stdclose(ap);

    PUFFS_MSG_ALLOC(vn, close);
    puffs_msg_setfaf(park_close);
    close_msg->pvnr_fflag = ap->a_fflag;
    puffs_msg_setinfo(park_close, PUFFSOP_VN,
                      PUFFS_VN_CLOSE, VPTOPNC(vp));

    puffs_msg_enqueue(pmp, park_close);
    PUFFS_MSG_RELEASE(close);
    return vop_stdclose(ap);
}
예제 #5
0
/* XXX: callinactive can't setback */
static int
puffs_vnop_inactive(struct vop_inactive_args *ap)
{
    PUFFS_MSG_VARS(vn, inactive);
    struct vnode *vp = ap->a_vp;
    struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
    struct puffs_node *pnode = VPTOPP(vp);

    flushvncache(vp, MNT_NOWAIT);

    if (doinact(pmp, pnode->pn_stat & PNODE_DOINACT)) {
        /*
         * do not wait for reply from userspace, otherwise it may
         * deadlock.
         */

        PUFFS_MSG_ALLOC(vn, inactive);
        puffs_msg_setfaf(park_inactive);
        puffs_msg_setinfo(park_inactive, PUFFSOP_VN,
                          PUFFS_VN_INACTIVE, VPTOPNC(vp));

        puffs_msg_enqueue(pmp, park_inactive);
        PUFFS_MSG_RELEASE(inactive);
    }
    pnode->pn_stat &= ~PNODE_DOINACT;

    /*
     * file server thinks it's gone?  then don't be afraid care,
     * node's life was already all it would ever be
     */
    if (pnode->pn_stat & PNODE_NOREFS) {
        pnode->pn_stat |= PNODE_DYING;
        vrecycle(vp);
    }

    return 0;
}
예제 #6
0
static int
dosetattr(struct vnode *vp, struct vattr *vap, struct ucred *cred, int flags)
{
    PUFFS_MSG_VARS(vn, setattr);
    struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
    struct puffs_node *pn = VPTOPP(vp);
    int error = 0;

    if ((vp->v_mount->mnt_flag & MNT_RDONLY) &&
            (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL
             || vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL
             || vap->va_mode != (mode_t)VNOVAL))
        return EROFS;

    if ((vp->v_mount->mnt_flag & MNT_RDONLY)
            && vp->v_type == VREG && vap->va_size != VNOVAL)
        return EROFS;

    /*
     * Flush metacache first.  If we are called with some explicit
     * parameters, treat them as information overriding metacache
     * information.
     */
    if (pn->pn_stat & PNODE_METACACHE_MASK) {
        if ((pn->pn_stat & PNODE_METACACHE_ATIME)
                && vap->va_atime.tv_sec == VNOVAL)
            vap->va_atime = pn->pn_mc_atime;
        if ((pn->pn_stat & PNODE_METACACHE_CTIME)
                && vap->va_ctime.tv_sec == VNOVAL)
            vap->va_ctime = pn->pn_mc_ctime;
        if ((pn->pn_stat & PNODE_METACACHE_MTIME)
                && vap->va_mtime.tv_sec == VNOVAL)
            vap->va_mtime = pn->pn_mc_mtime;
        if ((pn->pn_stat & PNODE_METACACHE_SIZE)
                && vap->va_size == VNOVAL)
            vap->va_size = pn->pn_mc_size;

        pn->pn_stat &= ~PNODE_METACACHE_MASK;
    }

    PUFFS_MSG_ALLOC(vn, setattr);
    (void)memcpy(&setattr_msg->pvnr_va, vap, sizeof(struct vattr));
    puffs_credcvt(&setattr_msg->pvnr_cred, cred);
    puffs_msg_setinfo(park_setattr, PUFFSOP_VN,
                      PUFFS_VN_SETATTR, VPTOPNC(vp));
    if (flags & SETATTR_ASYNC)
        puffs_msg_setfaf(park_setattr);

    puffs_msg_enqueue(pmp, park_setattr);
    if ((flags & SETATTR_ASYNC) == 0)
        error = puffs_msg_wait2(pmp, park_setattr, vp->v_data, NULL);
    PUFFS_MSG_RELEASE(setattr);
    if ((flags & SETATTR_ASYNC) == 0) {
        error = checkerr(pmp, error, __func__);
        if (error)
            return error;
    } else {
        error = 0;
    }

    if (vap->va_size != VNOVAL) {
        pn->pn_serversize = vap->va_size;
        if (flags & SETATTR_CHSIZE)
            puffs_meta_setsize(vp, vap->va_size, 0);
    }

    return 0;
}