示例#1
0
int
fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio)
{
	fuse_trace_printf_func();

	if (tick->tk_aw_ohead.error == ENOSYS) {
		fsess_set_notimpl(tick->tk_data->mp, fticket_opcode(tick));
	}
	return 0;
}
示例#2
0
/*
    struct vnop_create_args {
	struct vnode *a_dvp;
	struct vnode **a_vpp;
	struct componentname *a_cnp;
	struct vattr *a_vap;
    };
*/
static int
fuse_vnop_create(struct vop_create_args *ap)
{
	struct vnode *dvp = ap->a_dvp;
	struct vnode **vpp = ap->a_vpp;
	struct componentname *cnp = ap->a_cnp;
	struct vattr *vap = ap->a_vap;
	struct thread *td = cnp->cn_thread;
	struct ucred *cred = cnp->cn_cred;

	struct fuse_open_in *foi;
	struct fuse_entry_out *feo;
	struct fuse_dispatcher fdi;
	struct fuse_dispatcher *fdip = &fdi;

	int err;

	struct mount *mp = vnode_mount(dvp);
	uint64_t parentnid = VTOFUD(dvp)->nid;
	mode_t mode = MAKEIMODE(vap->va_type, vap->va_mode);
	uint64_t x_fh_id;
	uint32_t x_open_flags;

	fuse_trace_printf_vnop();

	if (fuse_isdeadfs(dvp)) {
		return ENXIO;
	}
	bzero(&fdi, sizeof(fdi));

	/* XXX:	Will we ever want devices ? */
	if ((vap->va_type != VREG)) {
		MPASS(vap->va_type != VFIFO);
		goto bringup;
	}
	debug_printf("parent nid = %ju, mode = %x\n", (uintmax_t)parentnid,
	    mode);

	fdisp_init(fdip, sizeof(*foi) + cnp->cn_namelen + 1);
	if (!fsess_isimpl(mp, FUSE_CREATE)) {
		debug_printf("eh, daemon doesn't implement create?\n");
		return (EINVAL);
	}
	fdisp_make(fdip, FUSE_CREATE, vnode_mount(dvp), parentnid, td, cred);

	foi = fdip->indata;
	foi->mode = mode;
	foi->flags = O_CREAT | O_RDWR;

	memcpy((char *)fdip->indata + sizeof(*foi), cnp->cn_nameptr,
	    cnp->cn_namelen);
	((char *)fdip->indata)[sizeof(*foi) + cnp->cn_namelen] = '\0';

	err = fdisp_wait_answ(fdip);

	if (err) {
		if (err == ENOSYS)
			fsess_set_notimpl(mp, FUSE_CREATE);
		debug_printf("create: got err=%d from daemon\n", err);
		goto out;
	}
bringup:
	feo = fdip->answ;

	if ((err = fuse_internal_checkentry(feo, VREG))) {
		goto out;
	}
	err = fuse_vnode_get(mp, feo->nodeid, dvp, vpp, cnp, VREG);
	if (err) {
		struct fuse_release_in *fri;
		uint64_t nodeid = feo->nodeid;
		uint64_t fh_id = ((struct fuse_open_out *)(feo + 1))->fh;

		fdisp_init(fdip, sizeof(*fri));
		fdisp_make(fdip, FUSE_RELEASE, mp, nodeid, td, cred);
		fri = fdip->indata;
		fri->fh = fh_id;
		fri->flags = OFLAGS(mode);
		fuse_insert_callback(fdip->tick, fuse_internal_forget_callback);
		fuse_insert_message(fdip->tick);
		return err;
	}
	ASSERT_VOP_ELOCKED(*vpp, "fuse_vnop_create");

	fdip->answ = feo + 1;

	x_fh_id = ((struct fuse_open_out *)(feo + 1))->fh;
	x_open_flags = ((struct fuse_open_out *)(feo + 1))->open_flags;
	fuse_filehandle_init(*vpp, FUFH_RDWR, NULL, x_fh_id);
	fuse_vnode_open(*vpp, x_open_flags, td);
	cache_purge_negative(dvp);

out:
	fdisp_destroy(fdip);
	return err;
}
示例#3
0
int
fuse_internal_access(struct vnode *vp,
    mode_t mode,
    struct fuse_access_param *facp,
    struct thread *td,
    struct ucred *cred)
{
	int err = 0;
	uint32_t mask = 0;
	int dataflags;
	int vtype;
	struct mount *mp;
	struct fuse_dispatcher fdi;
	struct fuse_access_in *fai;
	struct fuse_data *data;

	/* NOT YET DONE */
	/*
	 * If this vnop gives you trouble, just return 0 here for a lazy
	 * kludge.
	 */
	/* return 0;*/

	fuse_trace_printf_func();

	mp = vnode_mount(vp);
	vtype = vnode_vtype(vp);

	data = fuse_get_mpdata(mp);
	dataflags = data->dataflags;

	if ((mode & VWRITE) && vfs_isrdonly(mp)) {
		return EACCES;
	}
	/* Unless explicitly permitted, deny everyone except the fs owner. */
	    if (vnode_isvroot(vp) && !(facp->facc_flags & FACCESS_NOCHECKSPY)) {
		if (!(dataflags & FSESS_DAEMON_CAN_SPY)) {
			int denied = fuse_match_cred(data->daemoncred,
			    cred);

			if (denied) {
				return EPERM;
			}
		}
		facp->facc_flags |= FACCESS_NOCHECKSPY;
	}
	if (!(facp->facc_flags & FACCESS_DO_ACCESS)) {
		return 0;
	}
	if (((vtype == VREG) && (mode & VEXEC))) {
#ifdef NEED_MOUNT_ARGUMENT_FOR_THIS
		/* Let	 the kernel handle this through open / close heuristics.*/
		    return ENOTSUP;
#else
		    /* 	Let the kernel handle this. */
		    return 0;
#endif
	}
	if (!fsess_isimpl(mp, FUSE_ACCESS)) {
		/* Let the kernel handle this. */
		    return 0;
	}
	if (dataflags & FSESS_DEFAULT_PERMISSIONS) {
		/* Let the kernel handle this. */
		    return 0;
	}
	if ((mode & VADMIN) != 0) {
		err = priv_check_cred(cred, PRIV_VFS_ADMIN, 0);
		if (err) {
			return err;
		}
	}
	if ((mode & (VWRITE | VAPPEND | VADMIN)) != 0) {
		mask |= W_OK;
	}
	if ((mode & VREAD) != 0) {
		mask |= R_OK;
	}
	if ((mode & VEXEC) != 0) {
		mask |= X_OK;
	}
	bzero(&fdi, sizeof(fdi));

	fdisp_init(&fdi, sizeof(*fai));
	fdisp_make_vp(&fdi, FUSE_ACCESS, vp, td, cred);

	fai = fdi.indata;
	fai->mask = F_OK;
	fai->mask |= mask;

	err = fdisp_wait_answ(&fdi);
	fdisp_destroy(&fdi);

	if (err == ENOSYS) {
		fsess_set_notimpl(mp, FUSE_ACCESS);
		err = 0;
	}
	return err;
}