aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--include/fuse_lowlevel.h13
-rw-r--r--lib/fuse_lowlevel.c46
3 files changed, 54 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 284b797..a65048d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-05-23 Miklos Szeredi <miklos@szeredi.hu>
+
+ * lowlevel lib: add fuse_reply_iov function, which is similar to
+ fuse_reply_buf, but accepts a vector of buffers. Patch by Roger
+ Willcocks
+
2007-05-21 Miklos Szeredi <miklos@szeredi.hu>
* Fix Oops or error if a regular file is created with mknod(2) on
diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index 8b0e3ee..b55eeb2 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -913,6 +913,19 @@ int fuse_reply_write(fuse_req_t req, size_t count);
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size);
/**
+ * Reply with data vector
+ *
+ * Possible requests:
+ * read, readdir, getxattr, listxattr
+ *
+ * @param req request handle
+ * @param iov the vector containing the data
+ * @param count the size of vector
+ * @return zero for success, -errno for failure to send reply
+ */
+int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count);
+
+/**
* Reply with filesystem statistics
*
* Possible requests:
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index f6342b2..43b0364 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -149,12 +149,10 @@ static void free_req(fuse_req_t req)
destroy_req(req);
}
-static int send_reply(fuse_req_t req, int error, const void *arg,
- size_t argsize)
+static int send_reply_iov(fuse_req_t req, int error, struct iovec *iov,
+ int count)
{
struct fuse_out_header out;
- struct iovec iov[2];
- size_t count;
int res;
if (error <= -1000 || error > 0) {
@@ -164,19 +162,14 @@ static int send_reply(fuse_req_t req, int error, const void *arg,
out.unique = req->unique;
out.error = error;
- count = 1;
iov[0].iov_base = &out;
iov[0].iov_len = sizeof(struct fuse_out_header);
- if (argsize && !error) {
- count++;
- iov[1].iov_base = (void *) arg;
- iov[1].iov_len = argsize;
- }
out.len = iov_length(iov, count);
if (req->f->debug) {
printf(" unique: %llu, error: %i (%s), outsize: %i\n",
- out.unique, out.error, strerror(-out.error), out.len);
+ (unsigned long long) out.unique, out.error,
+ strerror(-out.error), out.len);
fflush(stdout);
}
res = fuse_chan_send(req->ch, iov, count);
@@ -185,6 +178,37 @@ static int send_reply(fuse_req_t req, int error, const void *arg,
return res;
}
+static int send_reply(fuse_req_t req, int error, const void *arg,
+ size_t argsize)
+{
+ struct iovec iov[2];
+ int count = 1;
+ if (argsize) {
+ iov[1].iov_base = (void *) arg;
+ iov[1].iov_len = argsize;
+ count++;
+ }
+ return send_reply_iov(req, error, iov, count);
+}
+
+int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
+{
+ int res;
+ struct iovec *padded_iov;
+
+ padded_iov = malloc((count + 1) * sizeof(struct iovec));
+ if (padded_iov == NULL)
+ return fuse_reply_err(req, -ENOMEM);
+
+ memcpy(padded_iov + 1, iov, count * sizeof(struct iovec));
+ count++;
+
+ res = send_reply_iov(req, 0, padded_iov, count);
+ free(padded_iov);
+
+ return res;
+}
+
size_t fuse_dirent_size(size_t namelen)
{
return FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + namelen);