aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--include/fuse_lowlevel.h19
-rw-r--r--lib/fuse.c26
-rw-r--r--lib/fuse_lowlevel.c9
4 files changed, 52 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index ef22dd1..caacc4a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -52,6 +52,10 @@
to be processed faster and doesn't require a modification to fuse
filesystems. Reported by Terje Malmedal
+ * Add ->forget_multi() operation to the lowlevel API. The
+ filesystem may implement this to process multiple forget requests
+ in one call
+
2010-11-10 Miklos Szeredi <miklos@szeredi.hu>
* Add new write_buf() method to the highlevel API. Similarly to
diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h
index 8f31471..e38fe92 100644
--- a/include/fuse_lowlevel.h
+++ b/include/fuse_lowlevel.h
@@ -114,6 +114,11 @@ struct fuse_ctx {
mode_t umask;
};
+struct fuse_forget_data {
+ uint64_t ino;
+ uint64_t nlookup;
+};
+
/* 'to_set' flags in setattr */
#define FUSE_SET_ATTR_MODE (1 << 0)
#define FUSE_SET_ATTR_UID (1 << 1)
@@ -913,6 +918,20 @@ struct fuse_lowlevel_ops {
*/
void (*retrieve_reply) (void *cookie, fuse_ino_t ino, off_t offset,
struct fuse_bufvec *bufv);
+
+ /**
+ * Forget about multiple inodes
+ *
+ * Introduced in version 2.9
+ *
+ * Valid replies:
+ * fuse_reply_none
+ *
+ * @param req request handle
+ */
+ void (*forget_multi) (fuse_req_t req, size_t count,
+ struct fuse_forget_data *forgets);
+
};
/**
diff --git a/lib/fuse.c b/lib/fuse.c
index 02af677..b8cce23 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -2493,17 +2493,34 @@ static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent,
reply_entry(req, &e, err);
}
+static void do_forget(struct fuse *f, fuse_ino_t ino, uint64_t nlookup)
+{
+ if (f->conf.debug)
+ fprintf(stderr, "FORGET %llu/%llu\n", (unsigned long long)ino,
+ (unsigned long long) nlookup);
+ forget_node(f, ino, nlookup);
+}
+
static void fuse_lib_forget(fuse_req_t req, fuse_ino_t ino,
unsigned long nlookup)
{
+ do_forget(req_fuse(req), ino, nlookup);
+ fuse_reply_none(req);
+}
+
+static void fuse_lib_forget_multi(fuse_req_t req, size_t count,
+ struct fuse_forget_data *forgets)
+{
struct fuse *f = req_fuse(req);
- if (f->conf.debug)
- fprintf(stderr, "FORGET %llu/%lu\n", (unsigned long long)ino,
- nlookup);
- forget_node(f, ino, nlookup);
+ size_t i;
+
+ for (i = 0; i < count; i++)
+ do_forget(f, forgets[i].ino, forgets[i].nlookup);
+
fuse_reply_none(req);
}
+
static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
@@ -3820,6 +3837,7 @@ static struct fuse_lowlevel_ops fuse_path_ops = {
.destroy = fuse_lib_destroy,
.lookup = fuse_lib_lookup,
.forget = fuse_lib_forget,
+ .forget_multi = fuse_lib_forget_multi,
.getattr = fuse_lib_getattr,
.setattr = fuse_lib_setattr,
.access = fuse_lib_access,
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index 4643a8a..faa415a 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -906,7 +906,10 @@ static void do_batch_forget(fuse_req_t req, fuse_ino_t nodeid,
(void) nodeid;
- if (req->f->op.forget) {
+ if (req->f->op.forget_multi) {
+ req->f->op.forget_multi(req, arg->count,
+ (struct fuse_forget_data *) param);
+ } else if (req->f->op.forget) {
for (i = 0; i < arg->count; i++) {
struct fuse_forget_one *forget = &param[i];
struct fuse_req *dummy_req;
@@ -922,8 +925,10 @@ static void do_batch_forget(fuse_req_t req, fuse_ino_t nodeid,
req->f->op.forget(dummy_req, forget->nodeid,
forget->nlookup);
}
+ fuse_reply_none(req);
+ } else {
+ fuse_reply_none(req);
}
- fuse_reply_none(req);
}
static void do_getattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)