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); }
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); }
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; }
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); }
/* 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; }
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; }