[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