aboutsummaryrefslogtreecommitdiffstats
path: root/lib/fuse_lowlevel.c
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2013-06-21 18:17:27 +0200
committerMiklos Szeredi <mszeredi@suse.cz>2013-06-21 18:17:27 +0200
commit5334a152e1272a072339fb4519de04ed4269d3ca (patch)
treece350efe74f0ecc17fd7cc4d43ddf51d06b5a993 /lib/fuse_lowlevel.c
parent39065e40e0f00528980b35b52d8f5e13759e5a59 (diff)
downloadlibfuse-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.c68
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)