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