[prev in list] [next in list] [prev in thread] [next in thread]
List: fuse-devel
Subject: [fuse-devel] [PATCH] cuse mmap support (libfuse)
From: "Jader H. Silva" <jaderhs5 () gmail ! com>
Date: 2015-07-23 17:45:08
Message-ID: 55B12824.1000303 () gmail ! com
[Download RAW message or body]
From: "Jader H. Silva" <jaderhs5@gmail.com>
Implement cuse mmap, munmap and notify retrieve reply callbacks
---
include/cuse_lowlevel.h | 5 +++++
include/fuse_kernel.h | 25 +++++++++++++++++++++++++
include/fuse_lowlevel.h | 21 +++++++++++++++++++++
lib/cuse_lowlevel.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
lib/fuse_i.h | 4 ++++
lib/fuse_lowlevel.c | 24 ++++++++++++++++++++++++
lib/fuse_versionscript | 2 ++
7 files changed, 126 insertions(+)
diff --git a/include/cuse_lowlevel.h b/include/cuse_lowlevel.h
index e147fa2..6b48f37 100644
--- a/include/cuse_lowlevel.h
+++ b/include/cuse_lowlevel.h
@@ -63,6 +63,11 @@ struct cuse_lowlevel_ops {
const void *in_buf, size_t in_bufsz, size_t out_bufsz);
void (*poll) (fuse_req_t req, struct fuse_file_info *fi,
struct fuse_pollhandle *ph);
+ void (*mmap) (fuse_req_t req, size_t size, off_t off, int prot, int flags,
+ struct fuse_file_info *fi);
+ void (*munmap) (fuse_req_t req, uint64_t mapid, uint64_t size, uint64_t off, struct \
fuse_file_info *fi); + void (*retrieve_reply) (fuse_req_t req, void *cookie, \
fuse_ino_t ino, + off_t offset, struct fuse_bufvec *bufv);
};
struct fuse_session *cuse_lowlevel_new(struct fuse_args *args,
diff --git a/include/fuse_kernel.h b/include/fuse_kernel.h
index 25084a0..3bcccd4 100644
--- a/include/fuse_kernel.h
+++ b/include/fuse_kernel.h
@@ -358,6 +358,8 @@ enum fuse_opcode {
FUSE_FALLOCATE = 43,
FUSE_READDIRPLUS = 44,
FUSE_RENAME2 = 45,
+ FUSE_MMAP = 46,
+ FUSE_MUNMAP = 47,
/* CUSE specific operations */
CUSE_INIT = 4096,
@@ -670,6 +672,29 @@ struct fuse_fallocate_in {
uint32_t padding;
};
+struct fuse_mmap_in {
+ uint64_t fh;
+ uint64_t addr;
+ uint64_t len;
+ uint32_t prot;
+ uint32_t flags;
+ uint64_t offset;
+};
+
+struct fuse_mmap_out {
+ uint64_t mapid; /* Mmap ID, same namespace as Inode ID */
+ uint64_t size; /* Size of memory region */
+ uint64_t reserved;
+};
+
+struct fuse_munmap_in {
+ uint64_t fh;
+ uint64_t mapid;
+ uint64_t size; /* Size of memory region */
+ uint64_t offset;
+ uint64_t reserved;
+};
+
struct fuse_in_header {
uint32_t len;
uint32_t opcode;
diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index 20e7692..9229771 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -1259,6 +1259,19 @@ int fuse_reply_lock(fuse_req_t req, const struct flock *lock);
*/
int fuse_reply_bmap(fuse_req_t req, uint64_t idx);
+/**
+ * Reply with map id
+ *
+ * Possible requests:
+ * mmap
+ *
+ * @param req request handle
+ * @param mapid memory map id
+ * @param size memory map size
+ * @return zero for success, -errno for failure to send reply
+ */
+int fuse_reply_mmap(fuse_req_t req, uint64_t mapid, uint64_t size);
+
/* ----------------------------------------------------------- *
* Filling a buffer in readdir *
* ----------------------------------------------------------- */
@@ -1513,6 +1526,14 @@ void *fuse_req_userdata(fuse_req_t req);
const struct fuse_ctx *fuse_req_ctx(fuse_req_t req);
/**
+ * Get the channel from the request
+ *
+ * @param req request handle
+ * @return the channel structure
+ */
+const struct fuse_chan *fuse_req_channel(fuse_req_t req);
+
+/**
* Get the current supplementary group IDs for the specified request
*
* Similar to the getgroups(2) system call, except the return value is
diff --git a/lib/cuse_lowlevel.c b/lib/cuse_lowlevel.c
index fbaa873..14be778 100644
--- a/lib/cuse_lowlevel.c
+++ b/lib/cuse_lowlevel.c
@@ -93,6 +93,14 @@ static void cuse_fll_poll(fuse_req_t req, fuse_ino_t ino,
req_clop(req)->poll(req, fi, ph);
}
+static void cuse_fll_retrieve_reply(fuse_req_t req, void *cookie,
+ fuse_ino_t ino, off_t offset,
+ struct fuse_bufvec *bufv)
+{
+ (void)ino;
+ req_clop(req)->retrieve_reply(req, cookie, ino, offset, bufv);
+}
+
static size_t cuse_pack_info(int argc, const char **argv, char *buf)
{
size_t size = 0;
@@ -169,6 +177,8 @@ struct fuse_session *cuse_lowlevel_new(struct fuse_args *args,
lop.fsync = clop->fsync ? cuse_fll_fsync : NULL;
lop.ioctl = clop->ioctl ? cuse_fll_ioctl : NULL;
lop.poll = clop->poll ? cuse_fll_poll : NULL;
+ lop.retrieve_reply = clop->retrieve_reply ? cuse_fll_retrieve_reply :
+ NULL;
se = fuse_lowlevel_new(args, &lop, sizeof(lop), userdata);
if (!se) {
@@ -346,6 +356,41 @@ void cuse_lowlevel_teardown(struct fuse_session *se)
fuse_session_destroy(se);
}
+void cuse_lowlevel_mmap(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
+{
+ struct fuse_file_info *fip = NULL;
+ struct fuse_file_info fi;
+ struct fuse_mmap_in *arg = (struct fuse_mmap_in *) inarg;
+
+ (void) nodeid;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fip = &fi;
+
+ if(req_clop(req)->mmap)
+ req_clop(req)->mmap(req, arg->len, arg->offset, arg->prot,
+ arg->flags, fip);
+ else
+ fuse_reply_err(req, ENOSYS);
+}
+
+void cuse_lowlevel_munmap(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
+{
+ struct fuse_file_info *fip = NULL;
+ struct fuse_file_info fi;
+ struct fuse_munmap_in *arg = (struct fuse_munmap_in *) inarg;
+
+ (void) nodeid;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fip = &fi;
+
+ if(req_clop(req)->munmap)
+ req_clop(req)->munmap(req, arg->mapid, arg->size, arg->offset, fip);
+ else
+ fuse_reply_err(req, 0);
+}
+
int cuse_lowlevel_main(int argc, char *argv[], const struct cuse_info *ci,
const struct cuse_lowlevel_ops *clop, void *userdata)
{
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index 4bbcbd6..3efc693 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -146,4 +146,8 @@ void fuse_free_req(fuse_req_t req);
void cuse_lowlevel_init(fuse_req_t req, fuse_ino_t nodeide, const void *inarg);
+void cuse_lowlevel_mmap(fuse_req_t req, fuse_ino_t nodeid, const void *inarg);
+
+void cuse_lowlevel_munmap(fuse_req_t req, fuse_ino_t nodeid, const void *inarg);
+
int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg);
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index f25d56f..09c94b9 100755
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -933,6 +933,21 @@ int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
return send_reply_ok(req, &arg, sizeof(arg));
}
+int fuse_reply_mmap(fuse_req_t req, uint64_t mapid, uint64_t size)
+{
+ struct iovec iov[2];
+ struct fuse_mmap_out outarg;
+
+ memset(&outarg, 0, sizeof(outarg));
+ outarg.mapid = mapid;
+ outarg.size = size;
+
+ iov[1].iov_base = &outarg;
+ iov[1].iov_len = sizeof(outarg);
+
+ return fuse_send_reply_iov_nofree(req, 0, iov, 2);
+}
+
static struct fuse_ioctl_iovec *fuse_ioctl_iovec_copy(const struct iovec *iov,
size_t count)
{
@@ -2358,6 +2373,7 @@ int fuse_lowlevel_notify_retrieve(struct fuse_chan *ch, \
fuse_ino_t ino,
err = send_notify_iov(f, ch, FUSE_NOTIFY_RETRIEVE, iov, 2);
if (err) {
+
pthread_mutex_lock(&f->lock);
list_del_nreq(&rreq->nreq);
pthread_mutex_unlock(&f->lock);
@@ -2377,6 +2393,12 @@ const struct fuse_ctx *fuse_req_ctx(fuse_req_t req)
return &req->ctx;
}
+const struct fuse_chan *fuse_req_channel(fuse_req_t req)
+{
+ return req->ch;
+}
+
+
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func,
void *data)
{
@@ -2448,6 +2470,8 @@ static struct {
[FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
[FUSE_READDIRPLUS] = { do_readdirplus, "READDIRPLUS"},
[FUSE_RENAME2] = { do_rename2, "RENAME2" },
+ [FUSE_MMAP] = { cuse_lowlevel_mmap, "FUSE_MMAP" },
+ [FUSE_MUNMAP] = { cuse_lowlevel_munmap, "FUSE_MUNMAP" },
[CUSE_INIT] = { cuse_lowlevel_init, "CUSE_INIT" },
};
diff --git a/lib/fuse_versionscript b/lib/fuse_versionscript
index 08dafbd..4ffb956 100644
--- a/lib/fuse_versionscript
+++ b/lib/fuse_versionscript
@@ -90,6 +90,7 @@ FUSE_3.0 {
fuse_reply_iov;
fuse_version;
fuse_reply_bmap;
+ fuse_reply_mmap;
cuse_lowlevel_new;
cuse_lowlevel_main;
cuse_lowlevel_setup;
@@ -109,6 +110,7 @@ FUSE_3.0 {
fuse_reply_ioctl_retry;
fuse_reply_poll;
fuse_req_ctx;
+ fuse_req_channel;
fuse_req_getgroups;
fuse_buf_copy;
fuse_buf_size;
--
2.1.4
------------------------------------------------------------------------------
_______________________________________________
fuse-devel mailing list
fuse-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fuse-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic