diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2013-06-21 18:17:27 +0200 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2013-06-21 18:17:27 +0200 |
commit | 5334a152e1272a072339fb4519de04ed4269d3ca (patch) | |
tree | ce350efe74f0ecc17fd7cc4d43ddf51d06b5a993 /lib/fuse_lowlevel.c | |
parent | 39065e40e0f00528980b35b52d8f5e13759e5a59 (diff) | |
download | libfuse-5334a152e1272a072339fb4519de04ed4269d3ca.tar.gz |
libfuse: remove fuse_chan_(send|receive)
Move the fuse_chan_ops.send and .receive implementations to fuse_lowlevel.c. The abstraction wasn't actually useful and made the the splice implementation more difficult.
Remove fuse_chan_ops.send and fuse_chan_ops.receive.
Diffstat (limited to 'lib/fuse_lowlevel.c')
-rw-r--r-- | lib/fuse_lowlevel.c | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 30877ec..77de5eb 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -153,6 +153,62 @@ static struct fuse_req *fuse_ll_alloc_req(struct fuse_ll *f) return req; } +static int fuse_chan_recv(struct fuse_chan *ch, char *buf, size_t size) +{ + int err; + ssize_t res; + struct fuse_session *se = fuse_chan_session(ch); + assert(se != NULL); + +restart: + res = read(fuse_chan_fd(ch), buf, size); + 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; + } + 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; +} static int fuse_send_msg(struct fuse_ll *f, struct fuse_chan *ch, struct iovec *iov, int count) @@ -301,8 +357,6 @@ int fuse_reply_err(fuse_req_t req, int err) void fuse_reply_none(fuse_req_t req) { - if (req->ch) - fuse_chan_send(req->ch, NULL, 0); fuse_free_req(req); } @@ -2631,9 +2685,8 @@ static void fuse_ll_pipe_destructor(void *data) #ifdef HAVE_SPLICE static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf, - struct fuse_chan **chp) + struct fuse_chan *ch) { - struct fuse_chan *ch = *chp; struct fuse_ll *f = fuse_session_data(se); size_t bufsize = buf->size; struct fuse_ll_pipe *llp; @@ -2719,7 +2772,7 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf, return res; fallback: - res = fuse_chan_recv(chp, buf->mem, bufsize); + res = fuse_chan_recv(ch, buf->mem, bufsize); if (res <= 0) return res; @@ -2729,11 +2782,11 @@ fallback: } #else static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf, - struct fuse_chan **chp) + struct fuse_chan *ch) { (void) se; - int res = fuse_chan_recv(chp, buf->mem, buf->size); + int res = fuse_chan_recv(ch, buf->mem, buf->size); if (res <= 0) return res; @@ -2743,7 +2796,6 @@ static int fuse_ll_receive_buf(struct fuse_session *se, struct fuse_buf *buf, } #endif - struct fuse_session *fuse_lowlevel_new(struct fuse_args *args, const struct fuse_lowlevel_ops *op, size_t op_size, void *userdata) |