154243797SSamuel Moelius // SPDX-License-Identifier: GPL-2.0-only 254243797SSamuel Moelius 354243797SSamuel Moelius #include "dev.h" 454243797SSamuel Moelius #include "fuse_i.h" 554243797SSamuel Moelius #include <linux/pagemap.h> 654243797SSamuel Moelius 754243797SSamuel Moelius static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size, 854243797SSamuel Moelius struct fuse_copy_state *cs) 954243797SSamuel Moelius { 1054243797SSamuel Moelius struct fuse_notify_poll_wakeup_out outarg; 1154243797SSamuel Moelius int err; 1254243797SSamuel Moelius 1354243797SSamuel Moelius if (size != sizeof(outarg)) 1454243797SSamuel Moelius return -EINVAL; 1554243797SSamuel Moelius 1654243797SSamuel Moelius err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1754243797SSamuel Moelius if (err) 1854243797SSamuel Moelius return err; 1954243797SSamuel Moelius 2054243797SSamuel Moelius fuse_copy_finish(cs); 2154243797SSamuel Moelius return fuse_notify_poll_wakeup(fc, &outarg); 2254243797SSamuel Moelius } 2354243797SSamuel Moelius 2454243797SSamuel Moelius static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size, 2554243797SSamuel Moelius struct fuse_copy_state *cs) 2654243797SSamuel Moelius { 2754243797SSamuel Moelius struct fuse_notify_inval_inode_out outarg; 2854243797SSamuel Moelius int err; 2954243797SSamuel Moelius 3054243797SSamuel Moelius if (size != sizeof(outarg)) 3154243797SSamuel Moelius return -EINVAL; 3254243797SSamuel Moelius 3354243797SSamuel Moelius err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 3454243797SSamuel Moelius if (err) 3554243797SSamuel Moelius return err; 3654243797SSamuel Moelius fuse_copy_finish(cs); 3754243797SSamuel Moelius 3854243797SSamuel Moelius down_read(&fc->killsb); 3954243797SSamuel Moelius err = fuse_reverse_inval_inode(fc, outarg.ino, 4054243797SSamuel Moelius outarg.off, outarg.len); 4154243797SSamuel Moelius up_read(&fc->killsb); 4254243797SSamuel Moelius return err; 4354243797SSamuel Moelius } 4454243797SSamuel Moelius 4554243797SSamuel Moelius static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, 4654243797SSamuel Moelius struct fuse_copy_state *cs) 4754243797SSamuel Moelius { 4854243797SSamuel Moelius struct fuse_notify_inval_entry_out outarg; 4954243797SSamuel Moelius int err; 5054243797SSamuel Moelius char *buf; 5154243797SSamuel Moelius struct qstr name; 5254243797SSamuel Moelius 5354243797SSamuel Moelius if (size < sizeof(outarg)) 5454243797SSamuel Moelius return -EINVAL; 5554243797SSamuel Moelius 5654243797SSamuel Moelius err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 5754243797SSamuel Moelius if (err) 5854243797SSamuel Moelius return err; 5954243797SSamuel Moelius 6054243797SSamuel Moelius if (outarg.namelen > fc->name_max) 6154243797SSamuel Moelius return -ENAMETOOLONG; 6254243797SSamuel Moelius 6354243797SSamuel Moelius err = -EINVAL; 6454243797SSamuel Moelius if (size != sizeof(outarg) + outarg.namelen + 1) 6554243797SSamuel Moelius return -EINVAL; 6654243797SSamuel Moelius 6754243797SSamuel Moelius buf = kzalloc(outarg.namelen + 1, GFP_KERNEL); 6854243797SSamuel Moelius if (!buf) 6954243797SSamuel Moelius return -ENOMEM; 7054243797SSamuel Moelius 7154243797SSamuel Moelius name.name = buf; 7254243797SSamuel Moelius name.len = outarg.namelen; 7354243797SSamuel Moelius err = fuse_copy_one(cs, buf, outarg.namelen + 1); 7454243797SSamuel Moelius if (err) 7554243797SSamuel Moelius goto err; 7654243797SSamuel Moelius fuse_copy_finish(cs); 7754243797SSamuel Moelius buf[outarg.namelen] = 0; 7854243797SSamuel Moelius 7954243797SSamuel Moelius down_read(&fc->killsb); 8054243797SSamuel Moelius err = fuse_reverse_inval_entry(fc, outarg.parent, 0, &name, outarg.flags); 8154243797SSamuel Moelius up_read(&fc->killsb); 8254243797SSamuel Moelius err: 8354243797SSamuel Moelius kfree(buf); 8454243797SSamuel Moelius return err; 8554243797SSamuel Moelius } 8654243797SSamuel Moelius 8754243797SSamuel Moelius static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size, 8854243797SSamuel Moelius struct fuse_copy_state *cs) 8954243797SSamuel Moelius { 9054243797SSamuel Moelius struct fuse_notify_delete_out outarg; 9154243797SSamuel Moelius int err; 9254243797SSamuel Moelius char *buf; 9354243797SSamuel Moelius struct qstr name; 9454243797SSamuel Moelius 9554243797SSamuel Moelius if (size < sizeof(outarg)) 9654243797SSamuel Moelius return -EINVAL; 9754243797SSamuel Moelius 9854243797SSamuel Moelius err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 9954243797SSamuel Moelius if (err) 10054243797SSamuel Moelius return err; 10154243797SSamuel Moelius 10254243797SSamuel Moelius if (outarg.namelen > fc->name_max) 10354243797SSamuel Moelius return -ENAMETOOLONG; 10454243797SSamuel Moelius 10554243797SSamuel Moelius if (size != sizeof(outarg) + outarg.namelen + 1) 10654243797SSamuel Moelius return -EINVAL; 10754243797SSamuel Moelius 10854243797SSamuel Moelius buf = kzalloc(outarg.namelen + 1, GFP_KERNEL); 10954243797SSamuel Moelius if (!buf) 11054243797SSamuel Moelius return -ENOMEM; 11154243797SSamuel Moelius 11254243797SSamuel Moelius name.name = buf; 11354243797SSamuel Moelius name.len = outarg.namelen; 11454243797SSamuel Moelius err = fuse_copy_one(cs, buf, outarg.namelen + 1); 11554243797SSamuel Moelius if (err) 11654243797SSamuel Moelius goto err; 11754243797SSamuel Moelius fuse_copy_finish(cs); 11854243797SSamuel Moelius buf[outarg.namelen] = 0; 11954243797SSamuel Moelius 12054243797SSamuel Moelius down_read(&fc->killsb); 12154243797SSamuel Moelius err = fuse_reverse_inval_entry(fc, outarg.parent, outarg.child, &name, 0); 12254243797SSamuel Moelius up_read(&fc->killsb); 12354243797SSamuel Moelius err: 12454243797SSamuel Moelius kfree(buf); 12554243797SSamuel Moelius return err; 12654243797SSamuel Moelius } 12754243797SSamuel Moelius 12854243797SSamuel Moelius static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, 12954243797SSamuel Moelius struct fuse_copy_state *cs) 13054243797SSamuel Moelius { 13154243797SSamuel Moelius struct fuse_notify_store_out outarg; 13254243797SSamuel Moelius struct inode *inode; 13354243797SSamuel Moelius struct address_space *mapping; 13454243797SSamuel Moelius u64 nodeid; 13554243797SSamuel Moelius int err; 13654243797SSamuel Moelius unsigned int num; 13754243797SSamuel Moelius loff_t file_size; 13854243797SSamuel Moelius loff_t pos; 13954243797SSamuel Moelius loff_t end; 14054243797SSamuel Moelius 14154243797SSamuel Moelius if (size < sizeof(outarg)) 14254243797SSamuel Moelius return -EINVAL; 14354243797SSamuel Moelius 14454243797SSamuel Moelius err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 14554243797SSamuel Moelius if (err) 14654243797SSamuel Moelius return err; 14754243797SSamuel Moelius 14854243797SSamuel Moelius if (size - sizeof(outarg) != outarg.size) 14954243797SSamuel Moelius return -EINVAL; 15054243797SSamuel Moelius 15154243797SSamuel Moelius if (outarg.offset >= MAX_LFS_FILESIZE) 15254243797SSamuel Moelius return -EINVAL; 15354243797SSamuel Moelius 15454243797SSamuel Moelius nodeid = outarg.nodeid; 15554243797SSamuel Moelius pos = outarg.offset; 15654243797SSamuel Moelius num = min(outarg.size, MAX_LFS_FILESIZE - pos); 15754243797SSamuel Moelius 15854243797SSamuel Moelius down_read(&fc->killsb); 15954243797SSamuel Moelius 16054243797SSamuel Moelius err = -ENOENT; 16154243797SSamuel Moelius inode = fuse_ilookup(fc, nodeid, NULL); 16254243797SSamuel Moelius if (!inode) 16354243797SSamuel Moelius goto out_up_killsb; 164*6edc2007SLinus Torvalds if (!S_ISREG(inode->i_mode)) { 165*6edc2007SLinus Torvalds err = -EINVAL; 166*6edc2007SLinus Torvalds goto out_iput; 167*6edc2007SLinus Torvalds } 16854243797SSamuel Moelius 16954243797SSamuel Moelius mapping = inode->i_mapping; 17054243797SSamuel Moelius file_size = i_size_read(inode); 17154243797SSamuel Moelius end = pos + num; 17254243797SSamuel Moelius if (end > file_size) { 17354243797SSamuel Moelius file_size = end; 17454243797SSamuel Moelius fuse_write_update_attr(inode, file_size, num); 17554243797SSamuel Moelius } 17654243797SSamuel Moelius 17754243797SSamuel Moelius while (num) { 17854243797SSamuel Moelius struct folio *folio; 17954243797SSamuel Moelius unsigned int folio_offset; 18054243797SSamuel Moelius unsigned int nr_bytes; 18154243797SSamuel Moelius pgoff_t index = pos >> PAGE_SHIFT; 18254243797SSamuel Moelius 18354243797SSamuel Moelius folio = filemap_grab_folio(mapping, index); 18454243797SSamuel Moelius err = PTR_ERR(folio); 18554243797SSamuel Moelius if (IS_ERR(folio)) 18654243797SSamuel Moelius goto out_iput; 18754243797SSamuel Moelius 18854243797SSamuel Moelius folio_offset = offset_in_folio(folio, pos); 18954243797SSamuel Moelius nr_bytes = min(num, folio_size(folio) - folio_offset); 19054243797SSamuel Moelius 19154243797SSamuel Moelius err = fuse_copy_folio(cs, &folio, folio_offset, nr_bytes, 0); 19254243797SSamuel Moelius if (!folio_test_uptodate(folio) && !err && folio_offset == 0 && 19354243797SSamuel Moelius (nr_bytes == folio_size(folio) || file_size == end)) { 19454243797SSamuel Moelius folio_zero_segment(folio, nr_bytes, folio_size(folio)); 19554243797SSamuel Moelius folio_mark_uptodate(folio); 19654243797SSamuel Moelius } 19754243797SSamuel Moelius folio_unlock(folio); 19854243797SSamuel Moelius folio_put(folio); 19954243797SSamuel Moelius 20054243797SSamuel Moelius if (err) 20154243797SSamuel Moelius goto out_iput; 20254243797SSamuel Moelius 20354243797SSamuel Moelius pos += nr_bytes; 20454243797SSamuel Moelius num -= nr_bytes; 20554243797SSamuel Moelius } 20654243797SSamuel Moelius 20754243797SSamuel Moelius err = 0; 20854243797SSamuel Moelius 20954243797SSamuel Moelius out_iput: 21054243797SSamuel Moelius iput(inode); 21154243797SSamuel Moelius out_up_killsb: 21254243797SSamuel Moelius up_read(&fc->killsb); 21354243797SSamuel Moelius return err; 21454243797SSamuel Moelius } 21554243797SSamuel Moelius 21654243797SSamuel Moelius struct fuse_retrieve_args { 21754243797SSamuel Moelius struct fuse_args_pages ap; 21854243797SSamuel Moelius struct fuse_notify_retrieve_in inarg; 21954243797SSamuel Moelius }; 22054243797SSamuel Moelius 22154243797SSamuel Moelius static void fuse_retrieve_end(struct fuse_args *args, int error) 22254243797SSamuel Moelius { 22354243797SSamuel Moelius struct fuse_retrieve_args *ra = 22454243797SSamuel Moelius container_of(args, typeof(*ra), ap.args); 22554243797SSamuel Moelius 22654243797SSamuel Moelius release_pages(ra->ap.folios, ra->ap.num_folios); 22754243797SSamuel Moelius kfree(ra); 22854243797SSamuel Moelius } 22954243797SSamuel Moelius 23054243797SSamuel Moelius static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode, 23154243797SSamuel Moelius struct fuse_notify_retrieve_out *outarg) 23254243797SSamuel Moelius { 23354243797SSamuel Moelius int err; 23454243797SSamuel Moelius struct address_space *mapping = inode->i_mapping; 23554243797SSamuel Moelius loff_t file_size; 23654243797SSamuel Moelius unsigned int num; 23754243797SSamuel Moelius unsigned int offset; 23854243797SSamuel Moelius size_t total_len = 0; 23954243797SSamuel Moelius unsigned int num_pages; 24054243797SSamuel Moelius struct fuse_conn *fc = fm->fc; 24154243797SSamuel Moelius struct fuse_retrieve_args *ra; 24254243797SSamuel Moelius size_t args_size = sizeof(*ra); 24354243797SSamuel Moelius struct fuse_args_pages *ap; 24454243797SSamuel Moelius struct fuse_args *args; 24554243797SSamuel Moelius loff_t pos = outarg->offset; 24654243797SSamuel Moelius 24754243797SSamuel Moelius offset = offset_in_page(pos); 24854243797SSamuel Moelius file_size = i_size_read(inode); 24954243797SSamuel Moelius 25054243797SSamuel Moelius num = min(outarg->size, fc->max_write); 25154243797SSamuel Moelius if (pos > file_size) 25254243797SSamuel Moelius num = 0; 25354243797SSamuel Moelius else if (num > file_size - pos) 25454243797SSamuel Moelius num = file_size - pos; 25554243797SSamuel Moelius 25654243797SSamuel Moelius num_pages = DIV_ROUND_UP(num + offset, PAGE_SIZE); 25754243797SSamuel Moelius num_pages = min(num_pages, fc->max_pages); 25854243797SSamuel Moelius num = min(num, num_pages << PAGE_SHIFT); 25954243797SSamuel Moelius 26054243797SSamuel Moelius args_size += num_pages * (sizeof(ap->folios[0]) + sizeof(ap->descs[0])); 26154243797SSamuel Moelius 26254243797SSamuel Moelius ra = kzalloc(args_size, GFP_KERNEL); 26354243797SSamuel Moelius if (!ra) 26454243797SSamuel Moelius return -ENOMEM; 26554243797SSamuel Moelius 26654243797SSamuel Moelius ap = &ra->ap; 26754243797SSamuel Moelius ap->folios = (void *) (ra + 1); 26854243797SSamuel Moelius ap->descs = (void *) (ap->folios + num_pages); 26954243797SSamuel Moelius 27054243797SSamuel Moelius args = &ap->args; 27154243797SSamuel Moelius args->nodeid = outarg->nodeid; 27254243797SSamuel Moelius args->opcode = FUSE_NOTIFY_REPLY; 27354243797SSamuel Moelius args->in_numargs = 3; 27454243797SSamuel Moelius args->in_pages = true; 27554243797SSamuel Moelius args->end = fuse_retrieve_end; 27654243797SSamuel Moelius 27754243797SSamuel Moelius while (num && ap->num_folios < num_pages) { 27854243797SSamuel Moelius struct folio *folio; 27954243797SSamuel Moelius unsigned int folio_offset; 28054243797SSamuel Moelius unsigned int nr_bytes; 28154243797SSamuel Moelius pgoff_t index = pos >> PAGE_SHIFT; 28254243797SSamuel Moelius 28354243797SSamuel Moelius folio = filemap_get_folio(mapping, index); 28454243797SSamuel Moelius if (IS_ERR(folio)) 28554243797SSamuel Moelius break; 286*6edc2007SLinus Torvalds if (!folio_test_uptodate(folio)) { 287*6edc2007SLinus Torvalds folio_put(folio); 288*6edc2007SLinus Torvalds break; 289*6edc2007SLinus Torvalds } 29054243797SSamuel Moelius 29154243797SSamuel Moelius folio_offset = offset_in_folio(folio, pos); 29254243797SSamuel Moelius nr_bytes = min(folio_size(folio) - folio_offset, num); 29354243797SSamuel Moelius 29454243797SSamuel Moelius ap->folios[ap->num_folios] = folio; 29554243797SSamuel Moelius ap->descs[ap->num_folios].offset = folio_offset; 29654243797SSamuel Moelius ap->descs[ap->num_folios].length = nr_bytes; 29754243797SSamuel Moelius ap->num_folios++; 29854243797SSamuel Moelius 29954243797SSamuel Moelius pos += nr_bytes; 30054243797SSamuel Moelius num -= nr_bytes; 30154243797SSamuel Moelius total_len += nr_bytes; 30254243797SSamuel Moelius } 30354243797SSamuel Moelius ra->inarg.offset = outarg->offset; 30454243797SSamuel Moelius ra->inarg.size = total_len; 30554243797SSamuel Moelius fuse_set_zero_arg0(args); 30654243797SSamuel Moelius args->in_args[1].size = sizeof(ra->inarg); 30754243797SSamuel Moelius args->in_args[1].value = &ra->inarg; 30854243797SSamuel Moelius args->in_args[2].size = total_len; 30954243797SSamuel Moelius 31054243797SSamuel Moelius err = fuse_simple_notify_reply(fm, args, outarg->notify_unique); 31154243797SSamuel Moelius if (err) 31254243797SSamuel Moelius fuse_retrieve_end(args, err); 31354243797SSamuel Moelius 31454243797SSamuel Moelius return err; 31554243797SSamuel Moelius } 31654243797SSamuel Moelius 31754243797SSamuel Moelius static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, 31854243797SSamuel Moelius struct fuse_copy_state *cs) 31954243797SSamuel Moelius { 32054243797SSamuel Moelius struct fuse_notify_retrieve_out outarg; 32154243797SSamuel Moelius struct fuse_mount *fm; 32254243797SSamuel Moelius struct inode *inode; 32354243797SSamuel Moelius u64 nodeid; 32454243797SSamuel Moelius int err; 32554243797SSamuel Moelius 32654243797SSamuel Moelius if (size != sizeof(outarg)) 32754243797SSamuel Moelius return -EINVAL; 32854243797SSamuel Moelius 32954243797SSamuel Moelius err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 33054243797SSamuel Moelius if (err) 33154243797SSamuel Moelius return err; 33254243797SSamuel Moelius 33354243797SSamuel Moelius fuse_copy_finish(cs); 33454243797SSamuel Moelius 33554243797SSamuel Moelius if (outarg.offset >= MAX_LFS_FILESIZE) 33654243797SSamuel Moelius return -EINVAL; 33754243797SSamuel Moelius 33854243797SSamuel Moelius down_read(&fc->killsb); 33954243797SSamuel Moelius err = -ENOENT; 34054243797SSamuel Moelius nodeid = outarg.nodeid; 34154243797SSamuel Moelius 34254243797SSamuel Moelius inode = fuse_ilookup(fc, nodeid, &fm); 34354243797SSamuel Moelius if (inode) { 344*6edc2007SLinus Torvalds err = -EINVAL; 345*6edc2007SLinus Torvalds if (S_ISREG(inode->i_mode)) 34654243797SSamuel Moelius err = fuse_retrieve(fm, inode, &outarg); 34754243797SSamuel Moelius iput(inode); 34854243797SSamuel Moelius } 34954243797SSamuel Moelius up_read(&fc->killsb); 35054243797SSamuel Moelius 35154243797SSamuel Moelius return err; 35254243797SSamuel Moelius } 35354243797SSamuel Moelius 35454243797SSamuel Moelius static int fuse_notify_resend(struct fuse_conn *fc) 35554243797SSamuel Moelius { 35654243797SSamuel Moelius fuse_chan_resend(fc->chan); 35754243797SSamuel Moelius return 0; 35854243797SSamuel Moelius } 35954243797SSamuel Moelius 36054243797SSamuel Moelius /* 3610fa83460SJun Wu * Increments the fuse connection epoch. This will cause dentries and 3620fa83460SJun Wu * readdir caches from previous epochs to be invalidated. Additionally, 3630fa83460SJun Wu * if inval_wq is set, a work queue is scheduled to trigger the invalidation. 36454243797SSamuel Moelius */ 36554243797SSamuel Moelius static int fuse_notify_inc_epoch(struct fuse_conn *fc) 36654243797SSamuel Moelius { 36754243797SSamuel Moelius atomic_inc(&fc->epoch); 36854243797SSamuel Moelius if (inval_wq) 36954243797SSamuel Moelius schedule_work(&fc->epoch_work); 37054243797SSamuel Moelius 37154243797SSamuel Moelius return 0; 37254243797SSamuel Moelius } 37354243797SSamuel Moelius 37454243797SSamuel Moelius static int fuse_notify_prune(struct fuse_conn *fc, unsigned int size, 37554243797SSamuel Moelius struct fuse_copy_state *cs) 37654243797SSamuel Moelius { 37754243797SSamuel Moelius struct fuse_notify_prune_out outarg; 37854243797SSamuel Moelius const unsigned int batch = 512; 37954243797SSamuel Moelius u64 *nodeids __free(kfree) = kmalloc(sizeof(u64) * batch, GFP_KERNEL); 38054243797SSamuel Moelius unsigned int num, i; 38154243797SSamuel Moelius int err; 38254243797SSamuel Moelius 38354243797SSamuel Moelius if (!nodeids) 38454243797SSamuel Moelius return -ENOMEM; 38554243797SSamuel Moelius 38654243797SSamuel Moelius if (size < sizeof(outarg)) 38754243797SSamuel Moelius return -EINVAL; 38854243797SSamuel Moelius 38954243797SSamuel Moelius err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 39054243797SSamuel Moelius if (err) 39154243797SSamuel Moelius return err; 39254243797SSamuel Moelius 39354243797SSamuel Moelius if (size - sizeof(outarg) != array_size(outarg.count, sizeof(u64))) 39454243797SSamuel Moelius return -EINVAL; 39554243797SSamuel Moelius 39654243797SSamuel Moelius for (; outarg.count; outarg.count -= num) { 39754243797SSamuel Moelius num = min(batch, outarg.count); 39854243797SSamuel Moelius err = fuse_copy_one(cs, nodeids, num * sizeof(u64)); 39954243797SSamuel Moelius if (err) 40054243797SSamuel Moelius return err; 40154243797SSamuel Moelius 40254243797SSamuel Moelius scoped_guard(rwsem_read, &fc->killsb) { 40354243797SSamuel Moelius for (i = 0; i < num; i++) 40454243797SSamuel Moelius fuse_try_prune_one_inode(fc, nodeids[i]); 40554243797SSamuel Moelius } 40654243797SSamuel Moelius } 40754243797SSamuel Moelius return 0; 40854243797SSamuel Moelius } 40954243797SSamuel Moelius 41054243797SSamuel Moelius int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, 41154243797SSamuel Moelius unsigned int size, struct fuse_copy_state *cs) 41254243797SSamuel Moelius { 41354243797SSamuel Moelius switch (code) { 41454243797SSamuel Moelius case FUSE_NOTIFY_POLL: 41554243797SSamuel Moelius return fuse_notify_poll(fc, size, cs); 41654243797SSamuel Moelius 41754243797SSamuel Moelius case FUSE_NOTIFY_INVAL_INODE: 41854243797SSamuel Moelius return fuse_notify_inval_inode(fc, size, cs); 41954243797SSamuel Moelius 42054243797SSamuel Moelius case FUSE_NOTIFY_INVAL_ENTRY: 42154243797SSamuel Moelius return fuse_notify_inval_entry(fc, size, cs); 42254243797SSamuel Moelius 42354243797SSamuel Moelius case FUSE_NOTIFY_STORE: 42454243797SSamuel Moelius return fuse_notify_store(fc, size, cs); 42554243797SSamuel Moelius 42654243797SSamuel Moelius case FUSE_NOTIFY_RETRIEVE: 42754243797SSamuel Moelius return fuse_notify_retrieve(fc, size, cs); 42854243797SSamuel Moelius 42954243797SSamuel Moelius case FUSE_NOTIFY_DELETE: 43054243797SSamuel Moelius return fuse_notify_delete(fc, size, cs); 43154243797SSamuel Moelius 43254243797SSamuel Moelius case FUSE_NOTIFY_RESEND: 43354243797SSamuel Moelius return fuse_notify_resend(fc); 43454243797SSamuel Moelius 43554243797SSamuel Moelius case FUSE_NOTIFY_INC_EPOCH: 43654243797SSamuel Moelius return fuse_notify_inc_epoch(fc); 43754243797SSamuel Moelius 43854243797SSamuel Moelius case FUSE_NOTIFY_PRUNE: 43954243797SSamuel Moelius return fuse_notify_prune(fc, size, cs); 44054243797SSamuel Moelius 44154243797SSamuel Moelius default: 44254243797SSamuel Moelius return -EINVAL; 44354243797SSamuel Moelius } 44454243797SSamuel Moelius } 445