diff options
Diffstat (limited to 'lib/fuse_lowlevel.c')
-rwxr-xr-x | lib/fuse_lowlevel.c | 157 |
1 files changed, 68 insertions, 89 deletions
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index eff820f..a28ff47 100755 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -158,80 +158,11 @@ static struct fuse_req *fuse_ll_alloc_req(struct fuse_ll *f) return req; } -static int fuse_chan_recv(struct fuse_session *se, struct fuse_buf *buf, - struct fuse_chan *ch) -{ - struct fuse_ll *f = se->f; - int err; - ssize_t res; - - if (!buf->mem) { - buf->mem = malloc(f->bufsize); - if (!buf->mem) { - fprintf(stderr, - "fuse: failed to allocate read buffer\n"); - return -ENOMEM; - } - } - -restart: - res = read(fuse_chan_fd(ch), buf->mem, f->bufsize); - err = errno; - - if (fuse_session_exited(se)) - return 0; - if (res == -1) { - /* ENOENT means the operation was interrupted, it's safe - to restart */ - if (err == ENOENT) - goto restart; - - if (err == ENODEV) { - fuse_session_exit(se); - return 0; - } - /* Errors occurring during normal operation: EINTR (read - interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem - umounted) */ - if (err != EINTR && err != EAGAIN) - perror("fuse: reading device"); - return -err; - } - if ((size_t) res < sizeof(struct fuse_in_header)) { - fprintf(stderr, "short read on fuse device\n"); - return -EIO; - } - - buf->size = res; - - return res; -} - -static int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], - size_t count) -{ - ssize_t res = writev(fuse_chan_fd(ch), iov, count); - int err = errno; - - if (res == -1) { - struct fuse_session *se = fuse_chan_session(ch); - - assert(se != NULL); - - /* ENOENT means the operation was interrupted */ - if (!fuse_session_exited(se) && err != ENOENT) - perror("fuse: writing device"); - return -err; - } - - return 0; -} - void fuse_chan_close(struct fuse_chan *ch) { - int fd = fuse_chan_fd(ch); + int fd = ch->fd; if (fd != -1) - close(fd); + close(fd); } @@ -257,9 +188,24 @@ static int fuse_send_msg(struct fuse_ll *f, struct fuse_chan *ch, } } - return fuse_chan_send(ch, iov, count); + ssize_t res = writev(ch->fd, iov, count); + int err = errno; + + if (res == -1) { + struct fuse_session *se = fuse_chan_session(ch); + + assert(se != NULL); + + /* ENOENT means the operation was interrupted */ + if (!fuse_session_exited(se) && err != ENOENT) + perror("fuse: writing device"); + return -err; + } + + return 0; } + int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov, int count) { @@ -868,7 +814,7 @@ static int fuse_send_data_iov(struct fuse_ll *f, struct fuse_chan *ch, splice_flags |= SPLICE_F_MOVE; res = splice(llp->pipe[0], NULL, - fuse_chan_fd(ch), NULL, out->len, splice_flags); + ch->fd, NULL, out->len, splice_flags); if (res == -1) { res = -errno; perror("fuse: splice from pipe"); @@ -2088,7 +2034,7 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) fprintf(stderr, " max_background=%i\n", outarg.max_background); fprintf(stderr, " congestion_threshold=%i\n", - outarg.congestion_threshold); + outarg.congestion_threshold); fprintf(stderr, " time_gran=%u\n", outarg.time_gran); } @@ -2193,7 +2139,7 @@ int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph) } int fuse_lowlevel_notify_inval_inode(struct fuse_chan *ch, fuse_ino_t ino, - off_t off, off_t len) + off_t off, off_t len) { struct fuse_notify_inval_inode_out outarg; struct fuse_ll *f; @@ -2217,7 +2163,7 @@ int fuse_lowlevel_notify_inval_inode(struct fuse_chan *ch, fuse_ino_t ino, } int fuse_lowlevel_notify_inval_entry(struct fuse_chan *ch, fuse_ino_t parent, - const char *name, size_t namelen) + const char *name, size_t namelen) { struct fuse_notify_inval_entry_out outarg; struct fuse_ll *f; @@ -2723,7 +2669,7 @@ static void fuse_ll_help(void) " -o big_writes enable larger than 4kB writes\n" " -o no_remote_lock disable remote file locking\n" " -o no_remote_flock disable remote file locking (BSD)\n" -" -o no_remote_posix_lock disable remove file locking (POSIX)\n" +" -o no_remote_posix_lock disable remote file locking (POSIX)\n" " -o [no_]splice_write use splice to write to the fuse device\n" " -o [no_]splice_move move data while splicing to the fuse device\n" " -o [no_]splice_read use splice to read from the fuse device\n" @@ -2788,16 +2734,16 @@ static void fuse_ll_pipe_destructor(void *data) fuse_ll_pipe_free(llp); } -#ifdef HAVE_SPLICE int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf, struct fuse_chan *ch) { struct fuse_ll *f = se->f; + int err; + ssize_t res; +#ifdef HAVE_SPLICE size_t bufsize = f->bufsize; struct fuse_ll_pipe *llp; struct fuse_buf tmpbuf; - int err; - int res; if (f->conn.proto_minor < 14 || !(f->conn.want & FUSE_CAP_SPLICE_READ)) goto fallback; @@ -2819,7 +2765,7 @@ int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf, goto fallback; } - res = splice(fuse_chan_fd(ch), NULL, llp->pipe[1], NULL, bufsize, 0); + res = splice(ch->fd, NULL, llp->pipe[1], NULL, bufsize, 0); err = errno; if (fuse_session_exited(se)) @@ -2892,15 +2838,48 @@ int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf, return res; fallback: - return fuse_chan_recv(se, buf, ch); -} -#else -int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf, - struct fuse_chan *ch) -{ - return fuse_chan_recv(se, buf, ch); -} #endif + if (!buf->mem) { + buf->mem = malloc(f->bufsize); + if (!buf->mem) { + fprintf(stderr, + "fuse: failed to allocate read buffer\n"); + return -ENOMEM; + } + } + +restart: + res = read(ch->fd, buf->mem, f->bufsize); + err = errno; + + if (fuse_session_exited(se)) + return 0; + if (res == -1) { + /* ENOENT means the operation was interrupted, it's safe + to restart */ + if (err == ENOENT) + goto restart; + + if (err == ENODEV) { + fuse_session_exit(se); + return 0; + } + /* Errors occurring during normal operation: EINTR (read + interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem + umounted) */ + if (err != EINTR && err != EAGAIN) + perror("fuse: reading device"); + return -err; + } + if ((size_t) res < sizeof(struct fuse_in_header)) { + fprintf(stderr, "short read on fuse device\n"); + return -EIO; + } + + buf->size = res; + + return res; +} #define MIN_BUFSIZE 0x21000 |