1334f485dSMiklos Szeredi /* 2334f485dSMiklos Szeredi FUSE: Filesystem in Userspace 31729a16cSMiklos Szeredi Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4334f485dSMiklos Szeredi 5334f485dSMiklos Szeredi This program can be distributed under the terms of the GNU GPL. 6334f485dSMiklos Szeredi See the file COPYING. 7334f485dSMiklos Szeredi */ 8334f485dSMiklos Szeredi 9334f485dSMiklos Szeredi #include "fuse_i.h" 10334f485dSMiklos Szeredi 11334f485dSMiklos Szeredi #include <linux/init.h> 12334f485dSMiklos Szeredi #include <linux/module.h> 13334f485dSMiklos Szeredi #include <linux/poll.h> 14334f485dSMiklos Szeredi #include <linux/uio.h> 15334f485dSMiklos Szeredi #include <linux/miscdevice.h> 16334f485dSMiklos Szeredi #include <linux/pagemap.h> 17334f485dSMiklos Szeredi #include <linux/file.h> 18334f485dSMiklos Szeredi #include <linux/slab.h> 19dd3bb14fSMiklos Szeredi #include <linux/pipe_fs_i.h> 20ce534fb0SMiklos Szeredi #include <linux/swap.h> 21ce534fb0SMiklos Szeredi #include <linux/splice.h> 22334f485dSMiklos Szeredi 23334f485dSMiklos Szeredi MODULE_ALIAS_MISCDEV(FUSE_MINOR); 24578454ffSKay Sievers MODULE_ALIAS("devname:fuse"); 25334f485dSMiklos Szeredi 26e18b890bSChristoph Lameter static struct kmem_cache *fuse_req_cachep; 27334f485dSMiklos Szeredi 288bfc016dSMiklos Szeredi static struct fuse_conn *fuse_get_conn(struct file *file) 29334f485dSMiklos Szeredi { 300720b315SMiklos Szeredi /* 310720b315SMiklos Szeredi * Lockless access is OK, because file->private data is set 320720b315SMiklos Szeredi * once during mount and is valid until the file is released. 330720b315SMiklos Szeredi */ 340720b315SMiklos Szeredi return file->private_data; 35334f485dSMiklos Szeredi } 36334f485dSMiklos Szeredi 374250c066SMaxim Patlasov static void fuse_request_init(struct fuse_req *req, struct page **pages, 38b2430d75SMaxim Patlasov struct fuse_page_desc *page_descs, 394250c066SMaxim Patlasov unsigned npages) 40334f485dSMiklos Szeredi { 41334f485dSMiklos Szeredi memset(req, 0, sizeof(*req)); 424250c066SMaxim Patlasov memset(pages, 0, sizeof(*pages) * npages); 43b2430d75SMaxim Patlasov memset(page_descs, 0, sizeof(*page_descs) * npages); 44334f485dSMiklos Szeredi INIT_LIST_HEAD(&req->list); 45a4d27e75SMiklos Szeredi INIT_LIST_HEAD(&req->intr_entry); 46334f485dSMiklos Szeredi init_waitqueue_head(&req->waitq); 47334f485dSMiklos Szeredi atomic_set(&req->count, 1); 484250c066SMaxim Patlasov req->pages = pages; 49b2430d75SMaxim Patlasov req->page_descs = page_descs; 504250c066SMaxim Patlasov req->max_pages = npages; 5133e14b4dSMiklos Szeredi __set_bit(FR_PENDING, &req->flags); 52334f485dSMiklos Szeredi } 53334f485dSMiklos Szeredi 544250c066SMaxim Patlasov static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) 55334f485dSMiklos Szeredi { 564250c066SMaxim Patlasov struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, flags); 574250c066SMaxim Patlasov if (req) { 584250c066SMaxim Patlasov struct page **pages; 59b2430d75SMaxim Patlasov struct fuse_page_desc *page_descs; 604250c066SMaxim Patlasov 61b2430d75SMaxim Patlasov if (npages <= FUSE_REQ_INLINE_PAGES) { 624250c066SMaxim Patlasov pages = req->inline_pages; 63b2430d75SMaxim Patlasov page_descs = req->inline_page_descs; 64b2430d75SMaxim Patlasov } else { 654250c066SMaxim Patlasov pages = kmalloc(sizeof(struct page *) * npages, flags); 66b2430d75SMaxim Patlasov page_descs = kmalloc(sizeof(struct fuse_page_desc) * 67b2430d75SMaxim Patlasov npages, flags); 68b2430d75SMaxim Patlasov } 694250c066SMaxim Patlasov 70b2430d75SMaxim Patlasov if (!pages || !page_descs) { 71b2430d75SMaxim Patlasov kfree(pages); 72b2430d75SMaxim Patlasov kfree(page_descs); 734250c066SMaxim Patlasov kmem_cache_free(fuse_req_cachep, req); 744250c066SMaxim Patlasov return NULL; 754250c066SMaxim Patlasov } 764250c066SMaxim Patlasov 77b2430d75SMaxim Patlasov fuse_request_init(req, pages, page_descs, npages); 784250c066SMaxim Patlasov } 79334f485dSMiklos Szeredi return req; 80334f485dSMiklos Szeredi } 814250c066SMaxim Patlasov 824250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc(unsigned npages) 834250c066SMaxim Patlasov { 844250c066SMaxim Patlasov return __fuse_request_alloc(npages, GFP_KERNEL); 854250c066SMaxim Patlasov } 8608cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_alloc); 87334f485dSMiklos Szeredi 884250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc_nofs(unsigned npages) 893be5a52bSMiklos Szeredi { 904250c066SMaxim Patlasov return __fuse_request_alloc(npages, GFP_NOFS); 913be5a52bSMiklos Szeredi } 923be5a52bSMiklos Szeredi 93334f485dSMiklos Szeredi void fuse_request_free(struct fuse_req *req) 94334f485dSMiklos Szeredi { 95b2430d75SMaxim Patlasov if (req->pages != req->inline_pages) { 964250c066SMaxim Patlasov kfree(req->pages); 97b2430d75SMaxim Patlasov kfree(req->page_descs); 98b2430d75SMaxim Patlasov } 99334f485dSMiklos Szeredi kmem_cache_free(fuse_req_cachep, req); 100334f485dSMiklos Szeredi } 101334f485dSMiklos Szeredi 1028bfc016dSMiklos Szeredi static void block_sigs(sigset_t *oldset) 103334f485dSMiklos Szeredi { 104334f485dSMiklos Szeredi sigset_t mask; 105334f485dSMiklos Szeredi 106334f485dSMiklos Szeredi siginitsetinv(&mask, sigmask(SIGKILL)); 107334f485dSMiklos Szeredi sigprocmask(SIG_BLOCK, &mask, oldset); 108334f485dSMiklos Szeredi } 109334f485dSMiklos Szeredi 1108bfc016dSMiklos Szeredi static void restore_sigs(sigset_t *oldset) 111334f485dSMiklos Szeredi { 112334f485dSMiklos Szeredi sigprocmask(SIG_SETMASK, oldset, NULL); 113334f485dSMiklos Szeredi } 114334f485dSMiklos Szeredi 11536cf66edSMaxim Patlasov void __fuse_get_request(struct fuse_req *req) 116334f485dSMiklos Szeredi { 117334f485dSMiklos Szeredi atomic_inc(&req->count); 118334f485dSMiklos Szeredi } 119334f485dSMiklos Szeredi 120334f485dSMiklos Szeredi /* Must be called with > 1 refcount */ 121334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req) 122334f485dSMiklos Szeredi { 123334f485dSMiklos Szeredi BUG_ON(atomic_read(&req->count) < 2); 124334f485dSMiklos Szeredi atomic_dec(&req->count); 125334f485dSMiklos Szeredi } 126334f485dSMiklos Szeredi 12733649c91SMiklos Szeredi static void fuse_req_init_context(struct fuse_req *req) 12833649c91SMiklos Szeredi { 129499dcf20SEric W. Biederman req->in.h.uid = from_kuid_munged(&init_user_ns, current_fsuid()); 130499dcf20SEric W. Biederman req->in.h.gid = from_kgid_munged(&init_user_ns, current_fsgid()); 13133649c91SMiklos Szeredi req->in.h.pid = current->pid; 13233649c91SMiklos Szeredi } 13333649c91SMiklos Szeredi 1349759bd51SMiklos Szeredi void fuse_set_initialized(struct fuse_conn *fc) 1359759bd51SMiklos Szeredi { 1369759bd51SMiklos Szeredi /* Make sure stores before this are seen on another CPU */ 1379759bd51SMiklos Szeredi smp_wmb(); 1389759bd51SMiklos Szeredi fc->initialized = 1; 1399759bd51SMiklos Szeredi } 1409759bd51SMiklos Szeredi 1410aada884SMaxim Patlasov static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background) 1420aada884SMaxim Patlasov { 1430aada884SMaxim Patlasov return !fc->initialized || (for_background && fc->blocked); 1440aada884SMaxim Patlasov } 1450aada884SMaxim Patlasov 1468b41e671SMaxim Patlasov static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages, 1478b41e671SMaxim Patlasov bool for_background) 148334f485dSMiklos Szeredi { 14908a53cdcSMiklos Szeredi struct fuse_req *req; 1500aada884SMaxim Patlasov int err; 1510aada884SMaxim Patlasov atomic_inc(&fc->num_waiting); 1520aada884SMaxim Patlasov 1530aada884SMaxim Patlasov if (fuse_block_alloc(fc, for_background)) { 15408a53cdcSMiklos Szeredi sigset_t oldset; 1559bc5dddaSMiklos Szeredi int intr; 15608a53cdcSMiklos Szeredi 15708a53cdcSMiklos Szeredi block_sigs(&oldset); 158722d2beaSMaxim Patlasov intr = wait_event_interruptible_exclusive(fc->blocked_waitq, 1590aada884SMaxim Patlasov !fuse_block_alloc(fc, for_background)); 16008a53cdcSMiklos Szeredi restore_sigs(&oldset); 1619bc5dddaSMiklos Szeredi err = -EINTR; 1629bc5dddaSMiklos Szeredi if (intr) 1639bc5dddaSMiklos Szeredi goto out; 1640aada884SMaxim Patlasov } 1659759bd51SMiklos Szeredi /* Matches smp_wmb() in fuse_set_initialized() */ 1669759bd51SMiklos Szeredi smp_rmb(); 16708a53cdcSMiklos Szeredi 16851eb01e7SMiklos Szeredi err = -ENOTCONN; 16951eb01e7SMiklos Szeredi if (!fc->connected) 17051eb01e7SMiklos Szeredi goto out; 17151eb01e7SMiklos Szeredi 172de155226SMiklos Szeredi err = -ECONNREFUSED; 173de155226SMiklos Szeredi if (fc->conn_error) 174de155226SMiklos Szeredi goto out; 175de155226SMiklos Szeredi 176b111c8c0SMaxim Patlasov req = fuse_request_alloc(npages); 1779bc5dddaSMiklos Szeredi err = -ENOMEM; 178722d2beaSMaxim Patlasov if (!req) { 179722d2beaSMaxim Patlasov if (for_background) 180722d2beaSMaxim Patlasov wake_up(&fc->blocked_waitq); 1819bc5dddaSMiklos Szeredi goto out; 182722d2beaSMaxim Patlasov } 183334f485dSMiklos Szeredi 18433649c91SMiklos Szeredi fuse_req_init_context(req); 185825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 186825d6d33SMiklos Szeredi if (for_background) 187825d6d33SMiklos Szeredi __set_bit(FR_BACKGROUND, &req->flags); 188825d6d33SMiklos Szeredi 189334f485dSMiklos Szeredi return req; 1909bc5dddaSMiklos Szeredi 1919bc5dddaSMiklos Szeredi out: 1929bc5dddaSMiklos Szeredi atomic_dec(&fc->num_waiting); 1939bc5dddaSMiklos Szeredi return ERR_PTR(err); 194334f485dSMiklos Szeredi } 1958b41e671SMaxim Patlasov 1968b41e671SMaxim Patlasov struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages) 1978b41e671SMaxim Patlasov { 1988b41e671SMaxim Patlasov return __fuse_get_req(fc, npages, false); 1998b41e671SMaxim Patlasov } 20008cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_get_req); 201334f485dSMiklos Szeredi 2028b41e671SMaxim Patlasov struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc, 2038b41e671SMaxim Patlasov unsigned npages) 2048b41e671SMaxim Patlasov { 2058b41e671SMaxim Patlasov return __fuse_get_req(fc, npages, true); 2068b41e671SMaxim Patlasov } 2078b41e671SMaxim Patlasov EXPORT_SYMBOL_GPL(fuse_get_req_for_background); 2088b41e671SMaxim Patlasov 20933649c91SMiklos Szeredi /* 21033649c91SMiklos Szeredi * Return request in fuse_file->reserved_req. However that may 21133649c91SMiklos Szeredi * currently be in use. If that is the case, wait for it to become 21233649c91SMiklos Szeredi * available. 21333649c91SMiklos Szeredi */ 21433649c91SMiklos Szeredi static struct fuse_req *get_reserved_req(struct fuse_conn *fc, 21533649c91SMiklos Szeredi struct file *file) 21633649c91SMiklos Szeredi { 21733649c91SMiklos Szeredi struct fuse_req *req = NULL; 21833649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 21933649c91SMiklos Szeredi 22033649c91SMiklos Szeredi do { 221de5e3decSMiklos Szeredi wait_event(fc->reserved_req_waitq, ff->reserved_req); 22233649c91SMiklos Szeredi spin_lock(&fc->lock); 22333649c91SMiklos Szeredi if (ff->reserved_req) { 22433649c91SMiklos Szeredi req = ff->reserved_req; 22533649c91SMiklos Szeredi ff->reserved_req = NULL; 226cb0942b8SAl Viro req->stolen_file = get_file(file); 22733649c91SMiklos Szeredi } 22833649c91SMiklos Szeredi spin_unlock(&fc->lock); 22933649c91SMiklos Szeredi } while (!req); 23033649c91SMiklos Szeredi 23133649c91SMiklos Szeredi return req; 23233649c91SMiklos Szeredi } 23333649c91SMiklos Szeredi 23433649c91SMiklos Szeredi /* 23533649c91SMiklos Szeredi * Put stolen request back into fuse_file->reserved_req 23633649c91SMiklos Szeredi */ 23733649c91SMiklos Szeredi static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req) 23833649c91SMiklos Szeredi { 23933649c91SMiklos Szeredi struct file *file = req->stolen_file; 24033649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 24133649c91SMiklos Szeredi 24233649c91SMiklos Szeredi spin_lock(&fc->lock); 243b2430d75SMaxim Patlasov fuse_request_init(req, req->pages, req->page_descs, req->max_pages); 24433649c91SMiklos Szeredi BUG_ON(ff->reserved_req); 24533649c91SMiklos Szeredi ff->reserved_req = req; 246de5e3decSMiklos Szeredi wake_up_all(&fc->reserved_req_waitq); 24733649c91SMiklos Szeredi spin_unlock(&fc->lock); 24833649c91SMiklos Szeredi fput(file); 24933649c91SMiklos Szeredi } 25033649c91SMiklos Szeredi 25133649c91SMiklos Szeredi /* 25233649c91SMiklos Szeredi * Gets a requests for a file operation, always succeeds 25333649c91SMiklos Szeredi * 25433649c91SMiklos Szeredi * This is used for sending the FLUSH request, which must get to 25533649c91SMiklos Szeredi * userspace, due to POSIX locks which may need to be unlocked. 25633649c91SMiklos Szeredi * 25733649c91SMiklos Szeredi * If allocation fails due to OOM, use the reserved request in 25833649c91SMiklos Szeredi * fuse_file. 25933649c91SMiklos Szeredi * 26033649c91SMiklos Szeredi * This is very unlikely to deadlock accidentally, since the 26133649c91SMiklos Szeredi * filesystem should not have it's own file open. If deadlock is 26233649c91SMiklos Szeredi * intentional, it can still be broken by "aborting" the filesystem. 26333649c91SMiklos Szeredi */ 264b111c8c0SMaxim Patlasov struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, 265b111c8c0SMaxim Patlasov struct file *file) 26633649c91SMiklos Szeredi { 26733649c91SMiklos Szeredi struct fuse_req *req; 26833649c91SMiklos Szeredi 26933649c91SMiklos Szeredi atomic_inc(&fc->num_waiting); 2700aada884SMaxim Patlasov wait_event(fc->blocked_waitq, fc->initialized); 2719759bd51SMiklos Szeredi /* Matches smp_wmb() in fuse_set_initialized() */ 2729759bd51SMiklos Szeredi smp_rmb(); 273b111c8c0SMaxim Patlasov req = fuse_request_alloc(0); 27433649c91SMiklos Szeredi if (!req) 27533649c91SMiklos Szeredi req = get_reserved_req(fc, file); 27633649c91SMiklos Szeredi 27733649c91SMiklos Szeredi fuse_req_init_context(req); 278825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 279825d6d33SMiklos Szeredi __clear_bit(FR_BACKGROUND, &req->flags); 28033649c91SMiklos Szeredi return req; 28133649c91SMiklos Szeredi } 28233649c91SMiklos Szeredi 283334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) 284334f485dSMiklos Szeredi { 2857128ec2aSMiklos Szeredi if (atomic_dec_and_test(&req->count)) { 286825d6d33SMiklos Szeredi if (test_bit(FR_BACKGROUND, &req->flags)) { 287722d2beaSMaxim Patlasov /* 288722d2beaSMaxim Patlasov * We get here in the unlikely case that a background 289722d2beaSMaxim Patlasov * request was allocated but not sent 290722d2beaSMaxim Patlasov */ 291722d2beaSMaxim Patlasov spin_lock(&fc->lock); 292722d2beaSMaxim Patlasov if (!fc->blocked) 293722d2beaSMaxim Patlasov wake_up(&fc->blocked_waitq); 294722d2beaSMaxim Patlasov spin_unlock(&fc->lock); 295722d2beaSMaxim Patlasov } 296722d2beaSMaxim Patlasov 297825d6d33SMiklos Szeredi if (test_bit(FR_WAITING, &req->flags)) { 298825d6d33SMiklos Szeredi __clear_bit(FR_WAITING, &req->flags); 299ce1d5a49SMiklos Szeredi atomic_dec(&fc->num_waiting); 30073e0e738SMiklos Szeredi } 30133649c91SMiklos Szeredi 30233649c91SMiklos Szeredi if (req->stolen_file) 30333649c91SMiklos Szeredi put_reserved_req(fc, req); 30433649c91SMiklos Szeredi else 305ce1d5a49SMiklos Szeredi fuse_request_free(req); 3067128ec2aSMiklos Szeredi } 3077128ec2aSMiklos Szeredi } 30808cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_put_request); 3097128ec2aSMiklos Szeredi 310d12def1bSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args) 311d12def1bSMiklos Szeredi { 312d12def1bSMiklos Szeredi unsigned nbytes = 0; 313d12def1bSMiklos Szeredi unsigned i; 314d12def1bSMiklos Szeredi 315d12def1bSMiklos Szeredi for (i = 0; i < numargs; i++) 316d12def1bSMiklos Szeredi nbytes += args[i].size; 317d12def1bSMiklos Szeredi 318d12def1bSMiklos Szeredi return nbytes; 319d12def1bSMiklos Szeredi } 320d12def1bSMiklos Szeredi 321f88996a9SMiklos Szeredi static u64 fuse_get_unique(struct fuse_iqueue *fiq) 322d12def1bSMiklos Szeredi { 323f88996a9SMiklos Szeredi return ++fiq->reqctr; 324d12def1bSMiklos Szeredi } 325d12def1bSMiklos Szeredi 326f88996a9SMiklos Szeredi static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req) 327d12def1bSMiklos Szeredi { 328d12def1bSMiklos Szeredi req->in.h.len = sizeof(struct fuse_in_header) + 329d12def1bSMiklos Szeredi len_args(req->in.numargs, (struct fuse_arg *) req->in.args); 330f88996a9SMiklos Szeredi list_add_tail(&req->list, &fiq->pending); 3314ce60812SMiklos Szeredi wake_up_locked(&fiq->waitq); 332f88996a9SMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 333d12def1bSMiklos Szeredi } 334d12def1bSMiklos Szeredi 33507e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, 33607e77dcaSMiklos Szeredi u64 nodeid, u64 nlookup) 33707e77dcaSMiklos Szeredi { 338f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 339f88996a9SMiklos Szeredi 34002c048b9SMiklos Szeredi forget->forget_one.nodeid = nodeid; 34102c048b9SMiklos Szeredi forget->forget_one.nlookup = nlookup; 34207e77dcaSMiklos Szeredi 3434ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 344e16714d8SMiklos Szeredi if (fiq->connected) { 345f88996a9SMiklos Szeredi fiq->forget_list_tail->next = forget; 346f88996a9SMiklos Szeredi fiq->forget_list_tail = forget; 3474ce60812SMiklos Szeredi wake_up_locked(&fiq->waitq); 348f88996a9SMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 3495dfcc87fSMiklos Szeredi } else { 3505dfcc87fSMiklos Szeredi kfree(forget); 3515dfcc87fSMiklos Szeredi } 3524ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 35307e77dcaSMiklos Szeredi } 35407e77dcaSMiklos Szeredi 355d12def1bSMiklos Szeredi static void flush_bg_queue(struct fuse_conn *fc) 356d12def1bSMiklos Szeredi { 3577a6d3c8bSCsaba Henk while (fc->active_background < fc->max_background && 358d12def1bSMiklos Szeredi !list_empty(&fc->bg_queue)) { 359d12def1bSMiklos Szeredi struct fuse_req *req; 360f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 361d12def1bSMiklos Szeredi 362d12def1bSMiklos Szeredi req = list_entry(fc->bg_queue.next, struct fuse_req, list); 363d12def1bSMiklos Szeredi list_del(&req->list); 364d12def1bSMiklos Szeredi fc->active_background++; 3654ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 366f88996a9SMiklos Szeredi req->in.h.unique = fuse_get_unique(fiq); 367f88996a9SMiklos Szeredi queue_request(fiq, req); 3684ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 369d12def1bSMiklos Szeredi } 370d12def1bSMiklos Szeredi } 371d12def1bSMiklos Szeredi 3726dbbcb12SMiklos Szeredi /* 373334f485dSMiklos Szeredi * This function is called when a request is finished. Either a reply 374f9a2842eSMiklos Szeredi * has arrived or it was aborted (and not yet sent) or some error 375f43b155aSMiklos Szeredi * occurred during communication with userspace, or the device file 37651eb01e7SMiklos Szeredi * was closed. The requester thread is woken up (if still waiting), 37751eb01e7SMiklos Szeredi * the 'end' callback is called if given, else the reference to the 37851eb01e7SMiklos Szeredi * request is released 3797128ec2aSMiklos Szeredi * 380d7133114SMiklos Szeredi * Called with fc->lock, unlocks it 381334f485dSMiklos Szeredi */ 382334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req) 383b9ca67b2SMiklos Szeredi __releases(fc->lock) 384334f485dSMiklos Szeredi { 3854ce60812SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 386365ae710SMiklos Szeredi 387365ae710SMiklos Szeredi if (test_and_set_bit(FR_FINISHED, &req->flags)) { 388365ae710SMiklos Szeredi spin_unlock(&fc->lock); 389365ae710SMiklos Szeredi return; 390365ae710SMiklos Szeredi } 391365ae710SMiklos Szeredi 3924ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 3930d8e84b0SMiklos Szeredi list_del_init(&req->intr_entry); 3944ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 39533e14b4dSMiklos Szeredi WARN_ON(test_bit(FR_PENDING, &req->flags)); 39633e14b4dSMiklos Szeredi WARN_ON(test_bit(FR_SENT, &req->flags)); 397825d6d33SMiklos Szeredi if (test_bit(FR_BACKGROUND, &req->flags)) { 398825d6d33SMiklos Szeredi clear_bit(FR_BACKGROUND, &req->flags); 399722d2beaSMaxim Patlasov if (fc->num_background == fc->max_background) 40051eb01e7SMiklos Szeredi fc->blocked = 0; 401722d2beaSMaxim Patlasov 402722d2beaSMaxim Patlasov /* Wake up next waiter, if any */ 4033c18ef81SMiklos Szeredi if (!fc->blocked && waitqueue_active(&fc->blocked_waitq)) 404722d2beaSMaxim Patlasov wake_up(&fc->blocked_waitq); 405722d2beaSMaxim Patlasov 4067a6d3c8bSCsaba Henk if (fc->num_background == fc->congestion_threshold && 407a325f9b9STejun Heo fc->connected && fc->bdi_initialized) { 4088aa7e847SJens Axboe clear_bdi_congested(&fc->bdi, BLK_RW_SYNC); 4098aa7e847SJens Axboe clear_bdi_congested(&fc->bdi, BLK_RW_ASYNC); 410f92b99b9SMiklos Szeredi } 41151eb01e7SMiklos Szeredi fc->num_background--; 412d12def1bSMiklos Szeredi fc->active_background--; 413d12def1bSMiklos Szeredi flush_bg_queue(fc); 41451eb01e7SMiklos Szeredi } 415d7133114SMiklos Szeredi spin_unlock(&fc->lock); 41651eb01e7SMiklos Szeredi wake_up(&req->waitq); 417*1e6881c3SMiklos Szeredi if (req->end) 418*1e6881c3SMiklos Szeredi req->end(fc, req); 419f43b155aSMiklos Szeredi fuse_put_request(fc, req); 420334f485dSMiklos Szeredi } 421334f485dSMiklos Szeredi 422f88996a9SMiklos Szeredi static void queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req) 423a4d27e75SMiklos Szeredi { 4244ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 4258f7bb368SMiklos Szeredi if (list_empty(&req->intr_entry)) { 426f88996a9SMiklos Szeredi list_add_tail(&req->intr_entry, &fiq->interrupts); 4274ce60812SMiklos Szeredi wake_up_locked(&fiq->waitq); 4288f7bb368SMiklos Szeredi } 4294ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 430f88996a9SMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 431a4d27e75SMiklos Szeredi } 432a4d27e75SMiklos Szeredi 4337c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) 434334f485dSMiklos Szeredi { 4354ce60812SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 436c4775267SMiklos Szeredi int err; 437c4775267SMiklos Szeredi 438a4d27e75SMiklos Szeredi if (!fc->no_interrupt) { 439a4d27e75SMiklos Szeredi /* Any signal may interrupt this */ 440c4775267SMiklos Szeredi err = wait_event_interruptible(req->waitq, 44133e14b4dSMiklos Szeredi test_bit(FR_FINISHED, &req->flags)); 442c4775267SMiklos Szeredi if (!err) 443334f485dSMiklos Szeredi return; 444334f485dSMiklos Szeredi 445825d6d33SMiklos Szeredi set_bit(FR_INTERRUPTED, &req->flags); 4468f7bb368SMiklos Szeredi /* matches barrier in fuse_dev_do_read() */ 4478f7bb368SMiklos Szeredi smp_mb__after_atomic(); 44833e14b4dSMiklos Szeredi if (test_bit(FR_SENT, &req->flags)) 4494ce60812SMiklos Szeredi queue_interrupt(fiq, req); 450a4d27e75SMiklos Szeredi } 451a4d27e75SMiklos Szeredi 452825d6d33SMiklos Szeredi if (!test_bit(FR_FORCE, &req->flags)) { 453a4d27e75SMiklos Szeredi sigset_t oldset; 454a4d27e75SMiklos Szeredi 455a4d27e75SMiklos Szeredi /* Only fatal signals may interrupt this */ 456a4d27e75SMiklos Szeredi block_sigs(&oldset); 457c4775267SMiklos Szeredi err = wait_event_interruptible(req->waitq, 45833e14b4dSMiklos Szeredi test_bit(FR_FINISHED, &req->flags)); 459a4d27e75SMiklos Szeredi restore_sigs(&oldset); 460a4d27e75SMiklos Szeredi 461c4775267SMiklos Szeredi if (!err) 462a4d27e75SMiklos Szeredi return; 463a4d27e75SMiklos Szeredi 4644ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 465a131de0aSMiklos Szeredi /* Request is not yet in userspace, bail out */ 46633e14b4dSMiklos Szeredi if (test_bit(FR_PENDING, &req->flags)) { 467a131de0aSMiklos Szeredi list_del(&req->list); 4684ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 469a131de0aSMiklos Szeredi __fuse_put_request(req); 470334f485dSMiklos Szeredi req->out.h.error = -EINTR; 471a131de0aSMiklos Szeredi return; 472a131de0aSMiklos Szeredi } 4734ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 474a131de0aSMiklos Szeredi } 475a131de0aSMiklos Szeredi 476a131de0aSMiklos Szeredi /* 477a131de0aSMiklos Szeredi * Either request is already in userspace, or it was forced. 478a131de0aSMiklos Szeredi * Wait it out. 479a131de0aSMiklos Szeredi */ 48033e14b4dSMiklos Szeredi wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags)); 481334f485dSMiklos Szeredi } 482334f485dSMiklos Szeredi 4836a4e922cSEric Wong static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 484334f485dSMiklos Szeredi { 485e16714d8SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 486e16714d8SMiklos Szeredi 487825d6d33SMiklos Szeredi BUG_ON(test_bit(FR_BACKGROUND, &req->flags)); 4884ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 489e16714d8SMiklos Szeredi if (!fiq->connected) { 4904ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 491334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 492c4775267SMiklos Szeredi } else { 493f88996a9SMiklos Szeredi req->in.h.unique = fuse_get_unique(fiq); 494f88996a9SMiklos Szeredi queue_request(fiq, req); 495334f485dSMiklos Szeredi /* acquire extra reference, since request is still needed 496334f485dSMiklos Szeredi after request_end() */ 497334f485dSMiklos Szeredi __fuse_get_request(req); 4984ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 499334f485dSMiklos Szeredi 5007c352bdfSMiklos Szeredi request_wait_answer(fc, req); 501c4775267SMiklos Szeredi /* Pairs with smp_wmb() in request_end() */ 502c4775267SMiklos Szeredi smp_rmb(); 503334f485dSMiklos Szeredi } 504334f485dSMiklos Szeredi } 5056a4e922cSEric Wong 5066a4e922cSEric Wong void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 5076a4e922cSEric Wong { 508825d6d33SMiklos Szeredi __set_bit(FR_ISREPLY, &req->flags); 509825d6d33SMiklos Szeredi if (!test_bit(FR_WAITING, &req->flags)) { 510825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 5115437f241SMiklos Szeredi atomic_inc(&fc->num_waiting); 5125437f241SMiklos Szeredi } 5136a4e922cSEric Wong __fuse_request_send(fc, req); 5146a4e922cSEric Wong } 51508cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send); 516334f485dSMiklos Szeredi 51721f62174SMiklos Szeredi static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args) 51821f62174SMiklos Szeredi { 51921f62174SMiklos Szeredi if (fc->minor < 4 && args->in.h.opcode == FUSE_STATFS) 52021f62174SMiklos Szeredi args->out.args[0].size = FUSE_COMPAT_STATFS_SIZE; 52121f62174SMiklos Szeredi 52221f62174SMiklos Szeredi if (fc->minor < 9) { 52321f62174SMiklos Szeredi switch (args->in.h.opcode) { 52421f62174SMiklos Szeredi case FUSE_LOOKUP: 52521f62174SMiklos Szeredi case FUSE_CREATE: 52621f62174SMiklos Szeredi case FUSE_MKNOD: 52721f62174SMiklos Szeredi case FUSE_MKDIR: 52821f62174SMiklos Szeredi case FUSE_SYMLINK: 52921f62174SMiklos Szeredi case FUSE_LINK: 53021f62174SMiklos Szeredi args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; 53121f62174SMiklos Szeredi break; 53221f62174SMiklos Szeredi case FUSE_GETATTR: 53321f62174SMiklos Szeredi case FUSE_SETATTR: 53421f62174SMiklos Szeredi args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; 53521f62174SMiklos Szeredi break; 53621f62174SMiklos Szeredi } 53721f62174SMiklos Szeredi } 53821f62174SMiklos Szeredi if (fc->minor < 12) { 53921f62174SMiklos Szeredi switch (args->in.h.opcode) { 54021f62174SMiklos Szeredi case FUSE_CREATE: 54121f62174SMiklos Szeredi args->in.args[0].size = sizeof(struct fuse_open_in); 54221f62174SMiklos Szeredi break; 54321f62174SMiklos Szeredi case FUSE_MKNOD: 54421f62174SMiklos Szeredi args->in.args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE; 54521f62174SMiklos Szeredi break; 54621f62174SMiklos Szeredi } 54721f62174SMiklos Szeredi } 54821f62174SMiklos Szeredi } 54921f62174SMiklos Szeredi 5507078187aSMiklos Szeredi ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) 5517078187aSMiklos Szeredi { 5527078187aSMiklos Szeredi struct fuse_req *req; 5537078187aSMiklos Szeredi ssize_t ret; 5547078187aSMiklos Szeredi 5557078187aSMiklos Szeredi req = fuse_get_req(fc, 0); 5567078187aSMiklos Szeredi if (IS_ERR(req)) 5577078187aSMiklos Szeredi return PTR_ERR(req); 5587078187aSMiklos Szeredi 55921f62174SMiklos Szeredi /* Needs to be done after fuse_get_req() so that fc->minor is valid */ 56021f62174SMiklos Szeredi fuse_adjust_compat(fc, args); 56121f62174SMiklos Szeredi 5627078187aSMiklos Szeredi req->in.h.opcode = args->in.h.opcode; 5637078187aSMiklos Szeredi req->in.h.nodeid = args->in.h.nodeid; 5647078187aSMiklos Szeredi req->in.numargs = args->in.numargs; 5657078187aSMiklos Szeredi memcpy(req->in.args, args->in.args, 5667078187aSMiklos Szeredi args->in.numargs * sizeof(struct fuse_in_arg)); 5677078187aSMiklos Szeredi req->out.argvar = args->out.argvar; 5687078187aSMiklos Szeredi req->out.numargs = args->out.numargs; 5697078187aSMiklos Szeredi memcpy(req->out.args, args->out.args, 5707078187aSMiklos Szeredi args->out.numargs * sizeof(struct fuse_arg)); 5717078187aSMiklos Szeredi fuse_request_send(fc, req); 5727078187aSMiklos Szeredi ret = req->out.h.error; 5737078187aSMiklos Szeredi if (!ret && args->out.argvar) { 5747078187aSMiklos Szeredi BUG_ON(args->out.numargs != 1); 5757078187aSMiklos Szeredi ret = req->out.args[0].size; 5767078187aSMiklos Szeredi } 5777078187aSMiklos Szeredi fuse_put_request(fc, req); 5787078187aSMiklos Szeredi 5797078187aSMiklos Szeredi return ret; 5807078187aSMiklos Szeredi } 5817078187aSMiklos Szeredi 582f0139aa8SMiklos Szeredi /* 583f0139aa8SMiklos Szeredi * Called under fc->lock 584f0139aa8SMiklos Szeredi * 585f0139aa8SMiklos Szeredi * fc->connected must have been checked previously 586f0139aa8SMiklos Szeredi */ 587f0139aa8SMiklos Szeredi void fuse_request_send_background_locked(struct fuse_conn *fc, 588d12def1bSMiklos Szeredi struct fuse_req *req) 589334f485dSMiklos Szeredi { 590825d6d33SMiklos Szeredi BUG_ON(!test_bit(FR_BACKGROUND, &req->flags)); 591825d6d33SMiklos Szeredi if (!test_bit(FR_WAITING, &req->flags)) { 592825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 5935437f241SMiklos Szeredi atomic_inc(&fc->num_waiting); 5945437f241SMiklos Szeredi } 595825d6d33SMiklos Szeredi __set_bit(FR_ISREPLY, &req->flags); 59651eb01e7SMiklos Szeredi fc->num_background++; 5977a6d3c8bSCsaba Henk if (fc->num_background == fc->max_background) 59851eb01e7SMiklos Szeredi fc->blocked = 1; 5997a6d3c8bSCsaba Henk if (fc->num_background == fc->congestion_threshold && 600a325f9b9STejun Heo fc->bdi_initialized) { 6018aa7e847SJens Axboe set_bdi_congested(&fc->bdi, BLK_RW_SYNC); 6028aa7e847SJens Axboe set_bdi_congested(&fc->bdi, BLK_RW_ASYNC); 603f92b99b9SMiklos Szeredi } 604d12def1bSMiklos Szeredi list_add_tail(&req->list, &fc->bg_queue); 605d12def1bSMiklos Szeredi flush_bg_queue(fc); 606d12def1bSMiklos Szeredi } 60751eb01e7SMiklos Szeredi 608f0139aa8SMiklos Szeredi void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) 609d12def1bSMiklos Szeredi { 61042dc6211SMiklos Szeredi BUG_ON(!req->end); 611d12def1bSMiklos Szeredi spin_lock(&fc->lock); 612d12def1bSMiklos Szeredi if (fc->connected) { 613f0139aa8SMiklos Szeredi fuse_request_send_background_locked(fc, req); 614d7133114SMiklos Szeredi spin_unlock(&fc->lock); 615334f485dSMiklos Szeredi } else { 61642dc6211SMiklos Szeredi spin_unlock(&fc->lock); 617334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 61842dc6211SMiklos Szeredi req->end(fc, req); 61942dc6211SMiklos Szeredi fuse_put_request(fc, req); 620334f485dSMiklos Szeredi } 621334f485dSMiklos Szeredi } 62208cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send_background); 623334f485dSMiklos Szeredi 6242d45ba38SMiklos Szeredi static int fuse_request_send_notify_reply(struct fuse_conn *fc, 6252d45ba38SMiklos Szeredi struct fuse_req *req, u64 unique) 6262d45ba38SMiklos Szeredi { 6272d45ba38SMiklos Szeredi int err = -ENODEV; 628f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 6292d45ba38SMiklos Szeredi 630825d6d33SMiklos Szeredi __clear_bit(FR_ISREPLY, &req->flags); 6312d45ba38SMiklos Szeredi req->in.h.unique = unique; 6324ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 633e16714d8SMiklos Szeredi if (fiq->connected) { 634f88996a9SMiklos Szeredi queue_request(fiq, req); 6352d45ba38SMiklos Szeredi err = 0; 6362d45ba38SMiklos Szeredi } 6374ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 6382d45ba38SMiklos Szeredi 6392d45ba38SMiklos Szeredi return err; 6402d45ba38SMiklos Szeredi } 6412d45ba38SMiklos Szeredi 6420b05b183SAnand V. Avati void fuse_force_forget(struct file *file, u64 nodeid) 6430b05b183SAnand V. Avati { 6446131ffaaSAl Viro struct inode *inode = file_inode(file); 6450b05b183SAnand V. Avati struct fuse_conn *fc = get_fuse_conn(inode); 6460b05b183SAnand V. Avati struct fuse_req *req; 6470b05b183SAnand V. Avati struct fuse_forget_in inarg; 6480b05b183SAnand V. Avati 6490b05b183SAnand V. Avati memset(&inarg, 0, sizeof(inarg)); 6500b05b183SAnand V. Avati inarg.nlookup = 1; 651b111c8c0SMaxim Patlasov req = fuse_get_req_nofail_nopages(fc, file); 6520b05b183SAnand V. Avati req->in.h.opcode = FUSE_FORGET; 6530b05b183SAnand V. Avati req->in.h.nodeid = nodeid; 6540b05b183SAnand V. Avati req->in.numargs = 1; 6550b05b183SAnand V. Avati req->in.args[0].size = sizeof(inarg); 6560b05b183SAnand V. Avati req->in.args[0].value = &inarg; 657825d6d33SMiklos Szeredi __clear_bit(FR_ISREPLY, &req->flags); 6586a4e922cSEric Wong __fuse_request_send(fc, req); 6596a4e922cSEric Wong /* ignore errors */ 6606a4e922cSEric Wong fuse_put_request(fc, req); 6610b05b183SAnand V. Avati } 6620b05b183SAnand V. Avati 6633be5a52bSMiklos Szeredi /* 664334f485dSMiklos Szeredi * Lock the request. Up to the next unlock_request() there mustn't be 665334f485dSMiklos Szeredi * anything that could cause a page-fault. If the request was already 666f9a2842eSMiklos Szeredi * aborted bail out. 667334f485dSMiklos Szeredi */ 668dc00809aSMiklos Szeredi static int lock_request(struct fuse_req *req) 669334f485dSMiklos Szeredi { 670334f485dSMiklos Szeredi int err = 0; 671334f485dSMiklos Szeredi if (req) { 672dc00809aSMiklos Szeredi spin_lock(&req->waitq.lock); 673825d6d33SMiklos Szeredi if (test_bit(FR_ABORTED, &req->flags)) 674334f485dSMiklos Szeredi err = -ENOENT; 675334f485dSMiklos Szeredi else 676825d6d33SMiklos Szeredi set_bit(FR_LOCKED, &req->flags); 677dc00809aSMiklos Szeredi spin_unlock(&req->waitq.lock); 678334f485dSMiklos Szeredi } 679334f485dSMiklos Szeredi return err; 680334f485dSMiklos Szeredi } 681334f485dSMiklos Szeredi 682334f485dSMiklos Szeredi /* 6830d8e84b0SMiklos Szeredi * Unlock request. If it was aborted while locked, caller is responsible 6840d8e84b0SMiklos Szeredi * for unlocking and ending the request. 685334f485dSMiklos Szeredi */ 686dc00809aSMiklos Szeredi static int unlock_request(struct fuse_req *req) 687334f485dSMiklos Szeredi { 6880d8e84b0SMiklos Szeredi int err = 0; 689334f485dSMiklos Szeredi if (req) { 690dc00809aSMiklos Szeredi spin_lock(&req->waitq.lock); 691825d6d33SMiklos Szeredi if (test_bit(FR_ABORTED, &req->flags)) 6920d8e84b0SMiklos Szeredi err = -ENOENT; 6930d8e84b0SMiklos Szeredi else 694825d6d33SMiklos Szeredi clear_bit(FR_LOCKED, &req->flags); 695dc00809aSMiklos Szeredi spin_unlock(&req->waitq.lock); 696334f485dSMiklos Szeredi } 6970d8e84b0SMiklos Szeredi return err; 698334f485dSMiklos Szeredi } 699334f485dSMiklos Szeredi 700334f485dSMiklos Szeredi struct fuse_copy_state { 701334f485dSMiklos Szeredi int write; 702334f485dSMiklos Szeredi struct fuse_req *req; 7036c09e94aSAl Viro struct iov_iter *iter; 704dd3bb14fSMiklos Szeredi struct pipe_buffer *pipebufs; 705dd3bb14fSMiklos Szeredi struct pipe_buffer *currbuf; 706dd3bb14fSMiklos Szeredi struct pipe_inode_info *pipe; 707334f485dSMiklos Szeredi unsigned long nr_segs; 708334f485dSMiklos Szeredi struct page *pg; 709334f485dSMiklos Szeredi unsigned len; 710c55a01d3SMiklos Szeredi unsigned offset; 711ce534fb0SMiklos Szeredi unsigned move_pages:1; 712334f485dSMiklos Szeredi }; 713334f485dSMiklos Szeredi 714dc00809aSMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, int write, 7156c09e94aSAl Viro struct iov_iter *iter) 716334f485dSMiklos Szeredi { 717334f485dSMiklos Szeredi memset(cs, 0, sizeof(*cs)); 718334f485dSMiklos Szeredi cs->write = write; 7196c09e94aSAl Viro cs->iter = iter; 720334f485dSMiklos Szeredi } 721334f485dSMiklos Szeredi 722334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */ 7238bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs) 724334f485dSMiklos Szeredi { 725dd3bb14fSMiklos Szeredi if (cs->currbuf) { 726dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->currbuf; 727dd3bb14fSMiklos Szeredi 728c55a01d3SMiklos Szeredi if (cs->write) 729c3021629SMiklos Szeredi buf->len = PAGE_SIZE - cs->len; 730dd3bb14fSMiklos Szeredi cs->currbuf = NULL; 731c55a01d3SMiklos Szeredi } else if (cs->pg) { 732334f485dSMiklos Szeredi if (cs->write) { 733334f485dSMiklos Szeredi flush_dcache_page(cs->pg); 734334f485dSMiklos Szeredi set_page_dirty_lock(cs->pg); 735334f485dSMiklos Szeredi } 736334f485dSMiklos Szeredi put_page(cs->pg); 737334f485dSMiklos Szeredi } 738c55a01d3SMiklos Szeredi cs->pg = NULL; 739334f485dSMiklos Szeredi } 740334f485dSMiklos Szeredi 741334f485dSMiklos Szeredi /* 742334f485dSMiklos Szeredi * Get another pagefull of userspace buffer, and map it to kernel 743334f485dSMiklos Szeredi * address space, and lock request 744334f485dSMiklos Szeredi */ 745334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs) 746334f485dSMiklos Szeredi { 747c55a01d3SMiklos Szeredi struct page *page; 748334f485dSMiklos Szeredi int err; 749334f485dSMiklos Szeredi 750dc00809aSMiklos Szeredi err = unlock_request(cs->req); 7510d8e84b0SMiklos Szeredi if (err) 7520d8e84b0SMiklos Szeredi return err; 7530d8e84b0SMiklos Szeredi 754334f485dSMiklos Szeredi fuse_copy_finish(cs); 755dd3bb14fSMiklos Szeredi if (cs->pipebufs) { 756dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 757dd3bb14fSMiklos Szeredi 758c3021629SMiklos Szeredi if (!cs->write) { 759dd3bb14fSMiklos Szeredi err = buf->ops->confirm(cs->pipe, buf); 760dd3bb14fSMiklos Szeredi if (err) 761dd3bb14fSMiklos Szeredi return err; 762dd3bb14fSMiklos Szeredi 763dd3bb14fSMiklos Szeredi BUG_ON(!cs->nr_segs); 764dd3bb14fSMiklos Szeredi cs->currbuf = buf; 765c55a01d3SMiklos Szeredi cs->pg = buf->page; 766c55a01d3SMiklos Szeredi cs->offset = buf->offset; 767dd3bb14fSMiklos Szeredi cs->len = buf->len; 768dd3bb14fSMiklos Szeredi cs->pipebufs++; 769dd3bb14fSMiklos Szeredi cs->nr_segs--; 770dd3bb14fSMiklos Szeredi } else { 771c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 772c3021629SMiklos Szeredi return -EIO; 773c3021629SMiklos Szeredi 774c3021629SMiklos Szeredi page = alloc_page(GFP_HIGHUSER); 775c3021629SMiklos Szeredi if (!page) 776c3021629SMiklos Szeredi return -ENOMEM; 777c3021629SMiklos Szeredi 778c3021629SMiklos Szeredi buf->page = page; 779c3021629SMiklos Szeredi buf->offset = 0; 780c3021629SMiklos Szeredi buf->len = 0; 781c3021629SMiklos Szeredi 782c3021629SMiklos Szeredi cs->currbuf = buf; 783c55a01d3SMiklos Szeredi cs->pg = page; 784c55a01d3SMiklos Szeredi cs->offset = 0; 785c3021629SMiklos Szeredi cs->len = PAGE_SIZE; 786c3021629SMiklos Szeredi cs->pipebufs++; 787c3021629SMiklos Szeredi cs->nr_segs++; 788c3021629SMiklos Szeredi } 789c3021629SMiklos Szeredi } else { 7906c09e94aSAl Viro size_t off; 7916c09e94aSAl Viro err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off); 792334f485dSMiklos Szeredi if (err < 0) 793334f485dSMiklos Szeredi return err; 7946c09e94aSAl Viro BUG_ON(!err); 7956c09e94aSAl Viro cs->len = err; 7966c09e94aSAl Viro cs->offset = off; 797c55a01d3SMiklos Szeredi cs->pg = page; 7986c09e94aSAl Viro cs->offset = off; 7996c09e94aSAl Viro iov_iter_advance(cs->iter, err); 800dd3bb14fSMiklos Szeredi } 801334f485dSMiklos Szeredi 802dc00809aSMiklos Szeredi return lock_request(cs->req); 803334f485dSMiklos Szeredi } 804334f485dSMiklos Szeredi 805334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */ 8068bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size) 807334f485dSMiklos Szeredi { 808334f485dSMiklos Szeredi unsigned ncpy = min(*size, cs->len); 809334f485dSMiklos Szeredi if (val) { 810c55a01d3SMiklos Szeredi void *pgaddr = kmap_atomic(cs->pg); 811c55a01d3SMiklos Szeredi void *buf = pgaddr + cs->offset; 812c55a01d3SMiklos Szeredi 813334f485dSMiklos Szeredi if (cs->write) 814c55a01d3SMiklos Szeredi memcpy(buf, *val, ncpy); 815334f485dSMiklos Szeredi else 816c55a01d3SMiklos Szeredi memcpy(*val, buf, ncpy); 817c55a01d3SMiklos Szeredi 818c55a01d3SMiklos Szeredi kunmap_atomic(pgaddr); 819334f485dSMiklos Szeredi *val += ncpy; 820334f485dSMiklos Szeredi } 821334f485dSMiklos Szeredi *size -= ncpy; 822334f485dSMiklos Szeredi cs->len -= ncpy; 823c55a01d3SMiklos Szeredi cs->offset += ncpy; 824334f485dSMiklos Szeredi return ncpy; 825334f485dSMiklos Szeredi } 826334f485dSMiklos Szeredi 827ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page) 828ce534fb0SMiklos Szeredi { 829ce534fb0SMiklos Szeredi if (page_mapcount(page) || 830ce534fb0SMiklos Szeredi page->mapping != NULL || 831ce534fb0SMiklos Szeredi page_count(page) != 1 || 832ce534fb0SMiklos Szeredi (page->flags & PAGE_FLAGS_CHECK_AT_PREP & 833ce534fb0SMiklos Szeredi ~(1 << PG_locked | 834ce534fb0SMiklos Szeredi 1 << PG_referenced | 835ce534fb0SMiklos Szeredi 1 << PG_uptodate | 836ce534fb0SMiklos Szeredi 1 << PG_lru | 837ce534fb0SMiklos Szeredi 1 << PG_active | 838ce534fb0SMiklos Szeredi 1 << PG_reclaim))) { 839ce534fb0SMiklos Szeredi printk(KERN_WARNING "fuse: trying to steal weird page\n"); 840ce534fb0SMiklos Szeredi printk(KERN_WARNING " page=%p index=%li flags=%08lx, count=%i, mapcount=%i, mapping=%p\n", page, page->index, page->flags, page_count(page), page_mapcount(page), page->mapping); 841ce534fb0SMiklos Szeredi return 1; 842ce534fb0SMiklos Szeredi } 843ce534fb0SMiklos Szeredi return 0; 844ce534fb0SMiklos Szeredi } 845ce534fb0SMiklos Szeredi 846ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) 847ce534fb0SMiklos Szeredi { 848ce534fb0SMiklos Szeredi int err; 849ce534fb0SMiklos Szeredi struct page *oldpage = *pagep; 850ce534fb0SMiklos Szeredi struct page *newpage; 851ce534fb0SMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 852ce534fb0SMiklos Szeredi 853dc00809aSMiklos Szeredi err = unlock_request(cs->req); 8540d8e84b0SMiklos Szeredi if (err) 8550d8e84b0SMiklos Szeredi return err; 8560d8e84b0SMiklos Szeredi 857ce534fb0SMiklos Szeredi fuse_copy_finish(cs); 858ce534fb0SMiklos Szeredi 859ce534fb0SMiklos Szeredi err = buf->ops->confirm(cs->pipe, buf); 860ce534fb0SMiklos Szeredi if (err) 861ce534fb0SMiklos Szeredi return err; 862ce534fb0SMiklos Szeredi 863ce534fb0SMiklos Szeredi BUG_ON(!cs->nr_segs); 864ce534fb0SMiklos Szeredi cs->currbuf = buf; 865ce534fb0SMiklos Szeredi cs->len = buf->len; 866ce534fb0SMiklos Szeredi cs->pipebufs++; 867ce534fb0SMiklos Szeredi cs->nr_segs--; 868ce534fb0SMiklos Szeredi 869ce534fb0SMiklos Szeredi if (cs->len != PAGE_SIZE) 870ce534fb0SMiklos Szeredi goto out_fallback; 871ce534fb0SMiklos Szeredi 872ce534fb0SMiklos Szeredi if (buf->ops->steal(cs->pipe, buf) != 0) 873ce534fb0SMiklos Szeredi goto out_fallback; 874ce534fb0SMiklos Szeredi 875ce534fb0SMiklos Szeredi newpage = buf->page; 876ce534fb0SMiklos Szeredi 877aa991b3bSMiklos Szeredi if (!PageUptodate(newpage)) 878aa991b3bSMiklos Szeredi SetPageUptodate(newpage); 879ce534fb0SMiklos Szeredi 880ce534fb0SMiklos Szeredi ClearPageMappedToDisk(newpage); 881ce534fb0SMiklos Szeredi 882ce534fb0SMiklos Szeredi if (fuse_check_page(newpage) != 0) 883ce534fb0SMiklos Szeredi goto out_fallback_unlock; 884ce534fb0SMiklos Szeredi 885ce534fb0SMiklos Szeredi /* 886ce534fb0SMiklos Szeredi * This is a new and locked page, it shouldn't be mapped or 887ce534fb0SMiklos Szeredi * have any special flags on it 888ce534fb0SMiklos Szeredi */ 889ce534fb0SMiklos Szeredi if (WARN_ON(page_mapped(oldpage))) 890ce534fb0SMiklos Szeredi goto out_fallback_unlock; 891ce534fb0SMiklos Szeredi if (WARN_ON(page_has_private(oldpage))) 892ce534fb0SMiklos Szeredi goto out_fallback_unlock; 893ce534fb0SMiklos Szeredi if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage))) 894ce534fb0SMiklos Szeredi goto out_fallback_unlock; 895ce534fb0SMiklos Szeredi if (WARN_ON(PageMlocked(oldpage))) 896ce534fb0SMiklos Szeredi goto out_fallback_unlock; 897ce534fb0SMiklos Szeredi 898ef6a3c63SMiklos Szeredi err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); 899ce534fb0SMiklos Szeredi if (err) { 900ef6a3c63SMiklos Szeredi unlock_page(newpage); 901ef6a3c63SMiklos Szeredi return err; 902ce534fb0SMiklos Szeredi } 903ef6a3c63SMiklos Szeredi 904ce534fb0SMiklos Szeredi page_cache_get(newpage); 905ce534fb0SMiklos Szeredi 906ce534fb0SMiklos Szeredi if (!(buf->flags & PIPE_BUF_FLAG_LRU)) 907ce534fb0SMiklos Szeredi lru_cache_add_file(newpage); 908ce534fb0SMiklos Szeredi 909ce534fb0SMiklos Szeredi err = 0; 910dc00809aSMiklos Szeredi spin_lock(&cs->req->waitq.lock); 911825d6d33SMiklos Szeredi if (test_bit(FR_ABORTED, &cs->req->flags)) 912ce534fb0SMiklos Szeredi err = -ENOENT; 913ce534fb0SMiklos Szeredi else 914ce534fb0SMiklos Szeredi *pagep = newpage; 915dc00809aSMiklos Szeredi spin_unlock(&cs->req->waitq.lock); 916ce534fb0SMiklos Szeredi 917ce534fb0SMiklos Szeredi if (err) { 918ce534fb0SMiklos Szeredi unlock_page(newpage); 919ce534fb0SMiklos Szeredi page_cache_release(newpage); 920ce534fb0SMiklos Szeredi return err; 921ce534fb0SMiklos Szeredi } 922ce534fb0SMiklos Szeredi 923ce534fb0SMiklos Szeredi unlock_page(oldpage); 924ce534fb0SMiklos Szeredi page_cache_release(oldpage); 925ce534fb0SMiklos Szeredi cs->len = 0; 926ce534fb0SMiklos Szeredi 927ce534fb0SMiklos Szeredi return 0; 928ce534fb0SMiklos Szeredi 929ce534fb0SMiklos Szeredi out_fallback_unlock: 930ce534fb0SMiklos Szeredi unlock_page(newpage); 931ce534fb0SMiklos Szeredi out_fallback: 932c55a01d3SMiklos Szeredi cs->pg = buf->page; 933c55a01d3SMiklos Szeredi cs->offset = buf->offset; 934ce534fb0SMiklos Szeredi 935dc00809aSMiklos Szeredi err = lock_request(cs->req); 936ce534fb0SMiklos Szeredi if (err) 937ce534fb0SMiklos Szeredi return err; 938ce534fb0SMiklos Szeredi 939ce534fb0SMiklos Szeredi return 1; 940ce534fb0SMiklos Szeredi } 941ce534fb0SMiklos Szeredi 942c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page, 943c3021629SMiklos Szeredi unsigned offset, unsigned count) 944c3021629SMiklos Szeredi { 945c3021629SMiklos Szeredi struct pipe_buffer *buf; 9460d8e84b0SMiklos Szeredi int err; 947c3021629SMiklos Szeredi 948c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 949c3021629SMiklos Szeredi return -EIO; 950c3021629SMiklos Szeredi 951dc00809aSMiklos Szeredi err = unlock_request(cs->req); 9520d8e84b0SMiklos Szeredi if (err) 9530d8e84b0SMiklos Szeredi return err; 9540d8e84b0SMiklos Szeredi 955c3021629SMiklos Szeredi fuse_copy_finish(cs); 956c3021629SMiklos Szeredi 957c3021629SMiklos Szeredi buf = cs->pipebufs; 958c3021629SMiklos Szeredi page_cache_get(page); 959c3021629SMiklos Szeredi buf->page = page; 960c3021629SMiklos Szeredi buf->offset = offset; 961c3021629SMiklos Szeredi buf->len = count; 962c3021629SMiklos Szeredi 963c3021629SMiklos Szeredi cs->pipebufs++; 964c3021629SMiklos Szeredi cs->nr_segs++; 965c3021629SMiklos Szeredi cs->len = 0; 966c3021629SMiklos Szeredi 967c3021629SMiklos Szeredi return 0; 968c3021629SMiklos Szeredi } 969c3021629SMiklos Szeredi 970334f485dSMiklos Szeredi /* 971334f485dSMiklos Szeredi * Copy a page in the request to/from the userspace buffer. Must be 972334f485dSMiklos Szeredi * done atomically 973334f485dSMiklos Szeredi */ 974ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep, 975334f485dSMiklos Szeredi unsigned offset, unsigned count, int zeroing) 976334f485dSMiklos Szeredi { 977ce534fb0SMiklos Szeredi int err; 978ce534fb0SMiklos Szeredi struct page *page = *pagep; 979ce534fb0SMiklos Szeredi 980b6777c40SMiklos Szeredi if (page && zeroing && count < PAGE_SIZE) 981b6777c40SMiklos Szeredi clear_highpage(page); 982b6777c40SMiklos Szeredi 983334f485dSMiklos Szeredi while (count) { 984c3021629SMiklos Szeredi if (cs->write && cs->pipebufs && page) { 985c3021629SMiklos Szeredi return fuse_ref_page(cs, page, offset, count); 986c3021629SMiklos Szeredi } else if (!cs->len) { 987ce534fb0SMiklos Szeredi if (cs->move_pages && page && 988ce534fb0SMiklos Szeredi offset == 0 && count == PAGE_SIZE) { 989ce534fb0SMiklos Szeredi err = fuse_try_move_page(cs, pagep); 990ce534fb0SMiklos Szeredi if (err <= 0) 991ce534fb0SMiklos Szeredi return err; 992ce534fb0SMiklos Szeredi } else { 993ce534fb0SMiklos Szeredi err = fuse_copy_fill(cs); 9941729a16cSMiklos Szeredi if (err) 995334f485dSMiklos Szeredi return err; 9961729a16cSMiklos Szeredi } 997ce534fb0SMiklos Szeredi } 998334f485dSMiklos Szeredi if (page) { 9992408f6efSCong Wang void *mapaddr = kmap_atomic(page); 1000334f485dSMiklos Szeredi void *buf = mapaddr + offset; 1001334f485dSMiklos Szeredi offset += fuse_copy_do(cs, &buf, &count); 10022408f6efSCong Wang kunmap_atomic(mapaddr); 1003334f485dSMiklos Szeredi } else 1004334f485dSMiklos Szeredi offset += fuse_copy_do(cs, NULL, &count); 1005334f485dSMiklos Szeredi } 1006334f485dSMiklos Szeredi if (page && !cs->write) 1007334f485dSMiklos Szeredi flush_dcache_page(page); 1008334f485dSMiklos Szeredi return 0; 1009334f485dSMiklos Szeredi } 1010334f485dSMiklos Szeredi 1011334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */ 1012334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes, 1013334f485dSMiklos Szeredi int zeroing) 1014334f485dSMiklos Szeredi { 1015334f485dSMiklos Szeredi unsigned i; 1016334f485dSMiklos Szeredi struct fuse_req *req = cs->req; 1017334f485dSMiklos Szeredi 1018334f485dSMiklos Szeredi for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) { 1019ce534fb0SMiklos Szeredi int err; 102085f40aecSMaxim Patlasov unsigned offset = req->page_descs[i].offset; 102185f40aecSMaxim Patlasov unsigned count = min(nbytes, req->page_descs[i].length); 1022ce534fb0SMiklos Szeredi 1023ce534fb0SMiklos Szeredi err = fuse_copy_page(cs, &req->pages[i], offset, count, 1024ce534fb0SMiklos Szeredi zeroing); 1025334f485dSMiklos Szeredi if (err) 1026334f485dSMiklos Szeredi return err; 1027334f485dSMiklos Szeredi 1028334f485dSMiklos Szeredi nbytes -= count; 1029334f485dSMiklos Szeredi } 1030334f485dSMiklos Szeredi return 0; 1031334f485dSMiklos Szeredi } 1032334f485dSMiklos Szeredi 1033334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */ 1034334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) 1035334f485dSMiklos Szeredi { 1036334f485dSMiklos Szeredi while (size) { 10371729a16cSMiklos Szeredi if (!cs->len) { 10381729a16cSMiklos Szeredi int err = fuse_copy_fill(cs); 10391729a16cSMiklos Szeredi if (err) 1040334f485dSMiklos Szeredi return err; 10411729a16cSMiklos Szeredi } 1042334f485dSMiklos Szeredi fuse_copy_do(cs, &val, &size); 1043334f485dSMiklos Szeredi } 1044334f485dSMiklos Szeredi return 0; 1045334f485dSMiklos Szeredi } 1046334f485dSMiklos Szeredi 1047334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */ 1048334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs, 1049334f485dSMiklos Szeredi unsigned argpages, struct fuse_arg *args, 1050334f485dSMiklos Szeredi int zeroing) 1051334f485dSMiklos Szeredi { 1052334f485dSMiklos Szeredi int err = 0; 1053334f485dSMiklos Szeredi unsigned i; 1054334f485dSMiklos Szeredi 1055334f485dSMiklos Szeredi for (i = 0; !err && i < numargs; i++) { 1056334f485dSMiklos Szeredi struct fuse_arg *arg = &args[i]; 1057334f485dSMiklos Szeredi if (i == numargs - 1 && argpages) 1058334f485dSMiklos Szeredi err = fuse_copy_pages(cs, arg->size, zeroing); 1059334f485dSMiklos Szeredi else 1060334f485dSMiklos Szeredi err = fuse_copy_one(cs, arg->value, arg->size); 1061334f485dSMiklos Szeredi } 1062334f485dSMiklos Szeredi return err; 1063334f485dSMiklos Szeredi } 1064334f485dSMiklos Szeredi 1065f88996a9SMiklos Szeredi static int forget_pending(struct fuse_iqueue *fiq) 106607e77dcaSMiklos Szeredi { 1067f88996a9SMiklos Szeredi return fiq->forget_list_head.next != NULL; 106807e77dcaSMiklos Szeredi } 106907e77dcaSMiklos Szeredi 1070f88996a9SMiklos Szeredi static int request_pending(struct fuse_iqueue *fiq) 1071a4d27e75SMiklos Szeredi { 1072f88996a9SMiklos Szeredi return !list_empty(&fiq->pending) || !list_empty(&fiq->interrupts) || 1073f88996a9SMiklos Szeredi forget_pending(fiq); 1074a4d27e75SMiklos Szeredi } 1075a4d27e75SMiklos Szeredi 1076334f485dSMiklos Szeredi /* 1077a4d27e75SMiklos Szeredi * Transfer an interrupt request to userspace 1078a4d27e75SMiklos Szeredi * 1079a4d27e75SMiklos Szeredi * Unlike other requests this is assembled on demand, without a need 1080a4d27e75SMiklos Szeredi * to allocate a separate fuse_req structure. 1081a4d27e75SMiklos Szeredi * 1082fd22d62eSMiklos Szeredi * Called with fiq->waitq.lock held, releases it 1083a4d27e75SMiklos Szeredi */ 1084fd22d62eSMiklos Szeredi static int fuse_read_interrupt(struct fuse_iqueue *fiq, 1085fd22d62eSMiklos Szeredi struct fuse_copy_state *cs, 1086c3021629SMiklos Szeredi size_t nbytes, struct fuse_req *req) 1087fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 1088a4d27e75SMiklos Szeredi { 1089a4d27e75SMiklos Szeredi struct fuse_in_header ih; 1090a4d27e75SMiklos Szeredi struct fuse_interrupt_in arg; 1091a4d27e75SMiklos Szeredi unsigned reqsize = sizeof(ih) + sizeof(arg); 1092a4d27e75SMiklos Szeredi int err; 1093a4d27e75SMiklos Szeredi 1094a4d27e75SMiklos Szeredi list_del_init(&req->intr_entry); 10954ce60812SMiklos Szeredi req->intr_unique = fuse_get_unique(fiq); 1096a4d27e75SMiklos Szeredi memset(&ih, 0, sizeof(ih)); 1097a4d27e75SMiklos Szeredi memset(&arg, 0, sizeof(arg)); 1098a4d27e75SMiklos Szeredi ih.len = reqsize; 1099a4d27e75SMiklos Szeredi ih.opcode = FUSE_INTERRUPT; 1100a4d27e75SMiklos Szeredi ih.unique = req->intr_unique; 1101a4d27e75SMiklos Szeredi arg.unique = req->in.h.unique; 1102a4d27e75SMiklos Szeredi 11034ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 1104c3021629SMiklos Szeredi if (nbytes < reqsize) 1105a4d27e75SMiklos Szeredi return -EINVAL; 1106a4d27e75SMiklos Szeredi 1107c3021629SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 1108a4d27e75SMiklos Szeredi if (!err) 1109c3021629SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 1110c3021629SMiklos Szeredi fuse_copy_finish(cs); 1111a4d27e75SMiklos Szeredi 1112a4d27e75SMiklos Szeredi return err ? err : reqsize; 1113a4d27e75SMiklos Szeredi } 1114a4d27e75SMiklos Szeredi 1115f88996a9SMiklos Szeredi static struct fuse_forget_link *dequeue_forget(struct fuse_iqueue *fiq, 111602c048b9SMiklos Szeredi unsigned max, 111702c048b9SMiklos Szeredi unsigned *countp) 111807e77dcaSMiklos Szeredi { 1119f88996a9SMiklos Szeredi struct fuse_forget_link *head = fiq->forget_list_head.next; 112002c048b9SMiklos Szeredi struct fuse_forget_link **newhead = &head; 112102c048b9SMiklos Szeredi unsigned count; 112207e77dcaSMiklos Szeredi 112302c048b9SMiklos Szeredi for (count = 0; *newhead != NULL && count < max; count++) 112402c048b9SMiklos Szeredi newhead = &(*newhead)->next; 112502c048b9SMiklos Szeredi 1126f88996a9SMiklos Szeredi fiq->forget_list_head.next = *newhead; 112702c048b9SMiklos Szeredi *newhead = NULL; 1128f88996a9SMiklos Szeredi if (fiq->forget_list_head.next == NULL) 1129f88996a9SMiklos Szeredi fiq->forget_list_tail = &fiq->forget_list_head; 113007e77dcaSMiklos Szeredi 113102c048b9SMiklos Szeredi if (countp != NULL) 113202c048b9SMiklos Szeredi *countp = count; 113302c048b9SMiklos Szeredi 113402c048b9SMiklos Szeredi return head; 113507e77dcaSMiklos Szeredi } 113607e77dcaSMiklos Szeredi 1137fd22d62eSMiklos Szeredi static int fuse_read_single_forget(struct fuse_iqueue *fiq, 113807e77dcaSMiklos Szeredi struct fuse_copy_state *cs, 113907e77dcaSMiklos Szeredi size_t nbytes) 1140fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 114107e77dcaSMiklos Szeredi { 114207e77dcaSMiklos Szeredi int err; 1143f88996a9SMiklos Szeredi struct fuse_forget_link *forget = dequeue_forget(fiq, 1, NULL); 114407e77dcaSMiklos Szeredi struct fuse_forget_in arg = { 114502c048b9SMiklos Szeredi .nlookup = forget->forget_one.nlookup, 114607e77dcaSMiklos Szeredi }; 114707e77dcaSMiklos Szeredi struct fuse_in_header ih = { 114807e77dcaSMiklos Szeredi .opcode = FUSE_FORGET, 114902c048b9SMiklos Szeredi .nodeid = forget->forget_one.nodeid, 1150f88996a9SMiklos Szeredi .unique = fuse_get_unique(fiq), 115107e77dcaSMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 115207e77dcaSMiklos Szeredi }; 115307e77dcaSMiklos Szeredi 11544ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 115507e77dcaSMiklos Szeredi kfree(forget); 115607e77dcaSMiklos Szeredi if (nbytes < ih.len) 115707e77dcaSMiklos Szeredi return -EINVAL; 115807e77dcaSMiklos Szeredi 115907e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 116007e77dcaSMiklos Szeredi if (!err) 116107e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 116207e77dcaSMiklos Szeredi fuse_copy_finish(cs); 116307e77dcaSMiklos Szeredi 116407e77dcaSMiklos Szeredi if (err) 116507e77dcaSMiklos Szeredi return err; 116607e77dcaSMiklos Szeredi 116707e77dcaSMiklos Szeredi return ih.len; 116807e77dcaSMiklos Szeredi } 116907e77dcaSMiklos Szeredi 1170fd22d62eSMiklos Szeredi static int fuse_read_batch_forget(struct fuse_iqueue *fiq, 117102c048b9SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1172fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 117302c048b9SMiklos Szeredi { 117402c048b9SMiklos Szeredi int err; 117502c048b9SMiklos Szeredi unsigned max_forgets; 117602c048b9SMiklos Szeredi unsigned count; 117702c048b9SMiklos Szeredi struct fuse_forget_link *head; 117802c048b9SMiklos Szeredi struct fuse_batch_forget_in arg = { .count = 0 }; 117902c048b9SMiklos Szeredi struct fuse_in_header ih = { 118002c048b9SMiklos Szeredi .opcode = FUSE_BATCH_FORGET, 1181f88996a9SMiklos Szeredi .unique = fuse_get_unique(fiq), 118202c048b9SMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 118302c048b9SMiklos Szeredi }; 118402c048b9SMiklos Szeredi 118502c048b9SMiklos Szeredi if (nbytes < ih.len) { 11864ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 118702c048b9SMiklos Szeredi return -EINVAL; 118802c048b9SMiklos Szeredi } 118902c048b9SMiklos Szeredi 119002c048b9SMiklos Szeredi max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one); 1191f88996a9SMiklos Szeredi head = dequeue_forget(fiq, max_forgets, &count); 11924ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 119302c048b9SMiklos Szeredi 119402c048b9SMiklos Szeredi arg.count = count; 119502c048b9SMiklos Szeredi ih.len += count * sizeof(struct fuse_forget_one); 119602c048b9SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 119702c048b9SMiklos Szeredi if (!err) 119802c048b9SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 119902c048b9SMiklos Szeredi 120002c048b9SMiklos Szeredi while (head) { 120102c048b9SMiklos Szeredi struct fuse_forget_link *forget = head; 120202c048b9SMiklos Szeredi 120302c048b9SMiklos Szeredi if (!err) { 120402c048b9SMiklos Szeredi err = fuse_copy_one(cs, &forget->forget_one, 120502c048b9SMiklos Szeredi sizeof(forget->forget_one)); 120602c048b9SMiklos Szeredi } 120702c048b9SMiklos Szeredi head = forget->next; 120802c048b9SMiklos Szeredi kfree(forget); 120902c048b9SMiklos Szeredi } 121002c048b9SMiklos Szeredi 121102c048b9SMiklos Szeredi fuse_copy_finish(cs); 121202c048b9SMiklos Szeredi 121302c048b9SMiklos Szeredi if (err) 121402c048b9SMiklos Szeredi return err; 121502c048b9SMiklos Szeredi 121602c048b9SMiklos Szeredi return ih.len; 121702c048b9SMiklos Szeredi } 121802c048b9SMiklos Szeredi 1219fd22d62eSMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq, 1220fd22d62eSMiklos Szeredi struct fuse_copy_state *cs, 122102c048b9SMiklos Szeredi size_t nbytes) 1222fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 122302c048b9SMiklos Szeredi { 1224f88996a9SMiklos Szeredi if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL) 1225fd22d62eSMiklos Szeredi return fuse_read_single_forget(fiq, cs, nbytes); 122602c048b9SMiklos Szeredi else 1227fd22d62eSMiklos Szeredi return fuse_read_batch_forget(fiq, cs, nbytes); 122802c048b9SMiklos Szeredi } 122902c048b9SMiklos Szeredi 1230a4d27e75SMiklos Szeredi /* 1231334f485dSMiklos Szeredi * Read a single request into the userspace filesystem's buffer. This 1232334f485dSMiklos Szeredi * function waits until a request is available, then removes it from 1233334f485dSMiklos Szeredi * the pending list and copies request data to userspace buffer. If 1234f9a2842eSMiklos Szeredi * no reply is needed (FORGET) or request has been aborted or there 1235f9a2842eSMiklos Szeredi * was an error during the copying then it's finished by calling 1236334f485dSMiklos Szeredi * request_end(). Otherwise add it to the processing list, and set 1237334f485dSMiklos Szeredi * the 'sent' flag. 1238334f485dSMiklos Szeredi */ 1239c3021629SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file, 1240c3021629SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1241334f485dSMiklos Szeredi { 124282cbdcd3SMiklos Szeredi ssize_t err; 1243f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 12443a2b5b9cSMiklos Szeredi struct fuse_pqueue *fpq = &fc->pq; 1245334f485dSMiklos Szeredi struct fuse_req *req; 1246334f485dSMiklos Szeredi struct fuse_in *in; 1247334f485dSMiklos Szeredi unsigned reqsize; 1248334f485dSMiklos Szeredi 12491d3d752bSMiklos Szeredi restart: 12504ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 1251e5ac1d1eSJeff Dike err = -EAGAIN; 1252e16714d8SMiklos Szeredi if ((file->f_flags & O_NONBLOCK) && fiq->connected && 1253f88996a9SMiklos Szeredi !request_pending(fiq)) 1254e5ac1d1eSJeff Dike goto err_unlock; 1255e5ac1d1eSJeff Dike 12565250921bSMiklos Szeredi err = wait_event_interruptible_exclusive_locked(fiq->waitq, 12575250921bSMiklos Szeredi !fiq->connected || request_pending(fiq)); 12585250921bSMiklos Szeredi if (err) 12595250921bSMiklos Szeredi goto err_unlock; 12605250921bSMiklos Szeredi 1261334f485dSMiklos Szeredi err = -ENODEV; 1262e16714d8SMiklos Szeredi if (!fiq->connected) 1263334f485dSMiklos Szeredi goto err_unlock; 1264334f485dSMiklos Szeredi 1265f88996a9SMiklos Szeredi if (!list_empty(&fiq->interrupts)) { 1266f88996a9SMiklos Szeredi req = list_entry(fiq->interrupts.next, struct fuse_req, 1267a4d27e75SMiklos Szeredi intr_entry); 1268fd22d62eSMiklos Szeredi return fuse_read_interrupt(fiq, cs, nbytes, req); 1269a4d27e75SMiklos Szeredi } 1270a4d27e75SMiklos Szeredi 1271f88996a9SMiklos Szeredi if (forget_pending(fiq)) { 1272f88996a9SMiklos Szeredi if (list_empty(&fiq->pending) || fiq->forget_batch-- > 0) 1273fd22d62eSMiklos Szeredi return fuse_read_forget(fc, fiq, cs, nbytes); 127407e77dcaSMiklos Szeredi 1275f88996a9SMiklos Szeredi if (fiq->forget_batch <= -8) 1276f88996a9SMiklos Szeredi fiq->forget_batch = 16; 127707e77dcaSMiklos Szeredi } 127807e77dcaSMiklos Szeredi 1279f88996a9SMiklos Szeredi req = list_entry(fiq->pending.next, struct fuse_req, list); 128033e14b4dSMiklos Szeredi clear_bit(FR_PENDING, &req->flags); 1281ef759258SMiklos Szeredi list_del_init(&req->list); 12824ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 12834ce60812SMiklos Szeredi 1284fd22d62eSMiklos Szeredi spin_lock(&fc->lock); 1285334f485dSMiklos Szeredi in = &req->in; 12861d3d752bSMiklos Szeredi reqsize = in->h.len; 12871d3d752bSMiklos Szeredi /* If request is too large, reply with an error and restart the read */ 1288c3021629SMiklos Szeredi if (nbytes < reqsize) { 12891d3d752bSMiklos Szeredi req->out.h.error = -EIO; 12901d3d752bSMiklos Szeredi /* SETXATTR is special, since it may contain too large data */ 12911d3d752bSMiklos Szeredi if (in->h.opcode == FUSE_SETXATTR) 12921d3d752bSMiklos Szeredi req->out.h.error = -E2BIG; 12931d3d752bSMiklos Szeredi request_end(fc, req); 12941d3d752bSMiklos Szeredi goto restart; 12951d3d752bSMiklos Szeredi } 129645a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 129782cbdcd3SMiklos Szeredi list_add(&req->list, &fpq->io); 129845a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 1299d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1300c3021629SMiklos Szeredi cs->req = req; 1301c3021629SMiklos Szeredi err = fuse_copy_one(cs, &in->h, sizeof(in->h)); 1302334f485dSMiklos Szeredi if (!err) 1303c3021629SMiklos Szeredi err = fuse_copy_args(cs, in->numargs, in->argpages, 1304334f485dSMiklos Szeredi (struct fuse_arg *) in->args, 0); 1305c3021629SMiklos Szeredi fuse_copy_finish(cs); 1306d7133114SMiklos Szeredi spin_lock(&fc->lock); 130745a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 1308825d6d33SMiklos Szeredi clear_bit(FR_LOCKED, &req->flags); 1309e96edd94SMiklos Szeredi if (!fpq->connected) { 131082cbdcd3SMiklos Szeredi err = -ENODEV; 131182cbdcd3SMiklos Szeredi goto out_end; 1312c9c9d7dfSMiklos Szeredi } 1313334f485dSMiklos Szeredi if (err) { 1314334f485dSMiklos Szeredi req->out.h.error = -EIO; 131582cbdcd3SMiklos Szeredi goto out_end; 1316334f485dSMiklos Szeredi } 1317825d6d33SMiklos Szeredi if (!test_bit(FR_ISREPLY, &req->flags)) { 131882cbdcd3SMiklos Szeredi err = reqsize; 131982cbdcd3SMiklos Szeredi goto out_end; 132082cbdcd3SMiklos Szeredi } 13213a2b5b9cSMiklos Szeredi list_move_tail(&req->list, &fpq->processing); 132245a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 13238f7bb368SMiklos Szeredi set_bit(FR_SENT, &req->flags); 13248f7bb368SMiklos Szeredi /* matches barrier in request_wait_answer() */ 13258f7bb368SMiklos Szeredi smp_mb__after_atomic(); 1326825d6d33SMiklos Szeredi if (test_bit(FR_INTERRUPTED, &req->flags)) 1327f88996a9SMiklos Szeredi queue_interrupt(fiq, req); 1328d7133114SMiklos Szeredi spin_unlock(&fc->lock); 132982cbdcd3SMiklos Szeredi 1330334f485dSMiklos Szeredi return reqsize; 1331334f485dSMiklos Szeredi 133282cbdcd3SMiklos Szeredi out_end: 133377cd9d48SMiklos Szeredi if (!test_bit(FR_PRIVATE, &req->flags)) 133482cbdcd3SMiklos Szeredi list_del_init(&req->list); 133545a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 133682cbdcd3SMiklos Szeredi request_end(fc, req); 133782cbdcd3SMiklos Szeredi return err; 133882cbdcd3SMiklos Szeredi 1339334f485dSMiklos Szeredi err_unlock: 13404ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 1341334f485dSMiklos Szeredi return err; 1342334f485dSMiklos Szeredi } 1343334f485dSMiklos Szeredi 134494e4fe2cSTom Van Braeckel static int fuse_dev_open(struct inode *inode, struct file *file) 134594e4fe2cSTom Van Braeckel { 134694e4fe2cSTom Van Braeckel /* 134794e4fe2cSTom Van Braeckel * The fuse device's file's private_data is used to hold 134894e4fe2cSTom Van Braeckel * the fuse_conn(ection) when it is mounted, and is used to 134994e4fe2cSTom Van Braeckel * keep track of whether the file has been mounted already. 135094e4fe2cSTom Van Braeckel */ 135194e4fe2cSTom Van Braeckel file->private_data = NULL; 135294e4fe2cSTom Van Braeckel return 0; 135394e4fe2cSTom Van Braeckel } 135494e4fe2cSTom Van Braeckel 1355fbdbaccaSAl Viro static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to) 1356c3021629SMiklos Szeredi { 1357c3021629SMiklos Szeredi struct fuse_copy_state cs; 1358c3021629SMiklos Szeredi struct file *file = iocb->ki_filp; 1359c3021629SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 1360c3021629SMiklos Szeredi if (!fc) 1361c3021629SMiklos Szeredi return -EPERM; 1362c3021629SMiklos Szeredi 1363fbdbaccaSAl Viro if (!iter_is_iovec(to)) 1364fbdbaccaSAl Viro return -EINVAL; 1365c3021629SMiklos Szeredi 1366dc00809aSMiklos Szeredi fuse_copy_init(&cs, 1, to); 1367fbdbaccaSAl Viro 1368fbdbaccaSAl Viro return fuse_dev_do_read(fc, file, &cs, iov_iter_count(to)); 1369c3021629SMiklos Szeredi } 1370c3021629SMiklos Szeredi 1371c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, 1372c3021629SMiklos Szeredi struct pipe_inode_info *pipe, 1373c3021629SMiklos Szeredi size_t len, unsigned int flags) 1374c3021629SMiklos Szeredi { 1375c3021629SMiklos Szeredi int ret; 1376c3021629SMiklos Szeredi int page_nr = 0; 1377c3021629SMiklos Szeredi int do_wakeup = 0; 1378c3021629SMiklos Szeredi struct pipe_buffer *bufs; 1379c3021629SMiklos Szeredi struct fuse_copy_state cs; 1380c3021629SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(in); 1381c3021629SMiklos Szeredi if (!fc) 1382c3021629SMiklos Szeredi return -EPERM; 1383c3021629SMiklos Szeredi 1384c3021629SMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1385c3021629SMiklos Szeredi if (!bufs) 1386c3021629SMiklos Szeredi return -ENOMEM; 1387c3021629SMiklos Szeredi 1388dc00809aSMiklos Szeredi fuse_copy_init(&cs, 1, NULL); 1389c3021629SMiklos Szeredi cs.pipebufs = bufs; 1390c3021629SMiklos Szeredi cs.pipe = pipe; 1391c3021629SMiklos Szeredi ret = fuse_dev_do_read(fc, in, &cs, len); 1392c3021629SMiklos Szeredi if (ret < 0) 1393c3021629SMiklos Szeredi goto out; 1394c3021629SMiklos Szeredi 1395c3021629SMiklos Szeredi ret = 0; 1396c3021629SMiklos Szeredi pipe_lock(pipe); 1397c3021629SMiklos Szeredi 1398c3021629SMiklos Szeredi if (!pipe->readers) { 1399c3021629SMiklos Szeredi send_sig(SIGPIPE, current, 0); 1400c3021629SMiklos Szeredi if (!ret) 1401c3021629SMiklos Szeredi ret = -EPIPE; 1402c3021629SMiklos Szeredi goto out_unlock; 1403c3021629SMiklos Szeredi } 1404c3021629SMiklos Szeredi 1405c3021629SMiklos Szeredi if (pipe->nrbufs + cs.nr_segs > pipe->buffers) { 1406c3021629SMiklos Szeredi ret = -EIO; 1407c3021629SMiklos Szeredi goto out_unlock; 1408c3021629SMiklos Szeredi } 1409c3021629SMiklos Szeredi 1410c3021629SMiklos Szeredi while (page_nr < cs.nr_segs) { 1411c3021629SMiklos Szeredi int newbuf = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); 1412c3021629SMiklos Szeredi struct pipe_buffer *buf = pipe->bufs + newbuf; 1413c3021629SMiklos Szeredi 1414c3021629SMiklos Szeredi buf->page = bufs[page_nr].page; 1415c3021629SMiklos Szeredi buf->offset = bufs[page_nr].offset; 1416c3021629SMiklos Szeredi buf->len = bufs[page_nr].len; 141728a625cbSMiklos Szeredi /* 141828a625cbSMiklos Szeredi * Need to be careful about this. Having buf->ops in module 141928a625cbSMiklos Szeredi * code can Oops if the buffer persists after module unload. 142028a625cbSMiklos Szeredi */ 142128a625cbSMiklos Szeredi buf->ops = &nosteal_pipe_buf_ops; 1422c3021629SMiklos Szeredi 1423c3021629SMiklos Szeredi pipe->nrbufs++; 1424c3021629SMiklos Szeredi page_nr++; 1425c3021629SMiklos Szeredi ret += buf->len; 1426c3021629SMiklos Szeredi 14276447a3cfSAl Viro if (pipe->files) 1428c3021629SMiklos Szeredi do_wakeup = 1; 1429c3021629SMiklos Szeredi } 1430c3021629SMiklos Szeredi 1431c3021629SMiklos Szeredi out_unlock: 1432c3021629SMiklos Szeredi pipe_unlock(pipe); 1433c3021629SMiklos Szeredi 1434c3021629SMiklos Szeredi if (do_wakeup) { 1435c3021629SMiklos Szeredi smp_mb(); 1436c3021629SMiklos Szeredi if (waitqueue_active(&pipe->wait)) 1437c3021629SMiklos Szeredi wake_up_interruptible(&pipe->wait); 1438c3021629SMiklos Szeredi kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); 1439c3021629SMiklos Szeredi } 1440c3021629SMiklos Szeredi 1441c3021629SMiklos Szeredi out: 1442c3021629SMiklos Szeredi for (; page_nr < cs.nr_segs; page_nr++) 1443c3021629SMiklos Szeredi page_cache_release(bufs[page_nr].page); 1444c3021629SMiklos Szeredi 1445c3021629SMiklos Szeredi kfree(bufs); 1446c3021629SMiklos Szeredi return ret; 1447c3021629SMiklos Szeredi } 1448c3021629SMiklos Szeredi 144995668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size, 145095668a69STejun Heo struct fuse_copy_state *cs) 145195668a69STejun Heo { 145295668a69STejun Heo struct fuse_notify_poll_wakeup_out outarg; 1453f6d47a17SMiklos Szeredi int err = -EINVAL; 145495668a69STejun Heo 145595668a69STejun Heo if (size != sizeof(outarg)) 1456f6d47a17SMiklos Szeredi goto err; 145795668a69STejun Heo 145895668a69STejun Heo err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 145995668a69STejun Heo if (err) 1460f6d47a17SMiklos Szeredi goto err; 146195668a69STejun Heo 1462f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 146395668a69STejun Heo return fuse_notify_poll_wakeup(fc, &outarg); 1464f6d47a17SMiklos Szeredi 1465f6d47a17SMiklos Szeredi err: 1466f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 1467f6d47a17SMiklos Szeredi return err; 146895668a69STejun Heo } 146995668a69STejun Heo 14703b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size, 14713b463ae0SJohn Muir struct fuse_copy_state *cs) 14723b463ae0SJohn Muir { 14733b463ae0SJohn Muir struct fuse_notify_inval_inode_out outarg; 14743b463ae0SJohn Muir int err = -EINVAL; 14753b463ae0SJohn Muir 14763b463ae0SJohn Muir if (size != sizeof(outarg)) 14773b463ae0SJohn Muir goto err; 14783b463ae0SJohn Muir 14793b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 14803b463ae0SJohn Muir if (err) 14813b463ae0SJohn Muir goto err; 14823b463ae0SJohn Muir fuse_copy_finish(cs); 14833b463ae0SJohn Muir 14843b463ae0SJohn Muir down_read(&fc->killsb); 14853b463ae0SJohn Muir err = -ENOENT; 1486b21dda43SMiklos Szeredi if (fc->sb) { 14873b463ae0SJohn Muir err = fuse_reverse_inval_inode(fc->sb, outarg.ino, 14883b463ae0SJohn Muir outarg.off, outarg.len); 1489b21dda43SMiklos Szeredi } 14903b463ae0SJohn Muir up_read(&fc->killsb); 14913b463ae0SJohn Muir return err; 14923b463ae0SJohn Muir 14933b463ae0SJohn Muir err: 14943b463ae0SJohn Muir fuse_copy_finish(cs); 14953b463ae0SJohn Muir return err; 14963b463ae0SJohn Muir } 14973b463ae0SJohn Muir 14983b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, 14993b463ae0SJohn Muir struct fuse_copy_state *cs) 15003b463ae0SJohn Muir { 15013b463ae0SJohn Muir struct fuse_notify_inval_entry_out outarg; 1502b2d82ee3SFang Wenqi int err = -ENOMEM; 1503b2d82ee3SFang Wenqi char *buf; 15043b463ae0SJohn Muir struct qstr name; 15053b463ae0SJohn Muir 1506b2d82ee3SFang Wenqi buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1507b2d82ee3SFang Wenqi if (!buf) 1508b2d82ee3SFang Wenqi goto err; 1509b2d82ee3SFang Wenqi 1510b2d82ee3SFang Wenqi err = -EINVAL; 15113b463ae0SJohn Muir if (size < sizeof(outarg)) 15123b463ae0SJohn Muir goto err; 15133b463ae0SJohn Muir 15143b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 15153b463ae0SJohn Muir if (err) 15163b463ae0SJohn Muir goto err; 15173b463ae0SJohn Muir 15183b463ae0SJohn Muir err = -ENAMETOOLONG; 15193b463ae0SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 15203b463ae0SJohn Muir goto err; 15213b463ae0SJohn Muir 1522c2183d1eSMiklos Szeredi err = -EINVAL; 1523c2183d1eSMiklos Szeredi if (size != sizeof(outarg) + outarg.namelen + 1) 1524c2183d1eSMiklos Szeredi goto err; 1525c2183d1eSMiklos Szeredi 15263b463ae0SJohn Muir name.name = buf; 15273b463ae0SJohn Muir name.len = outarg.namelen; 15283b463ae0SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 15293b463ae0SJohn Muir if (err) 15303b463ae0SJohn Muir goto err; 15313b463ae0SJohn Muir fuse_copy_finish(cs); 15323b463ae0SJohn Muir buf[outarg.namelen] = 0; 15333b463ae0SJohn Muir name.hash = full_name_hash(name.name, name.len); 15343b463ae0SJohn Muir 15353b463ae0SJohn Muir down_read(&fc->killsb); 15363b463ae0SJohn Muir err = -ENOENT; 1537b21dda43SMiklos Szeredi if (fc->sb) 1538451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 0, &name); 1539451d0f59SJohn Muir up_read(&fc->killsb); 1540451d0f59SJohn Muir kfree(buf); 1541451d0f59SJohn Muir return err; 1542451d0f59SJohn Muir 1543451d0f59SJohn Muir err: 1544451d0f59SJohn Muir kfree(buf); 1545451d0f59SJohn Muir fuse_copy_finish(cs); 1546451d0f59SJohn Muir return err; 1547451d0f59SJohn Muir } 1548451d0f59SJohn Muir 1549451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size, 1550451d0f59SJohn Muir struct fuse_copy_state *cs) 1551451d0f59SJohn Muir { 1552451d0f59SJohn Muir struct fuse_notify_delete_out outarg; 1553451d0f59SJohn Muir int err = -ENOMEM; 1554451d0f59SJohn Muir char *buf; 1555451d0f59SJohn Muir struct qstr name; 1556451d0f59SJohn Muir 1557451d0f59SJohn Muir buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1558451d0f59SJohn Muir if (!buf) 1559451d0f59SJohn Muir goto err; 1560451d0f59SJohn Muir 1561451d0f59SJohn Muir err = -EINVAL; 1562451d0f59SJohn Muir if (size < sizeof(outarg)) 1563451d0f59SJohn Muir goto err; 1564451d0f59SJohn Muir 1565451d0f59SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1566451d0f59SJohn Muir if (err) 1567451d0f59SJohn Muir goto err; 1568451d0f59SJohn Muir 1569451d0f59SJohn Muir err = -ENAMETOOLONG; 1570451d0f59SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 1571451d0f59SJohn Muir goto err; 1572451d0f59SJohn Muir 1573451d0f59SJohn Muir err = -EINVAL; 1574451d0f59SJohn Muir if (size != sizeof(outarg) + outarg.namelen + 1) 1575451d0f59SJohn Muir goto err; 1576451d0f59SJohn Muir 1577451d0f59SJohn Muir name.name = buf; 1578451d0f59SJohn Muir name.len = outarg.namelen; 1579451d0f59SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 1580451d0f59SJohn Muir if (err) 1581451d0f59SJohn Muir goto err; 1582451d0f59SJohn Muir fuse_copy_finish(cs); 1583451d0f59SJohn Muir buf[outarg.namelen] = 0; 1584451d0f59SJohn Muir name.hash = full_name_hash(name.name, name.len); 1585451d0f59SJohn Muir 1586451d0f59SJohn Muir down_read(&fc->killsb); 1587451d0f59SJohn Muir err = -ENOENT; 1588451d0f59SJohn Muir if (fc->sb) 1589451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 1590451d0f59SJohn Muir outarg.child, &name); 15913b463ae0SJohn Muir up_read(&fc->killsb); 1592b2d82ee3SFang Wenqi kfree(buf); 15933b463ae0SJohn Muir return err; 15943b463ae0SJohn Muir 15953b463ae0SJohn Muir err: 1596b2d82ee3SFang Wenqi kfree(buf); 15973b463ae0SJohn Muir fuse_copy_finish(cs); 15983b463ae0SJohn Muir return err; 15993b463ae0SJohn Muir } 16003b463ae0SJohn Muir 1601a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, 1602a1d75f25SMiklos Szeredi struct fuse_copy_state *cs) 1603a1d75f25SMiklos Szeredi { 1604a1d75f25SMiklos Szeredi struct fuse_notify_store_out outarg; 1605a1d75f25SMiklos Szeredi struct inode *inode; 1606a1d75f25SMiklos Szeredi struct address_space *mapping; 1607a1d75f25SMiklos Szeredi u64 nodeid; 1608a1d75f25SMiklos Szeredi int err; 1609a1d75f25SMiklos Szeredi pgoff_t index; 1610a1d75f25SMiklos Szeredi unsigned int offset; 1611a1d75f25SMiklos Szeredi unsigned int num; 1612a1d75f25SMiklos Szeredi loff_t file_size; 1613a1d75f25SMiklos Szeredi loff_t end; 1614a1d75f25SMiklos Szeredi 1615a1d75f25SMiklos Szeredi err = -EINVAL; 1616a1d75f25SMiklos Szeredi if (size < sizeof(outarg)) 1617a1d75f25SMiklos Szeredi goto out_finish; 1618a1d75f25SMiklos Szeredi 1619a1d75f25SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1620a1d75f25SMiklos Szeredi if (err) 1621a1d75f25SMiklos Szeredi goto out_finish; 1622a1d75f25SMiklos Szeredi 1623a1d75f25SMiklos Szeredi err = -EINVAL; 1624a1d75f25SMiklos Szeredi if (size - sizeof(outarg) != outarg.size) 1625a1d75f25SMiklos Szeredi goto out_finish; 1626a1d75f25SMiklos Szeredi 1627a1d75f25SMiklos Szeredi nodeid = outarg.nodeid; 1628a1d75f25SMiklos Szeredi 1629a1d75f25SMiklos Szeredi down_read(&fc->killsb); 1630a1d75f25SMiklos Szeredi 1631a1d75f25SMiklos Szeredi err = -ENOENT; 1632a1d75f25SMiklos Szeredi if (!fc->sb) 1633a1d75f25SMiklos Szeredi goto out_up_killsb; 1634a1d75f25SMiklos Szeredi 1635a1d75f25SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 1636a1d75f25SMiklos Szeredi if (!inode) 1637a1d75f25SMiklos Szeredi goto out_up_killsb; 1638a1d75f25SMiklos Szeredi 1639a1d75f25SMiklos Szeredi mapping = inode->i_mapping; 1640a1d75f25SMiklos Szeredi index = outarg.offset >> PAGE_CACHE_SHIFT; 1641a1d75f25SMiklos Szeredi offset = outarg.offset & ~PAGE_CACHE_MASK; 1642a1d75f25SMiklos Szeredi file_size = i_size_read(inode); 1643a1d75f25SMiklos Szeredi end = outarg.offset + outarg.size; 1644a1d75f25SMiklos Szeredi if (end > file_size) { 1645a1d75f25SMiklos Szeredi file_size = end; 1646a1d75f25SMiklos Szeredi fuse_write_update_size(inode, file_size); 1647a1d75f25SMiklos Szeredi } 1648a1d75f25SMiklos Szeredi 1649a1d75f25SMiklos Szeredi num = outarg.size; 1650a1d75f25SMiklos Szeredi while (num) { 1651a1d75f25SMiklos Szeredi struct page *page; 1652a1d75f25SMiklos Szeredi unsigned int this_num; 1653a1d75f25SMiklos Szeredi 1654a1d75f25SMiklos Szeredi err = -ENOMEM; 1655a1d75f25SMiklos Szeredi page = find_or_create_page(mapping, index, 1656a1d75f25SMiklos Szeredi mapping_gfp_mask(mapping)); 1657a1d75f25SMiklos Szeredi if (!page) 1658a1d75f25SMiklos Szeredi goto out_iput; 1659a1d75f25SMiklos Szeredi 1660a1d75f25SMiklos Szeredi this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 1661a1d75f25SMiklos Szeredi err = fuse_copy_page(cs, &page, offset, this_num, 0); 1662063ec1e5SMiklos Szeredi if (!err && offset == 0 && 1663063ec1e5SMiklos Szeredi (this_num == PAGE_CACHE_SIZE || file_size == end)) 1664a1d75f25SMiklos Szeredi SetPageUptodate(page); 1665a1d75f25SMiklos Szeredi unlock_page(page); 1666a1d75f25SMiklos Szeredi page_cache_release(page); 1667a1d75f25SMiklos Szeredi 1668a1d75f25SMiklos Szeredi if (err) 1669a1d75f25SMiklos Szeredi goto out_iput; 1670a1d75f25SMiklos Szeredi 1671a1d75f25SMiklos Szeredi num -= this_num; 1672a1d75f25SMiklos Szeredi offset = 0; 1673a1d75f25SMiklos Szeredi index++; 1674a1d75f25SMiklos Szeredi } 1675a1d75f25SMiklos Szeredi 1676a1d75f25SMiklos Szeredi err = 0; 1677a1d75f25SMiklos Szeredi 1678a1d75f25SMiklos Szeredi out_iput: 1679a1d75f25SMiklos Szeredi iput(inode); 1680a1d75f25SMiklos Szeredi out_up_killsb: 1681a1d75f25SMiklos Szeredi up_read(&fc->killsb); 1682a1d75f25SMiklos Szeredi out_finish: 1683a1d75f25SMiklos Szeredi fuse_copy_finish(cs); 1684a1d75f25SMiklos Szeredi return err; 1685a1d75f25SMiklos Szeredi } 1686a1d75f25SMiklos Szeredi 16872d45ba38SMiklos Szeredi static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) 16882d45ba38SMiklos Szeredi { 1689b745bc85SMel Gorman release_pages(req->pages, req->num_pages, false); 16902d45ba38SMiklos Szeredi } 16912d45ba38SMiklos Szeredi 16922d45ba38SMiklos Szeredi static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, 16932d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out *outarg) 16942d45ba38SMiklos Szeredi { 16952d45ba38SMiklos Szeredi int err; 16962d45ba38SMiklos Szeredi struct address_space *mapping = inode->i_mapping; 16972d45ba38SMiklos Szeredi struct fuse_req *req; 16982d45ba38SMiklos Szeredi pgoff_t index; 16992d45ba38SMiklos Szeredi loff_t file_size; 17002d45ba38SMiklos Szeredi unsigned int num; 17012d45ba38SMiklos Szeredi unsigned int offset; 17020157443cSGeert Uytterhoeven size_t total_len = 0; 17034d53dc99SMaxim Patlasov int num_pages; 17042d45ba38SMiklos Szeredi 17052d45ba38SMiklos Szeredi offset = outarg->offset & ~PAGE_CACHE_MASK; 17064d53dc99SMaxim Patlasov file_size = i_size_read(inode); 17074d53dc99SMaxim Patlasov 17084d53dc99SMaxim Patlasov num = outarg->size; 17094d53dc99SMaxim Patlasov if (outarg->offset > file_size) 17104d53dc99SMaxim Patlasov num = 0; 17114d53dc99SMaxim Patlasov else if (outarg->offset + num > file_size) 17124d53dc99SMaxim Patlasov num = file_size - outarg->offset; 17134d53dc99SMaxim Patlasov 17144d53dc99SMaxim Patlasov num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; 17154d53dc99SMaxim Patlasov num_pages = min(num_pages, FUSE_MAX_PAGES_PER_REQ); 17164d53dc99SMaxim Patlasov 17174d53dc99SMaxim Patlasov req = fuse_get_req(fc, num_pages); 17184d53dc99SMaxim Patlasov if (IS_ERR(req)) 17194d53dc99SMaxim Patlasov return PTR_ERR(req); 17202d45ba38SMiklos Szeredi 17212d45ba38SMiklos Szeredi req->in.h.opcode = FUSE_NOTIFY_REPLY; 17222d45ba38SMiklos Szeredi req->in.h.nodeid = outarg->nodeid; 17232d45ba38SMiklos Szeredi req->in.numargs = 2; 17242d45ba38SMiklos Szeredi req->in.argpages = 1; 1725b2430d75SMaxim Patlasov req->page_descs[0].offset = offset; 17262d45ba38SMiklos Szeredi req->end = fuse_retrieve_end; 17272d45ba38SMiklos Szeredi 17282d45ba38SMiklos Szeredi index = outarg->offset >> PAGE_CACHE_SHIFT; 17292d45ba38SMiklos Szeredi 17304d53dc99SMaxim Patlasov while (num && req->num_pages < num_pages) { 17312d45ba38SMiklos Szeredi struct page *page; 17322d45ba38SMiklos Szeredi unsigned int this_num; 17332d45ba38SMiklos Szeredi 17342d45ba38SMiklos Szeredi page = find_get_page(mapping, index); 17352d45ba38SMiklos Szeredi if (!page) 17362d45ba38SMiklos Szeredi break; 17372d45ba38SMiklos Szeredi 17382d45ba38SMiklos Szeredi this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 17392d45ba38SMiklos Szeredi req->pages[req->num_pages] = page; 174085f40aecSMaxim Patlasov req->page_descs[req->num_pages].length = this_num; 17412d45ba38SMiklos Szeredi req->num_pages++; 17422d45ba38SMiklos Szeredi 1743c9e67d48SMiklos Szeredi offset = 0; 17442d45ba38SMiklos Szeredi num -= this_num; 17452d45ba38SMiklos Szeredi total_len += this_num; 174648706d0aSMiklos Szeredi index++; 17472d45ba38SMiklos Szeredi } 17482d45ba38SMiklos Szeredi req->misc.retrieve_in.offset = outarg->offset; 17492d45ba38SMiklos Szeredi req->misc.retrieve_in.size = total_len; 17502d45ba38SMiklos Szeredi req->in.args[0].size = sizeof(req->misc.retrieve_in); 17512d45ba38SMiklos Szeredi req->in.args[0].value = &req->misc.retrieve_in; 17522d45ba38SMiklos Szeredi req->in.args[1].size = total_len; 17532d45ba38SMiklos Szeredi 17542d45ba38SMiklos Szeredi err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique); 17552d45ba38SMiklos Szeredi if (err) 17562d45ba38SMiklos Szeredi fuse_retrieve_end(fc, req); 17572d45ba38SMiklos Szeredi 17582d45ba38SMiklos Szeredi return err; 17592d45ba38SMiklos Szeredi } 17602d45ba38SMiklos Szeredi 17612d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, 17622d45ba38SMiklos Szeredi struct fuse_copy_state *cs) 17632d45ba38SMiklos Szeredi { 17642d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out outarg; 17652d45ba38SMiklos Szeredi struct inode *inode; 17662d45ba38SMiklos Szeredi int err; 17672d45ba38SMiklos Szeredi 17682d45ba38SMiklos Szeredi err = -EINVAL; 17692d45ba38SMiklos Szeredi if (size != sizeof(outarg)) 17702d45ba38SMiklos Szeredi goto copy_finish; 17712d45ba38SMiklos Szeredi 17722d45ba38SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 17732d45ba38SMiklos Szeredi if (err) 17742d45ba38SMiklos Szeredi goto copy_finish; 17752d45ba38SMiklos Szeredi 17762d45ba38SMiklos Szeredi fuse_copy_finish(cs); 17772d45ba38SMiklos Szeredi 17782d45ba38SMiklos Szeredi down_read(&fc->killsb); 17792d45ba38SMiklos Szeredi err = -ENOENT; 17802d45ba38SMiklos Szeredi if (fc->sb) { 17812d45ba38SMiklos Szeredi u64 nodeid = outarg.nodeid; 17822d45ba38SMiklos Szeredi 17832d45ba38SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 17842d45ba38SMiklos Szeredi if (inode) { 17852d45ba38SMiklos Szeredi err = fuse_retrieve(fc, inode, &outarg); 17862d45ba38SMiklos Szeredi iput(inode); 17872d45ba38SMiklos Szeredi } 17882d45ba38SMiklos Szeredi } 17892d45ba38SMiklos Szeredi up_read(&fc->killsb); 17902d45ba38SMiklos Szeredi 17912d45ba38SMiklos Szeredi return err; 17922d45ba38SMiklos Szeredi 17932d45ba38SMiklos Szeredi copy_finish: 17942d45ba38SMiklos Szeredi fuse_copy_finish(cs); 17952d45ba38SMiklos Szeredi return err; 17962d45ba38SMiklos Szeredi } 17972d45ba38SMiklos Szeredi 17988599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, 17998599396bSTejun Heo unsigned int size, struct fuse_copy_state *cs) 18008599396bSTejun Heo { 18010d278362SMiklos Szeredi /* Don't try to move pages (yet) */ 18020d278362SMiklos Szeredi cs->move_pages = 0; 18030d278362SMiklos Szeredi 18048599396bSTejun Heo switch (code) { 180595668a69STejun Heo case FUSE_NOTIFY_POLL: 180695668a69STejun Heo return fuse_notify_poll(fc, size, cs); 180795668a69STejun Heo 18083b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_INODE: 18093b463ae0SJohn Muir return fuse_notify_inval_inode(fc, size, cs); 18103b463ae0SJohn Muir 18113b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_ENTRY: 18123b463ae0SJohn Muir return fuse_notify_inval_entry(fc, size, cs); 18133b463ae0SJohn Muir 1814a1d75f25SMiklos Szeredi case FUSE_NOTIFY_STORE: 1815a1d75f25SMiklos Szeredi return fuse_notify_store(fc, size, cs); 1816a1d75f25SMiklos Szeredi 18172d45ba38SMiklos Szeredi case FUSE_NOTIFY_RETRIEVE: 18182d45ba38SMiklos Szeredi return fuse_notify_retrieve(fc, size, cs); 18192d45ba38SMiklos Szeredi 1820451d0f59SJohn Muir case FUSE_NOTIFY_DELETE: 1821451d0f59SJohn Muir return fuse_notify_delete(fc, size, cs); 1822451d0f59SJohn Muir 18238599396bSTejun Heo default: 1824f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 18258599396bSTejun Heo return -EINVAL; 18268599396bSTejun Heo } 18278599396bSTejun Heo } 18288599396bSTejun Heo 1829334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */ 18303a2b5b9cSMiklos Szeredi static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique) 1831334f485dSMiklos Szeredi { 1832334f485dSMiklos Szeredi struct fuse_req *req; 183305726acaSDong Fang 18343a2b5b9cSMiklos Szeredi list_for_each_entry(req, &fpq->processing, list) { 1835a4d27e75SMiklos Szeredi if (req->in.h.unique == unique || req->intr_unique == unique) 1836334f485dSMiklos Szeredi return req; 1837334f485dSMiklos Szeredi } 1838334f485dSMiklos Szeredi return NULL; 1839334f485dSMiklos Szeredi } 1840334f485dSMiklos Szeredi 1841334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out, 1842334f485dSMiklos Szeredi unsigned nbytes) 1843334f485dSMiklos Szeredi { 1844334f485dSMiklos Szeredi unsigned reqsize = sizeof(struct fuse_out_header); 1845334f485dSMiklos Szeredi 1846334f485dSMiklos Szeredi if (out->h.error) 1847334f485dSMiklos Szeredi return nbytes != reqsize ? -EINVAL : 0; 1848334f485dSMiklos Szeredi 1849334f485dSMiklos Szeredi reqsize += len_args(out->numargs, out->args); 1850334f485dSMiklos Szeredi 1851334f485dSMiklos Szeredi if (reqsize < nbytes || (reqsize > nbytes && !out->argvar)) 1852334f485dSMiklos Szeredi return -EINVAL; 1853334f485dSMiklos Szeredi else if (reqsize > nbytes) { 1854334f485dSMiklos Szeredi struct fuse_arg *lastarg = &out->args[out->numargs-1]; 1855334f485dSMiklos Szeredi unsigned diffsize = reqsize - nbytes; 1856334f485dSMiklos Szeredi if (diffsize > lastarg->size) 1857334f485dSMiklos Szeredi return -EINVAL; 1858334f485dSMiklos Szeredi lastarg->size -= diffsize; 1859334f485dSMiklos Szeredi } 1860334f485dSMiklos Szeredi return fuse_copy_args(cs, out->numargs, out->argpages, out->args, 1861334f485dSMiklos Szeredi out->page_zeroing); 1862334f485dSMiklos Szeredi } 1863334f485dSMiklos Szeredi 1864334f485dSMiklos Szeredi /* 1865334f485dSMiklos Szeredi * Write a single reply to a request. First the header is copied from 1866334f485dSMiklos Szeredi * the write buffer. The request is then searched on the processing 1867334f485dSMiklos Szeredi * list by the unique ID found in the header. If found, then remove 1868334f485dSMiklos Szeredi * it from the list and copy the rest of the buffer to the request. 1869334f485dSMiklos Szeredi * The request is finished by calling request_end() 1870334f485dSMiklos Szeredi */ 1871dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_conn *fc, 1872dd3bb14fSMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1873334f485dSMiklos Szeredi { 1874334f485dSMiklos Szeredi int err; 18753a2b5b9cSMiklos Szeredi struct fuse_pqueue *fpq = &fc->pq; 1876334f485dSMiklos Szeredi struct fuse_req *req; 1877334f485dSMiklos Szeredi struct fuse_out_header oh; 1878334f485dSMiklos Szeredi 1879334f485dSMiklos Szeredi if (nbytes < sizeof(struct fuse_out_header)) 1880334f485dSMiklos Szeredi return -EINVAL; 1881334f485dSMiklos Szeredi 1882dd3bb14fSMiklos Szeredi err = fuse_copy_one(cs, &oh, sizeof(oh)); 1883334f485dSMiklos Szeredi if (err) 1884334f485dSMiklos Szeredi goto err_finish; 18858599396bSTejun Heo 1886334f485dSMiklos Szeredi err = -EINVAL; 18878599396bSTejun Heo if (oh.len != nbytes) 18888599396bSTejun Heo goto err_finish; 18898599396bSTejun Heo 18908599396bSTejun Heo /* 18918599396bSTejun Heo * Zero oh.unique indicates unsolicited notification message 18928599396bSTejun Heo * and error contains notification code. 18938599396bSTejun Heo */ 18948599396bSTejun Heo if (!oh.unique) { 1895dd3bb14fSMiklos Szeredi err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs); 18968599396bSTejun Heo return err ? err : nbytes; 18978599396bSTejun Heo } 18988599396bSTejun Heo 18998599396bSTejun Heo err = -EINVAL; 19008599396bSTejun Heo if (oh.error <= -1000 || oh.error > 0) 1901334f485dSMiklos Szeredi goto err_finish; 1902334f485dSMiklos Szeredi 1903d7133114SMiklos Szeredi spin_lock(&fc->lock); 190445a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 190569a53bf2SMiklos Szeredi err = -ENOENT; 1906e96edd94SMiklos Szeredi if (!fpq->connected) 190745a91cb1SMiklos Szeredi goto err_unlock_pq; 190869a53bf2SMiklos Szeredi 19093a2b5b9cSMiklos Szeredi req = request_find(fpq, oh.unique); 1910334f485dSMiklos Szeredi if (!req) 191145a91cb1SMiklos Szeredi goto err_unlock_pq; 1912334f485dSMiklos Szeredi 1913a4d27e75SMiklos Szeredi /* Is it an interrupt reply? */ 1914a4d27e75SMiklos Szeredi if (req->intr_unique == oh.unique) { 191545a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 191645a91cb1SMiklos Szeredi 1917a4d27e75SMiklos Szeredi err = -EINVAL; 1918a4d27e75SMiklos Szeredi if (nbytes != sizeof(struct fuse_out_header)) 1919a4d27e75SMiklos Szeredi goto err_unlock; 1920a4d27e75SMiklos Szeredi 1921a4d27e75SMiklos Szeredi if (oh.error == -ENOSYS) 1922a4d27e75SMiklos Szeredi fc->no_interrupt = 1; 1923a4d27e75SMiklos Szeredi else if (oh.error == -EAGAIN) 1924f88996a9SMiklos Szeredi queue_interrupt(&fc->iq, req); 1925a4d27e75SMiklos Szeredi 1926a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 1927dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1928a4d27e75SMiklos Szeredi return nbytes; 1929a4d27e75SMiklos Szeredi } 1930a4d27e75SMiklos Szeredi 193133e14b4dSMiklos Szeredi clear_bit(FR_SENT, &req->flags); 19323a2b5b9cSMiklos Szeredi list_move(&req->list, &fpq->io); 1933334f485dSMiklos Szeredi req->out.h = oh; 1934825d6d33SMiklos Szeredi set_bit(FR_LOCKED, &req->flags); 193545a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 1936dd3bb14fSMiklos Szeredi cs->req = req; 1937ce534fb0SMiklos Szeredi if (!req->out.page_replace) 1938ce534fb0SMiklos Szeredi cs->move_pages = 0; 1939d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1940334f485dSMiklos Szeredi 1941dd3bb14fSMiklos Szeredi err = copy_out_args(cs, &req->out, nbytes); 1942dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1943334f485dSMiklos Szeredi 1944d7133114SMiklos Szeredi spin_lock(&fc->lock); 194545a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 1946825d6d33SMiklos Szeredi clear_bit(FR_LOCKED, &req->flags); 1947e96edd94SMiklos Szeredi if (!fpq->connected) 1948334f485dSMiklos Szeredi err = -ENOENT; 19490d8e84b0SMiklos Szeredi else if (err) 1950334f485dSMiklos Szeredi req->out.h.error = -EIO; 195177cd9d48SMiklos Szeredi if (!test_bit(FR_PRIVATE, &req->flags)) 1952f377cb79SMiklos Szeredi list_del_init(&req->list); 195345a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 1954334f485dSMiklos Szeredi request_end(fc, req); 1955334f485dSMiklos Szeredi 1956334f485dSMiklos Szeredi return err ? err : nbytes; 1957334f485dSMiklos Szeredi 195845a91cb1SMiklos Szeredi err_unlock_pq: 195945a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 1960334f485dSMiklos Szeredi err_unlock: 1961d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1962334f485dSMiklos Szeredi err_finish: 1963dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1964334f485dSMiklos Szeredi return err; 1965334f485dSMiklos Szeredi } 1966334f485dSMiklos Szeredi 1967fbdbaccaSAl Viro static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from) 1968dd3bb14fSMiklos Szeredi { 1969dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1970dd3bb14fSMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp); 1971dd3bb14fSMiklos Szeredi if (!fc) 1972dd3bb14fSMiklos Szeredi return -EPERM; 1973dd3bb14fSMiklos Szeredi 1974fbdbaccaSAl Viro if (!iter_is_iovec(from)) 1975fbdbaccaSAl Viro return -EINVAL; 1976dd3bb14fSMiklos Szeredi 1977dc00809aSMiklos Szeredi fuse_copy_init(&cs, 0, from); 1978fbdbaccaSAl Viro 1979fbdbaccaSAl Viro return fuse_dev_do_write(fc, &cs, iov_iter_count(from)); 1980dd3bb14fSMiklos Szeredi } 1981dd3bb14fSMiklos Szeredi 1982dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, 1983dd3bb14fSMiklos Szeredi struct file *out, loff_t *ppos, 1984dd3bb14fSMiklos Szeredi size_t len, unsigned int flags) 1985dd3bb14fSMiklos Szeredi { 1986dd3bb14fSMiklos Szeredi unsigned nbuf; 1987dd3bb14fSMiklos Szeredi unsigned idx; 1988dd3bb14fSMiklos Szeredi struct pipe_buffer *bufs; 1989dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1990dd3bb14fSMiklos Szeredi struct fuse_conn *fc; 1991dd3bb14fSMiklos Szeredi size_t rem; 1992dd3bb14fSMiklos Szeredi ssize_t ret; 1993dd3bb14fSMiklos Szeredi 1994dd3bb14fSMiklos Szeredi fc = fuse_get_conn(out); 1995dd3bb14fSMiklos Szeredi if (!fc) 1996dd3bb14fSMiklos Szeredi return -EPERM; 1997dd3bb14fSMiklos Szeredi 1998dd3bb14fSMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1999dd3bb14fSMiklos Szeredi if (!bufs) 2000dd3bb14fSMiklos Szeredi return -ENOMEM; 2001dd3bb14fSMiklos Szeredi 2002dd3bb14fSMiklos Szeredi pipe_lock(pipe); 2003dd3bb14fSMiklos Szeredi nbuf = 0; 2004dd3bb14fSMiklos Szeredi rem = 0; 2005dd3bb14fSMiklos Szeredi for (idx = 0; idx < pipe->nrbufs && rem < len; idx++) 2006dd3bb14fSMiklos Szeredi rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len; 2007dd3bb14fSMiklos Szeredi 2008dd3bb14fSMiklos Szeredi ret = -EINVAL; 2009dd3bb14fSMiklos Szeredi if (rem < len) { 2010dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 2011dd3bb14fSMiklos Szeredi goto out; 2012dd3bb14fSMiklos Szeredi } 2013dd3bb14fSMiklos Szeredi 2014dd3bb14fSMiklos Szeredi rem = len; 2015dd3bb14fSMiklos Szeredi while (rem) { 2016dd3bb14fSMiklos Szeredi struct pipe_buffer *ibuf; 2017dd3bb14fSMiklos Szeredi struct pipe_buffer *obuf; 2018dd3bb14fSMiklos Szeredi 2019dd3bb14fSMiklos Szeredi BUG_ON(nbuf >= pipe->buffers); 2020dd3bb14fSMiklos Szeredi BUG_ON(!pipe->nrbufs); 2021dd3bb14fSMiklos Szeredi ibuf = &pipe->bufs[pipe->curbuf]; 2022dd3bb14fSMiklos Szeredi obuf = &bufs[nbuf]; 2023dd3bb14fSMiklos Szeredi 2024dd3bb14fSMiklos Szeredi if (rem >= ibuf->len) { 2025dd3bb14fSMiklos Szeredi *obuf = *ibuf; 2026dd3bb14fSMiklos Szeredi ibuf->ops = NULL; 2027dd3bb14fSMiklos Szeredi pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); 2028dd3bb14fSMiklos Szeredi pipe->nrbufs--; 2029dd3bb14fSMiklos Szeredi } else { 2030dd3bb14fSMiklos Szeredi ibuf->ops->get(pipe, ibuf); 2031dd3bb14fSMiklos Szeredi *obuf = *ibuf; 2032dd3bb14fSMiklos Szeredi obuf->flags &= ~PIPE_BUF_FLAG_GIFT; 2033dd3bb14fSMiklos Szeredi obuf->len = rem; 2034dd3bb14fSMiklos Szeredi ibuf->offset += obuf->len; 2035dd3bb14fSMiklos Szeredi ibuf->len -= obuf->len; 2036dd3bb14fSMiklos Szeredi } 2037dd3bb14fSMiklos Szeredi nbuf++; 2038dd3bb14fSMiklos Szeredi rem -= obuf->len; 2039dd3bb14fSMiklos Szeredi } 2040dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 2041dd3bb14fSMiklos Szeredi 2042dc00809aSMiklos Szeredi fuse_copy_init(&cs, 0, NULL); 2043dd3bb14fSMiklos Szeredi cs.pipebufs = bufs; 20446c09e94aSAl Viro cs.nr_segs = nbuf; 2045dd3bb14fSMiklos Szeredi cs.pipe = pipe; 2046dd3bb14fSMiklos Szeredi 2047ce534fb0SMiklos Szeredi if (flags & SPLICE_F_MOVE) 2048ce534fb0SMiklos Szeredi cs.move_pages = 1; 2049ce534fb0SMiklos Szeredi 2050dd3bb14fSMiklos Szeredi ret = fuse_dev_do_write(fc, &cs, len); 2051dd3bb14fSMiklos Szeredi 2052dd3bb14fSMiklos Szeredi for (idx = 0; idx < nbuf; idx++) { 2053dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = &bufs[idx]; 2054dd3bb14fSMiklos Szeredi buf->ops->release(pipe, buf); 2055dd3bb14fSMiklos Szeredi } 2056dd3bb14fSMiklos Szeredi out: 2057dd3bb14fSMiklos Szeredi kfree(bufs); 2058dd3bb14fSMiklos Szeredi return ret; 2059dd3bb14fSMiklos Szeredi } 2060dd3bb14fSMiklos Szeredi 2061334f485dSMiklos Szeredi static unsigned fuse_dev_poll(struct file *file, poll_table *wait) 2062334f485dSMiklos Szeredi { 2063334f485dSMiklos Szeredi unsigned mask = POLLOUT | POLLWRNORM; 2064f88996a9SMiklos Szeredi struct fuse_iqueue *fiq; 20657025d9adSMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 2066334f485dSMiklos Szeredi if (!fc) 20677025d9adSMiklos Szeredi return POLLERR; 2068334f485dSMiklos Szeredi 2069f88996a9SMiklos Szeredi fiq = &fc->iq; 2070f88996a9SMiklos Szeredi poll_wait(file, &fiq->waitq, wait); 2071334f485dSMiklos Szeredi 20724ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 2073e16714d8SMiklos Szeredi if (!fiq->connected) 20747025d9adSMiklos Szeredi mask = POLLERR; 2075f88996a9SMiklos Szeredi else if (request_pending(fiq)) 2076334f485dSMiklos Szeredi mask |= POLLIN | POLLRDNORM; 20774ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 2078334f485dSMiklos Szeredi 2079334f485dSMiklos Szeredi return mask; 2080334f485dSMiklos Szeredi } 2081334f485dSMiklos Szeredi 208269a53bf2SMiklos Szeredi /* 208369a53bf2SMiklos Szeredi * Abort all requests on the given list (pending or processing) 208469a53bf2SMiklos Szeredi * 2085d7133114SMiklos Szeredi * This function releases and reacquires fc->lock 208669a53bf2SMiklos Szeredi */ 2087334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head) 2088b9ca67b2SMiklos Szeredi __releases(fc->lock) 2089b9ca67b2SMiklos Szeredi __acquires(fc->lock) 2090334f485dSMiklos Szeredi { 2091334f485dSMiklos Szeredi while (!list_empty(head)) { 2092334f485dSMiklos Szeredi struct fuse_req *req; 2093334f485dSMiklos Szeredi req = list_entry(head->next, struct fuse_req, list); 2094334f485dSMiklos Szeredi req->out.h.error = -ECONNABORTED; 209533e14b4dSMiklos Szeredi clear_bit(FR_PENDING, &req->flags); 209633e14b4dSMiklos Szeredi clear_bit(FR_SENT, &req->flags); 2097f377cb79SMiklos Szeredi list_del_init(&req->list); 2098334f485dSMiklos Szeredi request_end(fc, req); 2099d7133114SMiklos Szeredi spin_lock(&fc->lock); 2100334f485dSMiklos Szeredi } 2101334f485dSMiklos Szeredi } 2102334f485dSMiklos Szeredi 2103357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc) 2104357ccf2bSBryan Green { 2105357ccf2bSBryan Green struct rb_node *p; 2106357ccf2bSBryan Green 2107357ccf2bSBryan Green p = rb_first(&fc->polled_files); 2108357ccf2bSBryan Green 2109357ccf2bSBryan Green while (p) { 2110357ccf2bSBryan Green struct fuse_file *ff; 2111357ccf2bSBryan Green ff = rb_entry(p, struct fuse_file, polled_node); 2112357ccf2bSBryan Green wake_up_interruptible_all(&ff->poll_wait); 2113357ccf2bSBryan Green 2114357ccf2bSBryan Green p = rb_next(p); 2115357ccf2bSBryan Green } 2116357ccf2bSBryan Green } 2117357ccf2bSBryan Green 211869a53bf2SMiklos Szeredi /* 211969a53bf2SMiklos Szeredi * Abort all requests. 212069a53bf2SMiklos Szeredi * 2121b716d425SMiklos Szeredi * Emergency exit in case of a malicious or accidental deadlock, or just a hung 2122b716d425SMiklos Szeredi * filesystem. 212369a53bf2SMiklos Szeredi * 2124b716d425SMiklos Szeredi * The same effect is usually achievable through killing the filesystem daemon 2125b716d425SMiklos Szeredi * and all users of the filesystem. The exception is the combination of an 2126b716d425SMiklos Szeredi * asynchronous request and the tricky deadlock (see 2127b716d425SMiklos Szeredi * Documentation/filesystems/fuse.txt). 212869a53bf2SMiklos Szeredi * 2129b716d425SMiklos Szeredi * Aborting requests under I/O goes as follows: 1: Separate out unlocked 2130b716d425SMiklos Szeredi * requests, they should be finished off immediately. Locked requests will be 2131b716d425SMiklos Szeredi * finished after unlock; see unlock_request(). 2: Finish off the unlocked 2132b716d425SMiklos Szeredi * requests. It is possible that some request will finish before we can. This 2133b716d425SMiklos Szeredi * is OK, the request will in that case be removed from the list before we touch 2134b716d425SMiklos Szeredi * it. 213569a53bf2SMiklos Szeredi */ 213669a53bf2SMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc) 213769a53bf2SMiklos Szeredi { 2138f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 21393a2b5b9cSMiklos Szeredi struct fuse_pqueue *fpq = &fc->pq; 2140f88996a9SMiklos Szeredi 2141d7133114SMiklos Szeredi spin_lock(&fc->lock); 214269a53bf2SMiklos Szeredi if (fc->connected) { 2143b716d425SMiklos Szeredi struct fuse_req *req, *next; 214441f98274SMiklos Szeredi LIST_HEAD(to_end1); 214541f98274SMiklos Szeredi LIST_HEAD(to_end2); 2146b716d425SMiklos Szeredi 214769a53bf2SMiklos Szeredi fc->connected = 0; 214851eb01e7SMiklos Szeredi fc->blocked = 0; 21499759bd51SMiklos Szeredi fuse_set_initialized(fc); 215045a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 2151e96edd94SMiklos Szeredi fpq->connected = 0; 21523a2b5b9cSMiklos Szeredi list_for_each_entry_safe(req, next, &fpq->io, list) { 2153b716d425SMiklos Szeredi req->out.h.error = -ECONNABORTED; 2154b716d425SMiklos Szeredi spin_lock(&req->waitq.lock); 2155b716d425SMiklos Szeredi set_bit(FR_ABORTED, &req->flags); 215677cd9d48SMiklos Szeredi if (!test_bit(FR_LOCKED, &req->flags)) { 215777cd9d48SMiklos Szeredi set_bit(FR_PRIVATE, &req->flags); 215841f98274SMiklos Szeredi list_move(&req->list, &to_end1); 215977cd9d48SMiklos Szeredi } 2160b716d425SMiklos Szeredi spin_unlock(&req->waitq.lock); 2161b716d425SMiklos Szeredi } 216224b4d33dSMiklos Szeredi list_splice_init(&fpq->processing, &to_end2); 216345a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 216441f98274SMiklos Szeredi fc->max_background = UINT_MAX; 216541f98274SMiklos Szeredi flush_bg_queue(fc); 21668c91189aSMiklos Szeredi 21674ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 21688c91189aSMiklos Szeredi fiq->connected = 0; 2169f88996a9SMiklos Szeredi list_splice_init(&fiq->pending, &to_end2); 21708c91189aSMiklos Szeredi while (forget_pending(fiq)) 21718c91189aSMiklos Szeredi kfree(dequeue_forget(fiq, 1, NULL)); 21724ce60812SMiklos Szeredi wake_up_all_locked(&fiq->waitq); 21734ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 21748c91189aSMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 21758c91189aSMiklos Szeredi 217641f98274SMiklos Szeredi while (!list_empty(&to_end1)) { 217741f98274SMiklos Szeredi req = list_first_entry(&to_end1, struct fuse_req, list); 2178b716d425SMiklos Szeredi __fuse_get_request(req); 2179f377cb79SMiklos Szeredi list_del_init(&req->list); 2180b716d425SMiklos Szeredi request_end(fc, req); 2181b716d425SMiklos Szeredi spin_lock(&fc->lock); 2182b716d425SMiklos Szeredi } 218341f98274SMiklos Szeredi end_requests(fc, &to_end2); 2184357ccf2bSBryan Green end_polls(fc); 218551eb01e7SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 218669a53bf2SMiklos Szeredi } 2187d7133114SMiklos Szeredi spin_unlock(&fc->lock); 218869a53bf2SMiklos Szeredi } 218908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn); 219069a53bf2SMiklos Szeredi 219108cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file) 2192334f485dSMiklos Szeredi { 21930720b315SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 2194334f485dSMiklos Szeredi if (fc) { 21953a2b5b9cSMiklos Szeredi WARN_ON(!list_empty(&fc->pq.io)); 2196f88996a9SMiklos Szeredi WARN_ON(fc->iq.fasync != NULL); 2197ccd0a0bdSMiklos Szeredi fuse_abort_conn(fc); 2198bafa9654SMiklos Szeredi fuse_conn_put(fc); 2199385a17bfSJeff Dike } 2200f543f253SMiklos Szeredi 2201334f485dSMiklos Szeredi return 0; 2202334f485dSMiklos Szeredi } 220308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release); 2204334f485dSMiklos Szeredi 2205385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on) 2206385a17bfSJeff Dike { 2207385a17bfSJeff Dike struct fuse_conn *fc = fuse_get_conn(file); 2208385a17bfSJeff Dike if (!fc) 2209a87046d8SMiklos Szeredi return -EPERM; 2210385a17bfSJeff Dike 2211385a17bfSJeff Dike /* No locking - fasync_helper does its own locking */ 2212f88996a9SMiklos Szeredi return fasync_helper(fd, file, on, &fc->iq.fasync); 2213385a17bfSJeff Dike } 2214385a17bfSJeff Dike 22154b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = { 2216334f485dSMiklos Szeredi .owner = THIS_MODULE, 221794e4fe2cSTom Van Braeckel .open = fuse_dev_open, 2218334f485dSMiklos Szeredi .llseek = no_llseek, 2219fbdbaccaSAl Viro .read_iter = fuse_dev_read, 2220c3021629SMiklos Szeredi .splice_read = fuse_dev_splice_read, 2221fbdbaccaSAl Viro .write_iter = fuse_dev_write, 2222dd3bb14fSMiklos Szeredi .splice_write = fuse_dev_splice_write, 2223334f485dSMiklos Szeredi .poll = fuse_dev_poll, 2224334f485dSMiklos Szeredi .release = fuse_dev_release, 2225385a17bfSJeff Dike .fasync = fuse_dev_fasync, 2226334f485dSMiklos Szeredi }; 222708cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations); 2228334f485dSMiklos Szeredi 2229334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = { 2230334f485dSMiklos Szeredi .minor = FUSE_MINOR, 2231334f485dSMiklos Szeredi .name = "fuse", 2232334f485dSMiklos Szeredi .fops = &fuse_dev_operations, 2233334f485dSMiklos Szeredi }; 2234334f485dSMiklos Szeredi 2235334f485dSMiklos Szeredi int __init fuse_dev_init(void) 2236334f485dSMiklos Szeredi { 2237334f485dSMiklos Szeredi int err = -ENOMEM; 2238334f485dSMiklos Szeredi fuse_req_cachep = kmem_cache_create("fuse_request", 2239334f485dSMiklos Szeredi sizeof(struct fuse_req), 224020c2df83SPaul Mundt 0, 0, NULL); 2241334f485dSMiklos Szeredi if (!fuse_req_cachep) 2242334f485dSMiklos Szeredi goto out; 2243334f485dSMiklos Szeredi 2244334f485dSMiklos Szeredi err = misc_register(&fuse_miscdevice); 2245334f485dSMiklos Szeredi if (err) 2246334f485dSMiklos Szeredi goto out_cache_clean; 2247334f485dSMiklos Szeredi 2248334f485dSMiklos Szeredi return 0; 2249334f485dSMiklos Szeredi 2250334f485dSMiklos Szeredi out_cache_clean: 2251334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2252334f485dSMiklos Szeredi out: 2253334f485dSMiklos Szeredi return err; 2254334f485dSMiklos Szeredi } 2255334f485dSMiklos Szeredi 2256334f485dSMiklos Szeredi void fuse_dev_cleanup(void) 2257334f485dSMiklos Szeredi { 2258334f485dSMiklos Szeredi misc_deregister(&fuse_miscdevice); 2259334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2260334f485dSMiklos Szeredi } 2261