mirror of
https://github.com/openharmony/third_party_libfuse.git
synced 2026-07-18 18:44:26 -04:00
Add mmap() and munmap() methods to low level API
Currently this is only useful for CUSE. Also update retrieve_reply() method.
This commit is contained in:
@@ -1,3 +1,10 @@
|
||||
2011-12-06 Miklos Szeredi <miklos@szeredi.hu>
|
||||
|
||||
* Add mmap() and munmap() methods to low level API. Currently
|
||||
this is only useful for CUSE
|
||||
|
||||
* Update retrieve_reply() method
|
||||
|
||||
2011-12-05 Miklos Szeredi <miklos@szeredi.hu>
|
||||
|
||||
* Low level API: lock argument of fuse_reply_lock should have a
|
||||
|
||||
@@ -63,6 +63,13 @@ 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, uint64_t addr, size_t length,
|
||||
int prot, int flags, off_t offset,
|
||||
struct fuse_file_info *fi);
|
||||
void (*munmap) (fuse_req_t req, uint64_t map_id, size_t length,
|
||||
struct fuse_file_info *fi);
|
||||
void (*retrieve_reply) (fuse_req_t req, void *cookie, uint64_t map_id,
|
||||
off_t offset, struct fuse_bufvec *bufv);
|
||||
};
|
||||
|
||||
struct fuse_session *cuse_lowlevel_new(struct fuse_args *args,
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
*
|
||||
* 7.18
|
||||
* - add FUSE_IOCTL_DIR flag
|
||||
* - add FUSE_MMAP and FUSE_MUNMAP
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FUSE_H
|
||||
@@ -308,6 +309,8 @@ enum fuse_opcode {
|
||||
FUSE_POLL = 40,
|
||||
FUSE_NOTIFY_REPLY = 41,
|
||||
FUSE_BATCH_FORGET = 42,
|
||||
FUSE_MMAP = 43,
|
||||
FUSE_MUNMAP = 44,
|
||||
|
||||
/* CUSE specific operations */
|
||||
CUSE_INIT = 4096,
|
||||
@@ -600,6 +603,28 @@ struct fuse_notify_poll_wakeup_out {
|
||||
__u64 kh;
|
||||
};
|
||||
|
||||
struct fuse_mmap_in {
|
||||
__u64 fh;
|
||||
__u64 addr;
|
||||
__u64 len;
|
||||
__u32 prot;
|
||||
__u32 flags;
|
||||
__u64 offset;
|
||||
};
|
||||
|
||||
struct fuse_mmap_out {
|
||||
__u64 mapid; /* Mmap ID, same namespace as Inode ID */
|
||||
__u64 size; /* Size of memory region */
|
||||
__u64 reserved;
|
||||
};
|
||||
|
||||
struct fuse_munmap_in {
|
||||
__u64 fh;
|
||||
__u64 mapid;
|
||||
__u64 size; /* Size of memory region */
|
||||
__u64 reserved;
|
||||
};
|
||||
|
||||
struct fuse_in_header {
|
||||
__u32 len;
|
||||
__u32 opcode;
|
||||
|
||||
+51
-2
@@ -911,13 +911,19 @@ struct fuse_lowlevel_ops {
|
||||
/**
|
||||
* Callback function for the retrieve request
|
||||
*
|
||||
* Introduced in version 2.9
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_none
|
||||
*
|
||||
* @param req request handle
|
||||
* @param cookie user data supplied to fuse_lowlevel_notify_retrieve()
|
||||
* @param ino the inode number supplied to fuse_lowlevel_notify_retrieve()
|
||||
* @param offset the offset supplied to fuse_lowlevel_notify_retrieve()
|
||||
* @param bufv the buffer containing the returned data
|
||||
*/
|
||||
void (*retrieve_reply) (void *cookie, fuse_ino_t ino, off_t offset,
|
||||
struct fuse_bufvec *bufv);
|
||||
void (*retrieve_reply) (fuse_req_t req, void *cookie, fuse_ino_t ino,
|
||||
off_t offset, struct fuse_bufvec *bufv);
|
||||
|
||||
/**
|
||||
* Forget about multiple inodes
|
||||
@@ -951,6 +957,37 @@ struct fuse_lowlevel_ops {
|
||||
*/
|
||||
void (*flock) (fuse_req_t req, fuse_ino_t ino,
|
||||
struct fuse_file_info *fi, int op);
|
||||
|
||||
/**
|
||||
* Direct mmap (CUSE only for now)
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param addr starting address (in clients address space)
|
||||
* @param length length of the mapping
|
||||
* @param prot desired memory protection of the mapping
|
||||
* @param flags mmap flags
|
||||
* @param fi file information
|
||||
*
|
||||
* Introduced in version 2.9
|
||||
*/
|
||||
void (*mmap) (fuse_req_t req, fuse_ino_t ino, uint64_t addr,
|
||||
size_t length, int prot, int flags, off_t offset,
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
/**
|
||||
* Direct munmap (CUSE only for now)
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param map_id identifies the mapping
|
||||
* @param length length of the mapping
|
||||
* @param fi file information
|
||||
*
|
||||
* Introduced in version 2.9
|
||||
*/
|
||||
void (*munmap) (fuse_req_t req, fuse_ino_t ino, uint64_t map_id,
|
||||
size_t length, struct fuse_file_info *fi);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1234,6 +1271,18 @@ int fuse_reply_ioctl_iov(fuse_req_t req, int result, const struct iovec *iov,
|
||||
*/
|
||||
int fuse_reply_poll(fuse_req_t req, unsigned revents);
|
||||
|
||||
/**
|
||||
* Reply to an mmap request
|
||||
*
|
||||
* Possible requests:
|
||||
* mmap
|
||||
*
|
||||
* @param req request handle
|
||||
* @param map_id identifies the mapping
|
||||
* @param length length of the mapping (from zero offset)
|
||||
*/
|
||||
int fuse_reply_mmap(fuse_req_t req, uint64_t map_id, size_t length);
|
||||
|
||||
/* ----------------------------------------------------------- *
|
||||
* Notification *
|
||||
* ----------------------------------------------------------- */
|
||||
|
||||
@@ -93,6 +93,28 @@ static void cuse_fll_poll(fuse_req_t req, fuse_ino_t ino,
|
||||
req_clop(req)->poll(req, fi, ph);
|
||||
}
|
||||
|
||||
static void cuse_fll_mmap(fuse_req_t req, fuse_ino_t ino, uint64_t addr,
|
||||
size_t length, int prot, int flags, off_t offset,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
(void)ino;
|
||||
req_clop(req)->mmap(req, addr, length, prot, flags, offset, fi);
|
||||
}
|
||||
|
||||
static void cuse_fll_munmap(fuse_req_t req, fuse_ino_t ino, uint64_t map_id,
|
||||
size_t length, struct fuse_file_info *fi)
|
||||
{
|
||||
(void)ino;
|
||||
req_clop(req)->munmap(req, map_id, length, fi);
|
||||
}
|
||||
|
||||
static void cuse_fll_retrieve_reply(fuse_req_t req, void *cookie,
|
||||
fuse_ino_t ino, off_t offset,
|
||||
struct fuse_bufvec *bufv)
|
||||
{
|
||||
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 +191,10 @@ 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.mmap = clop->mmap ? cuse_fll_mmap : NULL;
|
||||
lop.munmap = clop->munmap ? cuse_fll_munmap : NULL;
|
||||
lop.retrieve_reply = clop->retrieve_reply ?
|
||||
cuse_fll_retrieve_reply : NULL;
|
||||
|
||||
se = fuse_lowlevel_new_common(args, &lop, sizeof(lop), userdata);
|
||||
if (!se) {
|
||||
|
||||
+64
-6
@@ -437,7 +437,18 @@ static int fuse_send_data_iov_fallback(struct fuse_ll *f, struct fuse_chan *ch,
|
||||
void *mbuf;
|
||||
int res;
|
||||
|
||||
/* FIXME: Avoid memory copy if none of the buffers contain an fd */
|
||||
/* Optimize common case */
|
||||
if (buf->count == 1 && buf->idx == 0 && buf->off == 0 &&
|
||||
!(buf->buf[0].flags & FUSE_BUF_IS_FD)) {
|
||||
/* FIXME: also avoid memory copy if there are multiple buffers
|
||||
but none of them contain an fd */
|
||||
|
||||
iov[iov_count].iov_base = buf->buf[0].mem;
|
||||
iov[iov_count].iov_len = len;
|
||||
iov_count++;
|
||||
return fuse_send_msg(f, ch, iov, iov_count);
|
||||
}
|
||||
|
||||
res = posix_memalign(&mbuf, pagesize, len);
|
||||
if (res != 0)
|
||||
return res;
|
||||
@@ -956,6 +967,17 @@ int fuse_reply_poll(fuse_req_t req, unsigned revents)
|
||||
return send_reply_ok(req, &arg, sizeof(arg));
|
||||
}
|
||||
|
||||
int fuse_reply_mmap(fuse_req_t req, uint64_t map_id, size_t length)
|
||||
{
|
||||
struct fuse_mmap_out arg;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.mapid = map_id;
|
||||
arg.size = length;
|
||||
|
||||
return send_reply_ok(req, &arg, sizeof(arg));
|
||||
}
|
||||
|
||||
static void do_lookup(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
|
||||
{
|
||||
char *name = (char *) inarg;
|
||||
@@ -1704,6 +1726,38 @@ static void do_poll(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
|
||||
}
|
||||
}
|
||||
|
||||
static void do_mmap(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
|
||||
{
|
||||
struct fuse_mmap_in *arg = (struct fuse_mmap_in *) inarg;
|
||||
struct fuse_file_info fi;
|
||||
|
||||
memset(&fi, 0, sizeof(fi));
|
||||
fi.fh = arg->fh;
|
||||
fi.fh_old = fi.fh;
|
||||
|
||||
if (req->f->op.mmap)
|
||||
req->f->op.mmap(req, nodeid, arg->addr, arg->len, arg->prot,
|
||||
arg->flags, arg->offset, &fi);
|
||||
else
|
||||
fuse_reply_err(req, ENOSYS);
|
||||
|
||||
}
|
||||
|
||||
static void do_munmap(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
|
||||
{
|
||||
struct fuse_munmap_in *arg = (struct fuse_munmap_in *) inarg;
|
||||
struct fuse_file_info fi;
|
||||
|
||||
memset(&fi, 0, sizeof(fi));
|
||||
fi.fh = arg->fh;
|
||||
fi.fh_old = fi.fh;
|
||||
|
||||
if (req->f->op.munmap)
|
||||
req->f->op.munmap(req, nodeid, arg->mapid, arg->size, &fi);
|
||||
else
|
||||
fuse_reply_err(req, ENOSYS);
|
||||
}
|
||||
|
||||
static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
|
||||
{
|
||||
struct fuse_init_in *arg = (struct fuse_init_in *) inarg;
|
||||
@@ -2069,12 +2123,14 @@ static void fuse_ll_retrieve_reply(struct fuse_notify_req *nreq,
|
||||
}
|
||||
bufv.buf[0].size = arg->size;
|
||||
|
||||
if (req->f->op.retrieve_reply)
|
||||
req->f->op.retrieve_reply(rreq->cookie, ino, arg->offset, &bufv);
|
||||
fuse_reply_none(req);
|
||||
free(rreq);
|
||||
|
||||
if (req->f->op.retrieve_reply) {
|
||||
req->f->op.retrieve_reply(req, rreq->cookie, ino,
|
||||
arg->offset, &bufv);
|
||||
} else {
|
||||
fuse_reply_none(req);
|
||||
}
|
||||
out:
|
||||
free(rreq);
|
||||
if ((ibuf->flags & FUSE_BUF_IS_FD) && bufv.idx < bufv.count)
|
||||
fuse_ll_clear_pipe(f);
|
||||
}
|
||||
@@ -2218,6 +2274,8 @@ static struct {
|
||||
[FUSE_DESTROY] = { do_destroy, "DESTROY" },
|
||||
[FUSE_NOTIFY_REPLY] = { (void *) 1, "NOTIFY_REPLY" },
|
||||
[FUSE_BATCH_FORGET] = { do_batch_forget, "BATCH_FORGET" },
|
||||
[FUSE_MMAP] = { do_mmap, "MMAP" },
|
||||
[FUSE_MUNMAP] = { do_munmap, "MUNMAP" },
|
||||
[CUSE_INIT] = { cuse_lowlevel_init, "CUSE_INIT" },
|
||||
};
|
||||
|
||||
|
||||
@@ -194,6 +194,7 @@ FUSE_2.9 {
|
||||
fuse_start_cleanup_thread;
|
||||
fuse_stop_cleanup_thread;
|
||||
fuse_clean_cache;
|
||||
fuse_reply_mmap;
|
||||
|
||||
local:
|
||||
*;
|
||||
|
||||
Reference in New Issue
Block a user