示例#1
0
int
fusefs_write(void *v)
{
	struct vop_write_args *ap = v;
	struct vnode *vp = ap->a_vp;
	struct uio *uio = ap->a_uio;
	struct proc *p = uio->uio_procp;
	struct fusefs_node *ip;
	struct fusefs_mnt *fmp;
	struct fusebuf *fbuf = NULL;
	size_t len, diff;
	int error=0;

	DPRINTF("fusefs_write\n");

	ip = VTOI(vp);
	fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;

	DPRINTF("write inode=%i, offset=%llu, resid=%x\n",
	    ip->ufs_ino.i_number, uio->uio_offset, uio->uio_resid);

	if (uio->uio_resid == 0)
		return (error);

	while (uio->uio_resid > 0) {
		len = MIN(uio->uio_resid, FUSELEN);
		fbuf = fb_setup(FUSEFDSIZE + len, ip->ufs_ino.i_number,
		    FBT_WRITE, p);

		fbuf->fb_io_fd = fusefs_fd_get(ip, FUFH_WRONLY);
		fbuf->fb_io_off = uio->uio_offset;
		fbuf->fb_io_len = len;

		if ((error = uiomove(fbuf->fb_dat, len, uio))) {
			DPRINTF("uio error %i", error);
			break;
		}

		error = fb_queue(fmp->dev, fbuf);

		if (error)
			break;

		diff = len - fbuf->fb_io_len;
		if (diff < 0) {
			error = EINVAL;
			break;
		}

		uio->uio_resid += diff;
		uio->uio_offset -= diff;

		pool_put(&fusefs_fbuf_pool, fbuf);
		fbuf = NULL;
	}

	if (fbuf)
		pool_put(&fusefs_fbuf_pool, fbuf);
	return (error);
}
示例#2
0
int
fusefs_read(void *v)
{
	struct vop_read_args *ap = v;
	struct vnode *vp = ap->a_vp;
	struct uio *uio = ap->a_uio;
	struct proc *p = uio->uio_procp;
	struct fusefs_node *ip;
	struct fusefs_mnt *fmp;
	struct fusebuf *fbuf = NULL;
	size_t size;
	int error=0;

	DPRINTF("fusefs_read\n");

	ip = VTOI(vp);
	fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;

	DPRINTF("read inode=%i, offset=%llu, resid=%x\n",
	    ip->ufs_ino.i_number, uio->uio_offset, uio->uio_resid);

	if (uio->uio_resid == 0)
		return (error);
	if (uio->uio_offset < 0)
		return (EINVAL);

	while (uio->uio_resid > 0) {
		fbuf = fb_setup(FUSEFDSIZE, ip->ufs_ino.i_number, FBT_READ, p);

		size = MIN(uio->uio_resid, FUSELEN);
		fbuf->fb_io_fd = fusefs_fd_get(ip, FUFH_RDONLY);
		fbuf->fb_io_off = uio->uio_offset;
		fbuf->fb_io_len = size;

		error = fb_queue(fmp->dev, fbuf);

		if (error)
			break;

		error = uiomove(fbuf->fb_dat, MIN(size, fbdatsize(fbuf)), uio);
		if (error)
			break;

		if (fbdatsize(fbuf) < size)
			break;

		pool_put(&fusefs_fbuf_pool, fbuf);
		fbuf = NULL;
	}

	if (fbuf)
		pool_put(&fusefs_fbuf_pool, fbuf);

	return (error);
}
示例#3
0
int
fusefs_read(void *v)
{
	struct vop_read_args *ap = v;
	struct vnode *vp = ap->a_vp;
	struct uio *uio = ap->a_uio;
	struct proc *p = uio->uio_procp;
	struct fusefs_node *ip;
	struct fusefs_mnt *fmp;
	struct fusebuf *fbuf = NULL;
	size_t size;
	int error=0;

	ip = VTOI(vp);
	fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;

	if (!fmp->sess_init)
		return (ENXIO);
	if (uio->uio_resid == 0)
		return (error);
	if (uio->uio_offset < 0)
		return (EINVAL);

	while (uio->uio_resid > 0) {
		fbuf = fb_setup(0, ip->ufs_ino.i_number, FBT_READ, p);

		size = MIN(uio->uio_resid, FUSEBUFMAXSIZE);
		fbuf->fb_io_fd = fusefs_fd_get(ip, FUFH_RDONLY);
		fbuf->fb_io_off = uio->uio_offset;
		fbuf->fb_io_len = size;

		error = fb_queue(fmp->dev, fbuf);

		if (error)
			break;

		error = uiomove(fbuf->fb_dat, MIN(size, fbuf->fb_len), uio);
		if (error)
			break;

		if (fbuf->fb_len < size)
			break;

		fb_delete(fbuf);
		fbuf = NULL;
	}

	fb_delete(fbuf);
	return (error);
}
示例#4
0
int
fusefs_write(void *v)
{
	struct vop_write_args *ap = v;
	struct vnode *vp = ap->a_vp;
	struct uio *uio = ap->a_uio;
	struct proc *p = uio->uio_procp;
	struct ucred *cred = p->p_ucred;
	struct vattr vattr;
	int ioflag = ap->a_ioflag;
	struct fusefs_node *ip;
	struct fusefs_mnt *fmp;
	struct fusebuf *fbuf = NULL;
	size_t len, diff;
	int error=0;

	ip = VTOI(vp);
	fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;

	if (!fmp->sess_init)
		return (ENXIO);
	if (uio->uio_resid == 0)
		return (error);

	if (ioflag & IO_APPEND) {
		if ((error = VOP_GETATTR(vp, &vattr, cred)) != 0)
			return (error);

		uio->uio_offset = vattr.va_size;
	}

	while (uio->uio_resid > 0) {
		len = MIN(uio->uio_resid, FUSEBUFMAXSIZE);
		fbuf = fb_setup(len, ip->ufs_ino.i_number, FBT_WRITE, p);

		fbuf->fb_io_fd = fusefs_fd_get(ip, FUFH_WRONLY);
		fbuf->fb_io_off = uio->uio_offset;
		fbuf->fb_io_len = len;

		if ((error = uiomove(fbuf->fb_dat, len, uio))) {
			printf("fusefs: uio error %i\n", error);
			break;
		}

		error = fb_queue(fmp->dev, fbuf);

		if (error)
			break;

		if (fbuf->fb_io_len > len) {
			error = EINVAL;
			break;
		}

		diff = len - fbuf->fb_io_len;
		uio->uio_resid += diff;
		uio->uio_offset -= diff;

		fb_delete(fbuf);
		fbuf = NULL;
	}

	fb_delete(fbuf);
	return (error);
}