From: Miklos Szeredi Date: Thu, 19 May 2011 13:30:01 +0000 (+0200) Subject: Add ->forget_multi() operation X-Git-Tag: fuse_2_9_0~43 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=7819846300dc036fb94569feff4f86cd33b459d9;p=qemu-gpiodev%2Flibfuse.git Add ->forget_multi() operation Add ->forget_multi() operation to the lowlevel API. The filesystem may implement this to process multiple forget requests in one call --- 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 * 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 = ¶m[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)