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> 14174cd4b1SIngo Molnar #include <linux/sched/signal.h> 15334f485dSMiklos Szeredi #include <linux/uio.h> 16334f485dSMiklos Szeredi #include <linux/miscdevice.h> 17334f485dSMiklos Szeredi #include <linux/pagemap.h> 18334f485dSMiklos Szeredi #include <linux/file.h> 19334f485dSMiklos Szeredi #include <linux/slab.h> 20dd3bb14fSMiklos Szeredi #include <linux/pipe_fs_i.h> 21ce534fb0SMiklos Szeredi #include <linux/swap.h> 22ce534fb0SMiklos Szeredi #include <linux/splice.h> 230b6e9ea0SSeth Forshee #include <linux/sched.h> 24334f485dSMiklos Szeredi 25334f485dSMiklos Szeredi MODULE_ALIAS_MISCDEV(FUSE_MINOR); 26578454ffSKay Sievers MODULE_ALIAS("devname:fuse"); 27334f485dSMiklos Szeredi 28c59fd85eSKirill Tkhai /* Ordinary requests have even IDs, while interrupts IDs are odd */ 29c59fd85eSKirill Tkhai #define FUSE_INT_REQ_BIT (1ULL << 0) 30c59fd85eSKirill Tkhai #define FUSE_REQ_ID_STEP (1ULL << 1) 31c59fd85eSKirill Tkhai 32e18b890bSChristoph Lameter static struct kmem_cache *fuse_req_cachep; 33334f485dSMiklos Szeredi 34cc080e9eSMiklos Szeredi static struct fuse_dev *fuse_get_dev(struct file *file) 35334f485dSMiklos Szeredi { 360720b315SMiklos Szeredi /* 370720b315SMiklos Szeredi * Lockless access is OK, because file->private data is set 380720b315SMiklos Szeredi * once during mount and is valid until the file is released. 390720b315SMiklos Szeredi */ 406aa7de05SMark Rutland return READ_ONCE(file->private_data); 41334f485dSMiklos Szeredi } 42334f485dSMiklos Szeredi 434250c066SMaxim Patlasov static void fuse_request_init(struct fuse_req *req, struct page **pages, 44b2430d75SMaxim Patlasov struct fuse_page_desc *page_descs, 454250c066SMaxim Patlasov unsigned npages) 46334f485dSMiklos Szeredi { 47334f485dSMiklos Szeredi INIT_LIST_HEAD(&req->list); 48a4d27e75SMiklos Szeredi INIT_LIST_HEAD(&req->intr_entry); 49334f485dSMiklos Szeredi init_waitqueue_head(&req->waitq); 50ec99f6d3SElena Reshetova refcount_set(&req->count, 1); 514250c066SMaxim Patlasov req->pages = pages; 52b2430d75SMaxim Patlasov req->page_descs = page_descs; 534250c066SMaxim Patlasov req->max_pages = npages; 5433e14b4dSMiklos Szeredi __set_bit(FR_PENDING, &req->flags); 55334f485dSMiklos Szeredi } 56334f485dSMiklos Szeredi 57e52a8250SMiklos Szeredi static struct page **fuse_req_pages_alloc(unsigned int npages, gfp_t flags, 58e52a8250SMiklos Szeredi struct fuse_page_desc **desc) 59e52a8250SMiklos Szeredi { 60e52a8250SMiklos Szeredi struct page **pages; 61e52a8250SMiklos Szeredi 62e52a8250SMiklos Szeredi pages = kzalloc(npages * (sizeof(struct page *) + 63e52a8250SMiklos Szeredi sizeof(struct fuse_page_desc)), flags); 64e52a8250SMiklos Szeredi *desc = (void *) pages + npages * sizeof(struct page *); 65e52a8250SMiklos Szeredi 66e52a8250SMiklos Szeredi return pages; 67e52a8250SMiklos Szeredi } 68e52a8250SMiklos Szeredi 694250c066SMaxim Patlasov static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) 70334f485dSMiklos Szeredi { 718a7aa286SMiklos Szeredi struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags); 724250c066SMaxim Patlasov if (req) { 738a7aa286SMiklos Szeredi struct page **pages = NULL; 748a7aa286SMiklos Szeredi struct fuse_page_desc *page_descs = NULL; 754250c066SMaxim Patlasov 765da784ccSConstantine Shulyupin WARN_ON(npages > FUSE_MAX_MAX_PAGES); 778a7aa286SMiklos Szeredi if (npages > FUSE_REQ_INLINE_PAGES) { 78e52a8250SMiklos Szeredi pages = fuse_req_pages_alloc(npages, flags, 79e52a8250SMiklos Szeredi &page_descs); 808a7aa286SMiklos Szeredi if (!pages) { 814250c066SMaxim Patlasov kmem_cache_free(fuse_req_cachep, req); 824250c066SMaxim Patlasov return NULL; 834250c066SMaxim Patlasov } 848a7aa286SMiklos Szeredi } else if (npages) { 858a7aa286SMiklos Szeredi pages = req->inline_pages; 868a7aa286SMiklos Szeredi page_descs = req->inline_page_descs; 878a7aa286SMiklos Szeredi } 884250c066SMaxim Patlasov 89b2430d75SMaxim Patlasov fuse_request_init(req, pages, page_descs, npages); 904250c066SMaxim Patlasov } 91334f485dSMiklos Szeredi return req; 92334f485dSMiklos Szeredi } 934250c066SMaxim Patlasov 944250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc(unsigned npages) 954250c066SMaxim Patlasov { 964250c066SMaxim Patlasov return __fuse_request_alloc(npages, GFP_KERNEL); 974250c066SMaxim Patlasov } 9808cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_alloc); 99334f485dSMiklos Szeredi 1004250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc_nofs(unsigned npages) 1013be5a52bSMiklos Szeredi { 1024250c066SMaxim Patlasov return __fuse_request_alloc(npages, GFP_NOFS); 1033be5a52bSMiklos Szeredi } 1043be5a52bSMiklos Szeredi 105e52a8250SMiklos Szeredi static void fuse_req_pages_free(struct fuse_req *req) 106334f485dSMiklos Szeredi { 1078a7aa286SMiklos Szeredi if (req->pages != req->inline_pages) 1084250c066SMaxim Patlasov kfree(req->pages); 109e52a8250SMiklos Szeredi } 1108a7aa286SMiklos Szeredi 111e52a8250SMiklos Szeredi bool fuse_req_realloc_pages(struct fuse_conn *fc, struct fuse_req *req, 112e52a8250SMiklos Szeredi gfp_t flags) 113e52a8250SMiklos Szeredi { 114e52a8250SMiklos Szeredi struct page **pages; 115e52a8250SMiklos Szeredi struct fuse_page_desc *page_descs; 116e52a8250SMiklos Szeredi unsigned int npages = min_t(unsigned int, 117e52a8250SMiklos Szeredi max_t(unsigned int, req->max_pages * 2, 118e52a8250SMiklos Szeredi FUSE_DEFAULT_MAX_PAGES_PER_REQ), 119e52a8250SMiklos Szeredi fc->max_pages); 120e52a8250SMiklos Szeredi WARN_ON(npages <= req->max_pages); 121e52a8250SMiklos Szeredi 122e52a8250SMiklos Szeredi pages = fuse_req_pages_alloc(npages, flags, &page_descs); 123e52a8250SMiklos Szeredi if (!pages) 124e52a8250SMiklos Szeredi return false; 125e52a8250SMiklos Szeredi 126e52a8250SMiklos Szeredi memcpy(pages, req->pages, sizeof(struct page *) * req->max_pages); 127e52a8250SMiklos Szeredi memcpy(page_descs, req->page_descs, 128e52a8250SMiklos Szeredi sizeof(struct fuse_page_desc) * req->max_pages); 129e52a8250SMiklos Szeredi fuse_req_pages_free(req); 130e52a8250SMiklos Szeredi req->pages = pages; 131e52a8250SMiklos Szeredi req->page_descs = page_descs; 132e52a8250SMiklos Szeredi req->max_pages = npages; 133e52a8250SMiklos Szeredi 134e52a8250SMiklos Szeredi return true; 135e52a8250SMiklos Szeredi } 136e52a8250SMiklos Szeredi 137e52a8250SMiklos Szeredi void fuse_request_free(struct fuse_req *req) 138e52a8250SMiklos Szeredi { 139e52a8250SMiklos Szeredi fuse_req_pages_free(req); 140334f485dSMiklos Szeredi kmem_cache_free(fuse_req_cachep, req); 141334f485dSMiklos Szeredi } 142334f485dSMiklos Szeredi 14336cf66edSMaxim Patlasov void __fuse_get_request(struct fuse_req *req) 144334f485dSMiklos Szeredi { 145ec99f6d3SElena Reshetova refcount_inc(&req->count); 146334f485dSMiklos Szeredi } 147334f485dSMiklos Szeredi 148334f485dSMiklos Szeredi /* Must be called with > 1 refcount */ 149334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req) 150334f485dSMiklos Szeredi { 151ec99f6d3SElena Reshetova refcount_dec(&req->count); 152334f485dSMiklos Szeredi } 153334f485dSMiklos Szeredi 1549759bd51SMiklos Szeredi void fuse_set_initialized(struct fuse_conn *fc) 1559759bd51SMiklos Szeredi { 1569759bd51SMiklos Szeredi /* Make sure stores before this are seen on another CPU */ 1579759bd51SMiklos Szeredi smp_wmb(); 1589759bd51SMiklos Szeredi fc->initialized = 1; 1599759bd51SMiklos Szeredi } 1609759bd51SMiklos Szeredi 1610aada884SMaxim Patlasov static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background) 1620aada884SMaxim Patlasov { 1630aada884SMaxim Patlasov return !fc->initialized || (for_background && fc->blocked); 1640aada884SMaxim Patlasov } 1650aada884SMaxim Patlasov 166b8f95e5dSMiklos Szeredi static void fuse_drop_waiting(struct fuse_conn *fc) 167b8f95e5dSMiklos Szeredi { 1682d84a2d1SMiklos Szeredi /* 1692d84a2d1SMiklos Szeredi * lockess check of fc->connected is okay, because atomic_dec_and_test() 1702d84a2d1SMiklos Szeredi * provides a memory barrier mached with the one in fuse_wait_aborted() 1712d84a2d1SMiklos Szeredi * to ensure no wake-up is missed. 1722d84a2d1SMiklos Szeredi */ 1732d84a2d1SMiklos Szeredi if (atomic_dec_and_test(&fc->num_waiting) && 1742d84a2d1SMiklos Szeredi !READ_ONCE(fc->connected)) { 175b8f95e5dSMiklos Szeredi /* wake up aborters */ 176b8f95e5dSMiklos Szeredi wake_up_all(&fc->blocked_waitq); 177b8f95e5dSMiklos Szeredi } 178b8f95e5dSMiklos Szeredi } 179b8f95e5dSMiklos Szeredi 1808b41e671SMaxim Patlasov static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages, 1818b41e671SMaxim Patlasov bool for_background) 182334f485dSMiklos Szeredi { 18308a53cdcSMiklos Szeredi struct fuse_req *req; 1840aada884SMaxim Patlasov int err; 1850aada884SMaxim Patlasov atomic_inc(&fc->num_waiting); 1860aada884SMaxim Patlasov 1870aada884SMaxim Patlasov if (fuse_block_alloc(fc, for_background)) { 1889bc5dddaSMiklos Szeredi err = -EINTR; 1897d3a07fcSAl Viro if (wait_event_killable_exclusive(fc->blocked_waitq, 1907d3a07fcSAl Viro !fuse_block_alloc(fc, for_background))) 1919bc5dddaSMiklos Szeredi goto out; 1920aada884SMaxim Patlasov } 1939759bd51SMiklos Szeredi /* Matches smp_wmb() in fuse_set_initialized() */ 1949759bd51SMiklos Szeredi smp_rmb(); 19508a53cdcSMiklos Szeredi 19651eb01e7SMiklos Szeredi err = -ENOTCONN; 19751eb01e7SMiklos Szeredi if (!fc->connected) 19851eb01e7SMiklos Szeredi goto out; 19951eb01e7SMiklos Szeredi 200de155226SMiklos Szeredi err = -ECONNREFUSED; 201de155226SMiklos Szeredi if (fc->conn_error) 202de155226SMiklos Szeredi goto out; 203de155226SMiklos Szeredi 204b111c8c0SMaxim Patlasov req = fuse_request_alloc(npages); 2059bc5dddaSMiklos Szeredi err = -ENOMEM; 206722d2beaSMaxim Patlasov if (!req) { 207722d2beaSMaxim Patlasov if (for_background) 208722d2beaSMaxim Patlasov wake_up(&fc->blocked_waitq); 2099bc5dddaSMiklos Szeredi goto out; 210722d2beaSMaxim Patlasov } 211334f485dSMiklos Szeredi 2128cb08329SEric W. Biederman req->in.h.uid = from_kuid(fc->user_ns, current_fsuid()); 2138cb08329SEric W. Biederman req->in.h.gid = from_kgid(fc->user_ns, current_fsgid()); 214c9582eb0SEric W. Biederman req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns); 215c9582eb0SEric W. Biederman 216825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 217825d6d33SMiklos Szeredi if (for_background) 218825d6d33SMiklos Szeredi __set_bit(FR_BACKGROUND, &req->flags); 219825d6d33SMiklos Szeredi 220c9582eb0SEric W. Biederman if (unlikely(req->in.h.uid == ((uid_t)-1) || 221c9582eb0SEric W. Biederman req->in.h.gid == ((gid_t)-1))) { 222c9582eb0SEric W. Biederman fuse_put_request(fc, req); 223c9582eb0SEric W. Biederman return ERR_PTR(-EOVERFLOW); 224c9582eb0SEric W. Biederman } 225334f485dSMiklos Szeredi return req; 2269bc5dddaSMiklos Szeredi 2279bc5dddaSMiklos Szeredi out: 228b8f95e5dSMiklos Szeredi fuse_drop_waiting(fc); 2299bc5dddaSMiklos Szeredi return ERR_PTR(err); 230334f485dSMiklos Szeredi } 2318b41e671SMaxim Patlasov 2328b41e671SMaxim Patlasov struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages) 2338b41e671SMaxim Patlasov { 2348b41e671SMaxim Patlasov return __fuse_get_req(fc, npages, false); 2358b41e671SMaxim Patlasov } 23608cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_get_req); 237334f485dSMiklos Szeredi 2388b41e671SMaxim Patlasov struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc, 2398b41e671SMaxim Patlasov unsigned npages) 2408b41e671SMaxim Patlasov { 2418b41e671SMaxim Patlasov return __fuse_get_req(fc, npages, true); 2428b41e671SMaxim Patlasov } 2438b41e671SMaxim Patlasov EXPORT_SYMBOL_GPL(fuse_get_req_for_background); 2448b41e671SMaxim Patlasov 24533649c91SMiklos Szeredi /* 24633649c91SMiklos Szeredi * Return request in fuse_file->reserved_req. However that may 24733649c91SMiklos Szeredi * currently be in use. If that is the case, wait for it to become 24833649c91SMiklos Szeredi * available. 24933649c91SMiklos Szeredi */ 25033649c91SMiklos Szeredi static struct fuse_req *get_reserved_req(struct fuse_conn *fc, 25133649c91SMiklos Szeredi struct file *file) 25233649c91SMiklos Szeredi { 25333649c91SMiklos Szeredi struct fuse_req *req = NULL; 2546b675738SKirill Tkhai struct fuse_inode *fi = get_fuse_inode(file_inode(file)); 25533649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 25633649c91SMiklos Szeredi 25733649c91SMiklos Szeredi do { 258de5e3decSMiklos Szeredi wait_event(fc->reserved_req_waitq, ff->reserved_req); 2596b675738SKirill Tkhai spin_lock(&fi->lock); 26033649c91SMiklos Szeredi if (ff->reserved_req) { 26133649c91SMiklos Szeredi req = ff->reserved_req; 26233649c91SMiklos Szeredi ff->reserved_req = NULL; 263cb0942b8SAl Viro req->stolen_file = get_file(file); 26433649c91SMiklos Szeredi } 2656b675738SKirill Tkhai spin_unlock(&fi->lock); 26633649c91SMiklos Szeredi } while (!req); 26733649c91SMiklos Szeredi 26833649c91SMiklos Szeredi return req; 26933649c91SMiklos Szeredi } 27033649c91SMiklos Szeredi 27133649c91SMiklos Szeredi /* 27233649c91SMiklos Szeredi * Put stolen request back into fuse_file->reserved_req 27333649c91SMiklos Szeredi */ 27433649c91SMiklos Szeredi static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req) 27533649c91SMiklos Szeredi { 27633649c91SMiklos Szeredi struct file *file = req->stolen_file; 2776b675738SKirill Tkhai struct fuse_inode *fi = get_fuse_inode(file_inode(file)); 27833649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 27933649c91SMiklos Szeredi 2808a7aa286SMiklos Szeredi WARN_ON(req->max_pages); 2816b675738SKirill Tkhai spin_lock(&fi->lock); 2828a7aa286SMiklos Szeredi memset(req, 0, sizeof(*req)); 2838a7aa286SMiklos Szeredi fuse_request_init(req, NULL, NULL, 0); 28433649c91SMiklos Szeredi BUG_ON(ff->reserved_req); 28533649c91SMiklos Szeredi ff->reserved_req = req; 286de5e3decSMiklos Szeredi wake_up_all(&fc->reserved_req_waitq); 2876b675738SKirill Tkhai spin_unlock(&fi->lock); 28833649c91SMiklos Szeredi fput(file); 28933649c91SMiklos Szeredi } 29033649c91SMiklos Szeredi 29133649c91SMiklos Szeredi /* 29233649c91SMiklos Szeredi * Gets a requests for a file operation, always succeeds 29333649c91SMiklos Szeredi * 29433649c91SMiklos Szeredi * This is used for sending the FLUSH request, which must get to 29533649c91SMiklos Szeredi * userspace, due to POSIX locks which may need to be unlocked. 29633649c91SMiklos Szeredi * 29733649c91SMiklos Szeredi * If allocation fails due to OOM, use the reserved request in 29833649c91SMiklos Szeredi * fuse_file. 29933649c91SMiklos Szeredi * 30033649c91SMiklos Szeredi * This is very unlikely to deadlock accidentally, since the 30133649c91SMiklos Szeredi * filesystem should not have it's own file open. If deadlock is 30233649c91SMiklos Szeredi * intentional, it can still be broken by "aborting" the filesystem. 30333649c91SMiklos Szeredi */ 304b111c8c0SMaxim Patlasov struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, 305b111c8c0SMaxim Patlasov struct file *file) 30633649c91SMiklos Szeredi { 30733649c91SMiklos Szeredi struct fuse_req *req; 30833649c91SMiklos Szeredi 30933649c91SMiklos Szeredi atomic_inc(&fc->num_waiting); 3100aada884SMaxim Patlasov wait_event(fc->blocked_waitq, fc->initialized); 3119759bd51SMiklos Szeredi /* Matches smp_wmb() in fuse_set_initialized() */ 3129759bd51SMiklos Szeredi smp_rmb(); 313b111c8c0SMaxim Patlasov req = fuse_request_alloc(0); 31433649c91SMiklos Szeredi if (!req) 31533649c91SMiklos Szeredi req = get_reserved_req(fc, file); 31633649c91SMiklos Szeredi 3178cb08329SEric W. Biederman req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid()); 3188cb08329SEric W. Biederman req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid()); 319c9582eb0SEric W. Biederman req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns); 320c9582eb0SEric W. Biederman 321825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 322825d6d33SMiklos Szeredi __clear_bit(FR_BACKGROUND, &req->flags); 32333649c91SMiklos Szeredi return req; 32433649c91SMiklos Szeredi } 32533649c91SMiklos Szeredi 326334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) 327334f485dSMiklos Szeredi { 328ec99f6d3SElena Reshetova if (refcount_dec_and_test(&req->count)) { 329825d6d33SMiklos Szeredi if (test_bit(FR_BACKGROUND, &req->flags)) { 330722d2beaSMaxim Patlasov /* 331722d2beaSMaxim Patlasov * We get here in the unlikely case that a background 332722d2beaSMaxim Patlasov * request was allocated but not sent 333722d2beaSMaxim Patlasov */ 334ae2dffa3SKirill Tkhai spin_lock(&fc->bg_lock); 335722d2beaSMaxim Patlasov if (!fc->blocked) 336722d2beaSMaxim Patlasov wake_up(&fc->blocked_waitq); 337ae2dffa3SKirill Tkhai spin_unlock(&fc->bg_lock); 338722d2beaSMaxim Patlasov } 339722d2beaSMaxim Patlasov 340825d6d33SMiklos Szeredi if (test_bit(FR_WAITING, &req->flags)) { 341825d6d33SMiklos Szeredi __clear_bit(FR_WAITING, &req->flags); 342b8f95e5dSMiklos Szeredi fuse_drop_waiting(fc); 34373e0e738SMiklos Szeredi } 34433649c91SMiklos Szeredi 34533649c91SMiklos Szeredi if (req->stolen_file) 34633649c91SMiklos Szeredi put_reserved_req(fc, req); 34733649c91SMiklos Szeredi else 348ce1d5a49SMiklos Szeredi fuse_request_free(req); 3497128ec2aSMiklos Szeredi } 3507128ec2aSMiklos Szeredi } 35108cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_put_request); 3527128ec2aSMiklos Szeredi 353d12def1bSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args) 354d12def1bSMiklos Szeredi { 355d12def1bSMiklos Szeredi unsigned nbytes = 0; 356d12def1bSMiklos Szeredi unsigned i; 357d12def1bSMiklos Szeredi 358d12def1bSMiklos Szeredi for (i = 0; i < numargs; i++) 359d12def1bSMiklos Szeredi nbytes += args[i].size; 360d12def1bSMiklos Szeredi 361d12def1bSMiklos Szeredi return nbytes; 362d12def1bSMiklos Szeredi } 363d12def1bSMiklos Szeredi 364f88996a9SMiklos Szeredi static u64 fuse_get_unique(struct fuse_iqueue *fiq) 365d12def1bSMiklos Szeredi { 366c59fd85eSKirill Tkhai fiq->reqctr += FUSE_REQ_ID_STEP; 367c59fd85eSKirill Tkhai return fiq->reqctr; 368d12def1bSMiklos Szeredi } 369d12def1bSMiklos Szeredi 370be2ff42cSKirill Tkhai static unsigned int fuse_req_hash(u64 unique) 371be2ff42cSKirill Tkhai { 372be2ff42cSKirill Tkhai return hash_long(unique & ~FUSE_INT_REQ_BIT, FUSE_PQ_HASH_BITS); 373be2ff42cSKirill Tkhai } 374be2ff42cSKirill Tkhai 375f88996a9SMiklos Szeredi static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req) 376d12def1bSMiklos Szeredi { 377d12def1bSMiklos Szeredi req->in.h.len = sizeof(struct fuse_in_header) + 378d12def1bSMiklos Szeredi len_args(req->in.numargs, (struct fuse_arg *) req->in.args); 379f88996a9SMiklos Szeredi list_add_tail(&req->list, &fiq->pending); 3804ce60812SMiklos Szeredi wake_up_locked(&fiq->waitq); 381f88996a9SMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 382d12def1bSMiklos Szeredi } 383d12def1bSMiklos Szeredi 38407e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, 38507e77dcaSMiklos Szeredi u64 nodeid, u64 nlookup) 38607e77dcaSMiklos Szeredi { 387f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 388f88996a9SMiklos Szeredi 38902c048b9SMiklos Szeredi forget->forget_one.nodeid = nodeid; 39002c048b9SMiklos Szeredi forget->forget_one.nlookup = nlookup; 39107e77dcaSMiklos Szeredi 3924ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 393e16714d8SMiklos Szeredi if (fiq->connected) { 394f88996a9SMiklos Szeredi fiq->forget_list_tail->next = forget; 395f88996a9SMiklos Szeredi fiq->forget_list_tail = forget; 3964ce60812SMiklos Szeredi wake_up_locked(&fiq->waitq); 397f88996a9SMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 3985dfcc87fSMiklos Szeredi } else { 3995dfcc87fSMiklos Szeredi kfree(forget); 4005dfcc87fSMiklos Szeredi } 4014ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 40207e77dcaSMiklos Szeredi } 40307e77dcaSMiklos Szeredi 404d12def1bSMiklos Szeredi static void flush_bg_queue(struct fuse_conn *fc) 405d12def1bSMiklos Szeredi { 406e287179aSKirill Tkhai struct fuse_iqueue *fiq = &fc->iq; 407e287179aSKirill Tkhai 4087a6d3c8bSCsaba Henk while (fc->active_background < fc->max_background && 409d12def1bSMiklos Szeredi !list_empty(&fc->bg_queue)) { 410d12def1bSMiklos Szeredi struct fuse_req *req; 411d12def1bSMiklos Szeredi 412e287179aSKirill Tkhai req = list_first_entry(&fc->bg_queue, struct fuse_req, list); 413d12def1bSMiklos Szeredi list_del(&req->list); 414d12def1bSMiklos Szeredi fc->active_background++; 4154ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 416f88996a9SMiklos Szeredi req->in.h.unique = fuse_get_unique(fiq); 417f88996a9SMiklos Szeredi queue_request(fiq, req); 4184ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 419d12def1bSMiklos Szeredi } 420d12def1bSMiklos Szeredi } 421d12def1bSMiklos Szeredi 4226dbbcb12SMiklos Szeredi /* 423334f485dSMiklos Szeredi * This function is called when a request is finished. Either a reply 424f9a2842eSMiklos Szeredi * has arrived or it was aborted (and not yet sent) or some error 425f43b155aSMiklos Szeredi * occurred during communication with userspace, or the device file 42651eb01e7SMiklos Szeredi * was closed. The requester thread is woken up (if still waiting), 42751eb01e7SMiklos Szeredi * the 'end' callback is called if given, else the reference to the 42851eb01e7SMiklos Szeredi * request is released 429334f485dSMiklos Szeredi */ 430334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req) 431334f485dSMiklos Szeredi { 4324ce60812SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 433365ae710SMiklos Szeredi 434efe2800fSMiklos Szeredi if (test_and_set_bit(FR_FINISHED, &req->flags)) 435b8f95e5dSMiklos Szeredi goto put_request; 436217316a6SKirill Tkhai /* 437217316a6SKirill Tkhai * test_and_set_bit() implies smp_mb() between bit 438217316a6SKirill Tkhai * changing and below intr_entry check. Pairs with 439217316a6SKirill Tkhai * smp_mb() from queue_interrupt(). 440217316a6SKirill Tkhai */ 441217316a6SKirill Tkhai if (!list_empty(&req->intr_entry)) { 4424ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 4430d8e84b0SMiklos Szeredi list_del_init(&req->intr_entry); 4444ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 445217316a6SKirill Tkhai } 44633e14b4dSMiklos Szeredi WARN_ON(test_bit(FR_PENDING, &req->flags)); 44733e14b4dSMiklos Szeredi WARN_ON(test_bit(FR_SENT, &req->flags)); 448825d6d33SMiklos Szeredi if (test_bit(FR_BACKGROUND, &req->flags)) { 449ae2dffa3SKirill Tkhai spin_lock(&fc->bg_lock); 450825d6d33SMiklos Szeredi clear_bit(FR_BACKGROUND, &req->flags); 451908a572bSMiklos Szeredi if (fc->num_background == fc->max_background) { 45251eb01e7SMiklos Szeredi fc->blocked = 0; 453722d2beaSMaxim Patlasov wake_up(&fc->blocked_waitq); 454908a572bSMiklos Szeredi } else if (!fc->blocked) { 455908a572bSMiklos Szeredi /* 456908a572bSMiklos Szeredi * Wake up next waiter, if any. It's okay to use 457908a572bSMiklos Szeredi * waitqueue_active(), as we've already synced up 458908a572bSMiklos Szeredi * fc->blocked with waiters with the wake_up() call 459908a572bSMiklos Szeredi * above. 460908a572bSMiklos Szeredi */ 461908a572bSMiklos Szeredi if (waitqueue_active(&fc->blocked_waitq)) 462908a572bSMiklos Szeredi wake_up(&fc->blocked_waitq); 463908a572bSMiklos Szeredi } 464722d2beaSMaxim Patlasov 4658a301eb1STejun Heo if (fc->num_background == fc->congestion_threshold && fc->sb) { 4665f7f7543SJan Kara clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); 4675f7f7543SJan Kara clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); 468f92b99b9SMiklos Szeredi } 46951eb01e7SMiklos Szeredi fc->num_background--; 470d12def1bSMiklos Szeredi fc->active_background--; 471d12def1bSMiklos Szeredi flush_bg_queue(fc); 472ae2dffa3SKirill Tkhai spin_unlock(&fc->bg_lock); 4735e0fed71SKirill Tkhai } else { 4745e0fed71SKirill Tkhai /* Wake up waiter sleeping in request_wait_answer() */ 47551eb01e7SMiklos Szeredi wake_up(&req->waitq); 4765e0fed71SKirill Tkhai } 4775e0fed71SKirill Tkhai 4781e6881c3SMiklos Szeredi if (req->end) 4791e6881c3SMiklos Szeredi req->end(fc, req); 480b8f95e5dSMiklos Szeredi put_request: 481f43b155aSMiklos Szeredi fuse_put_request(fc, req); 482334f485dSMiklos Szeredi } 483334f485dSMiklos Szeredi 484b782911bSKirill Tkhai static int queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req) 485a4d27e75SMiklos Szeredi { 4864ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 487b782911bSKirill Tkhai /* Check for we've sent request to interrupt this req */ 488b782911bSKirill Tkhai if (unlikely(!test_bit(FR_INTERRUPTED, &req->flags))) { 489b782911bSKirill Tkhai spin_unlock(&fiq->waitq.lock); 490b782911bSKirill Tkhai return -EINVAL; 491b782911bSKirill Tkhai } 492b782911bSKirill Tkhai 493217316a6SKirill Tkhai if (list_empty(&req->intr_entry)) { 494217316a6SKirill Tkhai list_add_tail(&req->intr_entry, &fiq->interrupts); 495217316a6SKirill Tkhai /* 496217316a6SKirill Tkhai * Pairs with smp_mb() implied by test_and_set_bit() 497217316a6SKirill Tkhai * from request_end(). 498217316a6SKirill Tkhai */ 499217316a6SKirill Tkhai smp_mb(); 5006ba4d272SSahitya Tummala if (test_bit(FR_FINISHED, &req->flags)) { 501217316a6SKirill Tkhai list_del_init(&req->intr_entry); 5026ba4d272SSahitya Tummala spin_unlock(&fiq->waitq.lock); 503b782911bSKirill Tkhai return 0; 5046ba4d272SSahitya Tummala } 5054ce60812SMiklos Szeredi wake_up_locked(&fiq->waitq); 5068da6e918SKirill Tkhai kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 5078f7bb368SMiklos Szeredi } 5084ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 509b782911bSKirill Tkhai return 0; 510a4d27e75SMiklos Szeredi } 511a4d27e75SMiklos Szeredi 5127c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) 513334f485dSMiklos Szeredi { 5144ce60812SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 515c4775267SMiklos Szeredi int err; 516c4775267SMiklos Szeredi 517a4d27e75SMiklos Szeredi if (!fc->no_interrupt) { 518a4d27e75SMiklos Szeredi /* Any signal may interrupt this */ 519c4775267SMiklos Szeredi err = wait_event_interruptible(req->waitq, 52033e14b4dSMiklos Szeredi test_bit(FR_FINISHED, &req->flags)); 521c4775267SMiklos Szeredi if (!err) 522334f485dSMiklos Szeredi return; 523334f485dSMiklos Szeredi 524825d6d33SMiklos Szeredi set_bit(FR_INTERRUPTED, &req->flags); 5258f7bb368SMiklos Szeredi /* matches barrier in fuse_dev_do_read() */ 5268f7bb368SMiklos Szeredi smp_mb__after_atomic(); 52733e14b4dSMiklos Szeredi if (test_bit(FR_SENT, &req->flags)) 5284ce60812SMiklos Szeredi queue_interrupt(fiq, req); 529a4d27e75SMiklos Szeredi } 530a4d27e75SMiklos Szeredi 531825d6d33SMiklos Szeredi if (!test_bit(FR_FORCE, &req->flags)) { 532a4d27e75SMiklos Szeredi /* Only fatal signals may interrupt this */ 5337d3a07fcSAl Viro err = wait_event_killable(req->waitq, 53433e14b4dSMiklos Szeredi test_bit(FR_FINISHED, &req->flags)); 535c4775267SMiklos Szeredi if (!err) 536a4d27e75SMiklos Szeredi return; 537a4d27e75SMiklos Szeredi 5384ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 539a131de0aSMiklos Szeredi /* Request is not yet in userspace, bail out */ 54033e14b4dSMiklos Szeredi if (test_bit(FR_PENDING, &req->flags)) { 541a131de0aSMiklos Szeredi list_del(&req->list); 5424ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 543a131de0aSMiklos Szeredi __fuse_put_request(req); 544334f485dSMiklos Szeredi req->out.h.error = -EINTR; 545a131de0aSMiklos Szeredi return; 546a131de0aSMiklos Szeredi } 5474ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 548a131de0aSMiklos Szeredi } 549a131de0aSMiklos Szeredi 550a131de0aSMiklos Szeredi /* 551a131de0aSMiklos Szeredi * Either request is already in userspace, or it was forced. 552a131de0aSMiklos Szeredi * Wait it out. 553a131de0aSMiklos Szeredi */ 55433e14b4dSMiklos Szeredi wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags)); 555334f485dSMiklos Szeredi } 556334f485dSMiklos Szeredi 5576a4e922cSEric Wong static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 558334f485dSMiklos Szeredi { 559e16714d8SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 560e16714d8SMiklos Szeredi 561825d6d33SMiklos Szeredi BUG_ON(test_bit(FR_BACKGROUND, &req->flags)); 5624ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 563e16714d8SMiklos Szeredi if (!fiq->connected) { 5644ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 565334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 566c4775267SMiklos Szeredi } else { 567f88996a9SMiklos Szeredi req->in.h.unique = fuse_get_unique(fiq); 568f88996a9SMiklos Szeredi queue_request(fiq, req); 569334f485dSMiklos Szeredi /* acquire extra reference, since request is still needed 570334f485dSMiklos Szeredi after request_end() */ 571334f485dSMiklos Szeredi __fuse_get_request(req); 5724ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 573334f485dSMiklos Szeredi 5747c352bdfSMiklos Szeredi request_wait_answer(fc, req); 575c4775267SMiklos Szeredi /* Pairs with smp_wmb() in request_end() */ 576c4775267SMiklos Szeredi smp_rmb(); 577334f485dSMiklos Szeredi } 578334f485dSMiklos Szeredi } 5796a4e922cSEric Wong 5806a4e922cSEric Wong void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 5816a4e922cSEric Wong { 582825d6d33SMiklos Szeredi __set_bit(FR_ISREPLY, &req->flags); 583825d6d33SMiklos Szeredi if (!test_bit(FR_WAITING, &req->flags)) { 584825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 5855437f241SMiklos Szeredi atomic_inc(&fc->num_waiting); 5865437f241SMiklos Szeredi } 5876a4e922cSEric Wong __fuse_request_send(fc, req); 5886a4e922cSEric Wong } 58908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send); 590334f485dSMiklos Szeredi 59121f62174SMiklos Szeredi static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args) 59221f62174SMiklos Szeredi { 59321f62174SMiklos Szeredi if (fc->minor < 4 && args->in.h.opcode == FUSE_STATFS) 59421f62174SMiklos Szeredi args->out.args[0].size = FUSE_COMPAT_STATFS_SIZE; 59521f62174SMiklos Szeredi 59621f62174SMiklos Szeredi if (fc->minor < 9) { 59721f62174SMiklos Szeredi switch (args->in.h.opcode) { 59821f62174SMiklos Szeredi case FUSE_LOOKUP: 59921f62174SMiklos Szeredi case FUSE_CREATE: 60021f62174SMiklos Szeredi case FUSE_MKNOD: 60121f62174SMiklos Szeredi case FUSE_MKDIR: 60221f62174SMiklos Szeredi case FUSE_SYMLINK: 60321f62174SMiklos Szeredi case FUSE_LINK: 60421f62174SMiklos Szeredi args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; 60521f62174SMiklos Szeredi break; 60621f62174SMiklos Szeredi case FUSE_GETATTR: 60721f62174SMiklos Szeredi case FUSE_SETATTR: 60821f62174SMiklos Szeredi args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; 60921f62174SMiklos Szeredi break; 61021f62174SMiklos Szeredi } 61121f62174SMiklos Szeredi } 61221f62174SMiklos Szeredi if (fc->minor < 12) { 61321f62174SMiklos Szeredi switch (args->in.h.opcode) { 61421f62174SMiklos Szeredi case FUSE_CREATE: 61521f62174SMiklos Szeredi args->in.args[0].size = sizeof(struct fuse_open_in); 61621f62174SMiklos Szeredi break; 61721f62174SMiklos Szeredi case FUSE_MKNOD: 61821f62174SMiklos Szeredi args->in.args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE; 61921f62174SMiklos Szeredi break; 62021f62174SMiklos Szeredi } 62121f62174SMiklos Szeredi } 62221f62174SMiklos Szeredi } 62321f62174SMiklos Szeredi 6247078187aSMiklos Szeredi ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) 6257078187aSMiklos Szeredi { 6267078187aSMiklos Szeredi struct fuse_req *req; 6277078187aSMiklos Szeredi ssize_t ret; 6287078187aSMiklos Szeredi 6297078187aSMiklos Szeredi req = fuse_get_req(fc, 0); 6307078187aSMiklos Szeredi if (IS_ERR(req)) 6317078187aSMiklos Szeredi return PTR_ERR(req); 6327078187aSMiklos Szeredi 63321f62174SMiklos Szeredi /* Needs to be done after fuse_get_req() so that fc->minor is valid */ 63421f62174SMiklos Szeredi fuse_adjust_compat(fc, args); 63521f62174SMiklos Szeredi 6367078187aSMiklos Szeredi req->in.h.opcode = args->in.h.opcode; 6377078187aSMiklos Szeredi req->in.h.nodeid = args->in.h.nodeid; 6387078187aSMiklos Szeredi req->in.numargs = args->in.numargs; 6397078187aSMiklos Szeredi memcpy(req->in.args, args->in.args, 6407078187aSMiklos Szeredi args->in.numargs * sizeof(struct fuse_in_arg)); 6417078187aSMiklos Szeredi req->out.argvar = args->out.argvar; 6427078187aSMiklos Szeredi req->out.numargs = args->out.numargs; 6437078187aSMiklos Szeredi memcpy(req->out.args, args->out.args, 6447078187aSMiklos Szeredi args->out.numargs * sizeof(struct fuse_arg)); 6457078187aSMiklos Szeredi fuse_request_send(fc, req); 6467078187aSMiklos Szeredi ret = req->out.h.error; 6477078187aSMiklos Szeredi if (!ret && args->out.argvar) { 6487078187aSMiklos Szeredi BUG_ON(args->out.numargs != 1); 6497078187aSMiklos Szeredi ret = req->out.args[0].size; 6507078187aSMiklos Szeredi } 6517078187aSMiklos Szeredi fuse_put_request(fc, req); 6527078187aSMiklos Szeredi 6537078187aSMiklos Szeredi return ret; 6547078187aSMiklos Szeredi } 6557078187aSMiklos Szeredi 65663825b4eSKirill Tkhai bool fuse_request_queue_background(struct fuse_conn *fc, struct fuse_req *req) 657334f485dSMiklos Szeredi { 65863825b4eSKirill Tkhai bool queued = false; 65963825b4eSKirill Tkhai 66063825b4eSKirill Tkhai WARN_ON(!test_bit(FR_BACKGROUND, &req->flags)); 661825d6d33SMiklos Szeredi if (!test_bit(FR_WAITING, &req->flags)) { 662825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 6635437f241SMiklos Szeredi atomic_inc(&fc->num_waiting); 6645437f241SMiklos Szeredi } 665825d6d33SMiklos Szeredi __set_bit(FR_ISREPLY, &req->flags); 666ae2dffa3SKirill Tkhai spin_lock(&fc->bg_lock); 66763825b4eSKirill Tkhai if (likely(fc->connected)) { 66851eb01e7SMiklos Szeredi fc->num_background++; 6697a6d3c8bSCsaba Henk if (fc->num_background == fc->max_background) 67051eb01e7SMiklos Szeredi fc->blocked = 1; 6717fbbe972SJan Kara if (fc->num_background == fc->congestion_threshold && fc->sb) { 6725f7f7543SJan Kara set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); 6735f7f7543SJan Kara set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); 674f92b99b9SMiklos Szeredi } 675d12def1bSMiklos Szeredi list_add_tail(&req->list, &fc->bg_queue); 676d12def1bSMiklos Szeredi flush_bg_queue(fc); 67763825b4eSKirill Tkhai queued = true; 67863825b4eSKirill Tkhai } 679ae2dffa3SKirill Tkhai spin_unlock(&fc->bg_lock); 68063825b4eSKirill Tkhai 68163825b4eSKirill Tkhai return queued; 682d12def1bSMiklos Szeredi } 68351eb01e7SMiklos Szeredi 684f0139aa8SMiklos Szeredi void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) 685d12def1bSMiklos Szeredi { 68663825b4eSKirill Tkhai WARN_ON(!req->end); 68763825b4eSKirill Tkhai if (!fuse_request_queue_background(fc, req)) { 688334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 68942dc6211SMiklos Szeredi req->end(fc, req); 69042dc6211SMiklos Szeredi fuse_put_request(fc, req); 691334f485dSMiklos Szeredi } 692334f485dSMiklos Szeredi } 69308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send_background); 694334f485dSMiklos Szeredi 6952d45ba38SMiklos Szeredi static int fuse_request_send_notify_reply(struct fuse_conn *fc, 6962d45ba38SMiklos Szeredi struct fuse_req *req, u64 unique) 6972d45ba38SMiklos Szeredi { 6982d45ba38SMiklos Szeredi int err = -ENODEV; 699f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 7002d45ba38SMiklos Szeredi 701825d6d33SMiklos Szeredi __clear_bit(FR_ISREPLY, &req->flags); 7022d45ba38SMiklos Szeredi req->in.h.unique = unique; 7034ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 704e16714d8SMiklos Szeredi if (fiq->connected) { 705f88996a9SMiklos Szeredi queue_request(fiq, req); 7062d45ba38SMiklos Szeredi err = 0; 7072d45ba38SMiklos Szeredi } 7084ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 7092d45ba38SMiklos Szeredi 7102d45ba38SMiklos Szeredi return err; 7112d45ba38SMiklos Szeredi } 7122d45ba38SMiklos Szeredi 7130b05b183SAnand V. Avati void fuse_force_forget(struct file *file, u64 nodeid) 7140b05b183SAnand V. Avati { 7156131ffaaSAl Viro struct inode *inode = file_inode(file); 7160b05b183SAnand V. Avati struct fuse_conn *fc = get_fuse_conn(inode); 7170b05b183SAnand V. Avati struct fuse_req *req; 7180b05b183SAnand V. Avati struct fuse_forget_in inarg; 7190b05b183SAnand V. Avati 7200b05b183SAnand V. Avati memset(&inarg, 0, sizeof(inarg)); 7210b05b183SAnand V. Avati inarg.nlookup = 1; 722b111c8c0SMaxim Patlasov req = fuse_get_req_nofail_nopages(fc, file); 7230b05b183SAnand V. Avati req->in.h.opcode = FUSE_FORGET; 7240b05b183SAnand V. Avati req->in.h.nodeid = nodeid; 7250b05b183SAnand V. Avati req->in.numargs = 1; 7260b05b183SAnand V. Avati req->in.args[0].size = sizeof(inarg); 7270b05b183SAnand V. Avati req->in.args[0].value = &inarg; 728825d6d33SMiklos Szeredi __clear_bit(FR_ISREPLY, &req->flags); 7296a4e922cSEric Wong __fuse_request_send(fc, req); 7306a4e922cSEric Wong /* ignore errors */ 7316a4e922cSEric Wong fuse_put_request(fc, req); 7320b05b183SAnand V. Avati } 7330b05b183SAnand V. Avati 7343be5a52bSMiklos Szeredi /* 735334f485dSMiklos Szeredi * Lock the request. Up to the next unlock_request() there mustn't be 736334f485dSMiklos Szeredi * anything that could cause a page-fault. If the request was already 737f9a2842eSMiklos Szeredi * aborted bail out. 738334f485dSMiklos Szeredi */ 739dc00809aSMiklos Szeredi static int lock_request(struct fuse_req *req) 740334f485dSMiklos Szeredi { 741334f485dSMiklos Szeredi int err = 0; 742334f485dSMiklos Szeredi if (req) { 743dc00809aSMiklos Szeredi spin_lock(&req->waitq.lock); 744825d6d33SMiklos Szeredi if (test_bit(FR_ABORTED, &req->flags)) 745334f485dSMiklos Szeredi err = -ENOENT; 746334f485dSMiklos Szeredi else 747825d6d33SMiklos Szeredi set_bit(FR_LOCKED, &req->flags); 748dc00809aSMiklos Szeredi spin_unlock(&req->waitq.lock); 749334f485dSMiklos Szeredi } 750334f485dSMiklos Szeredi return err; 751334f485dSMiklos Szeredi } 752334f485dSMiklos Szeredi 753334f485dSMiklos Szeredi /* 7540d8e84b0SMiklos Szeredi * Unlock request. If it was aborted while locked, caller is responsible 7550d8e84b0SMiklos Szeredi * for unlocking and ending the request. 756334f485dSMiklos Szeredi */ 757dc00809aSMiklos Szeredi static int unlock_request(struct fuse_req *req) 758334f485dSMiklos Szeredi { 7590d8e84b0SMiklos Szeredi int err = 0; 760334f485dSMiklos Szeredi if (req) { 761dc00809aSMiklos Szeredi spin_lock(&req->waitq.lock); 762825d6d33SMiklos Szeredi if (test_bit(FR_ABORTED, &req->flags)) 7630d8e84b0SMiklos Szeredi err = -ENOENT; 7640d8e84b0SMiklos Szeredi else 765825d6d33SMiklos Szeredi clear_bit(FR_LOCKED, &req->flags); 766dc00809aSMiklos Szeredi spin_unlock(&req->waitq.lock); 767334f485dSMiklos Szeredi } 7680d8e84b0SMiklos Szeredi return err; 769334f485dSMiklos Szeredi } 770334f485dSMiklos Szeredi 771334f485dSMiklos Szeredi struct fuse_copy_state { 772334f485dSMiklos Szeredi int write; 773334f485dSMiklos Szeredi struct fuse_req *req; 7746c09e94aSAl Viro struct iov_iter *iter; 775dd3bb14fSMiklos Szeredi struct pipe_buffer *pipebufs; 776dd3bb14fSMiklos Szeredi struct pipe_buffer *currbuf; 777dd3bb14fSMiklos Szeredi struct pipe_inode_info *pipe; 778334f485dSMiklos Szeredi unsigned long nr_segs; 779334f485dSMiklos Szeredi struct page *pg; 780334f485dSMiklos Szeredi unsigned len; 781c55a01d3SMiklos Szeredi unsigned offset; 782ce534fb0SMiklos Szeredi unsigned move_pages:1; 783334f485dSMiklos Szeredi }; 784334f485dSMiklos Szeredi 785dc00809aSMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, int write, 7866c09e94aSAl Viro struct iov_iter *iter) 787334f485dSMiklos Szeredi { 788334f485dSMiklos Szeredi memset(cs, 0, sizeof(*cs)); 789334f485dSMiklos Szeredi cs->write = write; 7906c09e94aSAl Viro cs->iter = iter; 791334f485dSMiklos Szeredi } 792334f485dSMiklos Szeredi 793334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */ 7948bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs) 795334f485dSMiklos Szeredi { 796dd3bb14fSMiklos Szeredi if (cs->currbuf) { 797dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->currbuf; 798dd3bb14fSMiklos Szeredi 799c55a01d3SMiklos Szeredi if (cs->write) 800c3021629SMiklos Szeredi buf->len = PAGE_SIZE - cs->len; 801dd3bb14fSMiklos Szeredi cs->currbuf = NULL; 802c55a01d3SMiklos Szeredi } else if (cs->pg) { 803334f485dSMiklos Szeredi if (cs->write) { 804334f485dSMiklos Szeredi flush_dcache_page(cs->pg); 805334f485dSMiklos Szeredi set_page_dirty_lock(cs->pg); 806334f485dSMiklos Szeredi } 807334f485dSMiklos Szeredi put_page(cs->pg); 808334f485dSMiklos Szeredi } 809c55a01d3SMiklos Szeredi cs->pg = NULL; 810334f485dSMiklos Szeredi } 811334f485dSMiklos Szeredi 812334f485dSMiklos Szeredi /* 813334f485dSMiklos Szeredi * Get another pagefull of userspace buffer, and map it to kernel 814334f485dSMiklos Szeredi * address space, and lock request 815334f485dSMiklos Szeredi */ 816334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs) 817334f485dSMiklos Szeredi { 818c55a01d3SMiklos Szeredi struct page *page; 819334f485dSMiklos Szeredi int err; 820334f485dSMiklos Szeredi 821dc00809aSMiklos Szeredi err = unlock_request(cs->req); 8220d8e84b0SMiklos Szeredi if (err) 8230d8e84b0SMiklos Szeredi return err; 8240d8e84b0SMiklos Szeredi 825334f485dSMiklos Szeredi fuse_copy_finish(cs); 826dd3bb14fSMiklos Szeredi if (cs->pipebufs) { 827dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 828dd3bb14fSMiklos Szeredi 829c3021629SMiklos Szeredi if (!cs->write) { 830fba597dbSMiklos Szeredi err = pipe_buf_confirm(cs->pipe, buf); 831dd3bb14fSMiklos Szeredi if (err) 832dd3bb14fSMiklos Szeredi return err; 833dd3bb14fSMiklos Szeredi 834dd3bb14fSMiklos Szeredi BUG_ON(!cs->nr_segs); 835dd3bb14fSMiklos Szeredi cs->currbuf = buf; 836c55a01d3SMiklos Szeredi cs->pg = buf->page; 837c55a01d3SMiklos Szeredi cs->offset = buf->offset; 838dd3bb14fSMiklos Szeredi cs->len = buf->len; 839dd3bb14fSMiklos Szeredi cs->pipebufs++; 840dd3bb14fSMiklos Szeredi cs->nr_segs--; 841dd3bb14fSMiklos Szeredi } else { 842c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 843c3021629SMiklos Szeredi return -EIO; 844c3021629SMiklos Szeredi 845c3021629SMiklos Szeredi page = alloc_page(GFP_HIGHUSER); 846c3021629SMiklos Szeredi if (!page) 847c3021629SMiklos Szeredi return -ENOMEM; 848c3021629SMiklos Szeredi 849c3021629SMiklos Szeredi buf->page = page; 850c3021629SMiklos Szeredi buf->offset = 0; 851c3021629SMiklos Szeredi buf->len = 0; 852c3021629SMiklos Szeredi 853c3021629SMiklos Szeredi cs->currbuf = buf; 854c55a01d3SMiklos Szeredi cs->pg = page; 855c55a01d3SMiklos Szeredi cs->offset = 0; 856c3021629SMiklos Szeredi cs->len = PAGE_SIZE; 857c3021629SMiklos Szeredi cs->pipebufs++; 858c3021629SMiklos Szeredi cs->nr_segs++; 859c3021629SMiklos Szeredi } 860c3021629SMiklos Szeredi } else { 8616c09e94aSAl Viro size_t off; 8626c09e94aSAl Viro err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off); 863334f485dSMiklos Szeredi if (err < 0) 864334f485dSMiklos Szeredi return err; 8656c09e94aSAl Viro BUG_ON(!err); 8666c09e94aSAl Viro cs->len = err; 8676c09e94aSAl Viro cs->offset = off; 868c55a01d3SMiklos Szeredi cs->pg = page; 8696c09e94aSAl Viro iov_iter_advance(cs->iter, err); 870dd3bb14fSMiklos Szeredi } 871334f485dSMiklos Szeredi 872dc00809aSMiklos Szeredi return lock_request(cs->req); 873334f485dSMiklos Szeredi } 874334f485dSMiklos Szeredi 875334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */ 8768bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size) 877334f485dSMiklos Szeredi { 878334f485dSMiklos Szeredi unsigned ncpy = min(*size, cs->len); 879334f485dSMiklos Szeredi if (val) { 880c55a01d3SMiklos Szeredi void *pgaddr = kmap_atomic(cs->pg); 881c55a01d3SMiklos Szeredi void *buf = pgaddr + cs->offset; 882c55a01d3SMiklos Szeredi 883334f485dSMiklos Szeredi if (cs->write) 884c55a01d3SMiklos Szeredi memcpy(buf, *val, ncpy); 885334f485dSMiklos Szeredi else 886c55a01d3SMiklos Szeredi memcpy(*val, buf, ncpy); 887c55a01d3SMiklos Szeredi 888c55a01d3SMiklos Szeredi kunmap_atomic(pgaddr); 889334f485dSMiklos Szeredi *val += ncpy; 890334f485dSMiklos Szeredi } 891334f485dSMiklos Szeredi *size -= ncpy; 892334f485dSMiklos Szeredi cs->len -= ncpy; 893c55a01d3SMiklos Szeredi cs->offset += ncpy; 894334f485dSMiklos Szeredi return ncpy; 895334f485dSMiklos Szeredi } 896334f485dSMiklos Szeredi 897ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page) 898ce534fb0SMiklos Szeredi { 899ce534fb0SMiklos Szeredi if (page_mapcount(page) || 900ce534fb0SMiklos Szeredi page->mapping != NULL || 901ce534fb0SMiklos Szeredi page_count(page) != 1 || 902ce534fb0SMiklos Szeredi (page->flags & PAGE_FLAGS_CHECK_AT_PREP & 903ce534fb0SMiklos Szeredi ~(1 << PG_locked | 904ce534fb0SMiklos Szeredi 1 << PG_referenced | 905ce534fb0SMiklos Szeredi 1 << PG_uptodate | 906ce534fb0SMiklos Szeredi 1 << PG_lru | 907ce534fb0SMiklos Szeredi 1 << PG_active | 908ce534fb0SMiklos Szeredi 1 << PG_reclaim))) { 909ce534fb0SMiklos Szeredi printk(KERN_WARNING "fuse: trying to steal weird page\n"); 910ce534fb0SMiklos 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); 911ce534fb0SMiklos Szeredi return 1; 912ce534fb0SMiklos Szeredi } 913ce534fb0SMiklos Szeredi return 0; 914ce534fb0SMiklos Szeredi } 915ce534fb0SMiklos Szeredi 916ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) 917ce534fb0SMiklos Szeredi { 918ce534fb0SMiklos Szeredi int err; 919ce534fb0SMiklos Szeredi struct page *oldpage = *pagep; 920ce534fb0SMiklos Szeredi struct page *newpage; 921ce534fb0SMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 922ce534fb0SMiklos Szeredi 923dc00809aSMiklos Szeredi err = unlock_request(cs->req); 9240d8e84b0SMiklos Szeredi if (err) 9250d8e84b0SMiklos Szeredi return err; 9260d8e84b0SMiklos Szeredi 927ce534fb0SMiklos Szeredi fuse_copy_finish(cs); 928ce534fb0SMiklos Szeredi 929fba597dbSMiklos Szeredi err = pipe_buf_confirm(cs->pipe, buf); 930ce534fb0SMiklos Szeredi if (err) 931ce534fb0SMiklos Szeredi return err; 932ce534fb0SMiklos Szeredi 933ce534fb0SMiklos Szeredi BUG_ON(!cs->nr_segs); 934ce534fb0SMiklos Szeredi cs->currbuf = buf; 935ce534fb0SMiklos Szeredi cs->len = buf->len; 936ce534fb0SMiklos Szeredi cs->pipebufs++; 937ce534fb0SMiklos Szeredi cs->nr_segs--; 938ce534fb0SMiklos Szeredi 939ce534fb0SMiklos Szeredi if (cs->len != PAGE_SIZE) 940ce534fb0SMiklos Szeredi goto out_fallback; 941ce534fb0SMiklos Szeredi 942ca76f5b6SMiklos Szeredi if (pipe_buf_steal(cs->pipe, buf) != 0) 943ce534fb0SMiklos Szeredi goto out_fallback; 944ce534fb0SMiklos Szeredi 945ce534fb0SMiklos Szeredi newpage = buf->page; 946ce534fb0SMiklos Szeredi 947aa991b3bSMiklos Szeredi if (!PageUptodate(newpage)) 948aa991b3bSMiklos Szeredi SetPageUptodate(newpage); 949ce534fb0SMiklos Szeredi 950ce534fb0SMiklos Szeredi ClearPageMappedToDisk(newpage); 951ce534fb0SMiklos Szeredi 952ce534fb0SMiklos Szeredi if (fuse_check_page(newpage) != 0) 953ce534fb0SMiklos Szeredi goto out_fallback_unlock; 954ce534fb0SMiklos Szeredi 955ce534fb0SMiklos Szeredi /* 956ce534fb0SMiklos Szeredi * This is a new and locked page, it shouldn't be mapped or 957ce534fb0SMiklos Szeredi * have any special flags on it 958ce534fb0SMiklos Szeredi */ 959ce534fb0SMiklos Szeredi if (WARN_ON(page_mapped(oldpage))) 960ce534fb0SMiklos Szeredi goto out_fallback_unlock; 961ce534fb0SMiklos Szeredi if (WARN_ON(page_has_private(oldpage))) 962ce534fb0SMiklos Szeredi goto out_fallback_unlock; 963ce534fb0SMiklos Szeredi if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage))) 964ce534fb0SMiklos Szeredi goto out_fallback_unlock; 965ce534fb0SMiklos Szeredi if (WARN_ON(PageMlocked(oldpage))) 966ce534fb0SMiklos Szeredi goto out_fallback_unlock; 967ce534fb0SMiklos Szeredi 968ef6a3c63SMiklos Szeredi err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); 969ce534fb0SMiklos Szeredi if (err) { 970ef6a3c63SMiklos Szeredi unlock_page(newpage); 971ef6a3c63SMiklos Szeredi return err; 972ce534fb0SMiklos Szeredi } 973ef6a3c63SMiklos Szeredi 97409cbfeafSKirill A. Shutemov get_page(newpage); 975ce534fb0SMiklos Szeredi 976ce534fb0SMiklos Szeredi if (!(buf->flags & PIPE_BUF_FLAG_LRU)) 977ce534fb0SMiklos Szeredi lru_cache_add_file(newpage); 978ce534fb0SMiklos Szeredi 979ce534fb0SMiklos Szeredi err = 0; 980dc00809aSMiklos Szeredi spin_lock(&cs->req->waitq.lock); 981825d6d33SMiklos Szeredi if (test_bit(FR_ABORTED, &cs->req->flags)) 982ce534fb0SMiklos Szeredi err = -ENOENT; 983ce534fb0SMiklos Szeredi else 984ce534fb0SMiklos Szeredi *pagep = newpage; 985dc00809aSMiklos Szeredi spin_unlock(&cs->req->waitq.lock); 986ce534fb0SMiklos Szeredi 987ce534fb0SMiklos Szeredi if (err) { 988ce534fb0SMiklos Szeredi unlock_page(newpage); 98909cbfeafSKirill A. Shutemov put_page(newpage); 990ce534fb0SMiklos Szeredi return err; 991ce534fb0SMiklos Szeredi } 992ce534fb0SMiklos Szeredi 993ce534fb0SMiklos Szeredi unlock_page(oldpage); 99409cbfeafSKirill A. Shutemov put_page(oldpage); 995ce534fb0SMiklos Szeredi cs->len = 0; 996ce534fb0SMiklos Szeredi 997ce534fb0SMiklos Szeredi return 0; 998ce534fb0SMiklos Szeredi 999ce534fb0SMiklos Szeredi out_fallback_unlock: 1000ce534fb0SMiklos Szeredi unlock_page(newpage); 1001ce534fb0SMiklos Szeredi out_fallback: 1002c55a01d3SMiklos Szeredi cs->pg = buf->page; 1003c55a01d3SMiklos Szeredi cs->offset = buf->offset; 1004ce534fb0SMiklos Szeredi 1005dc00809aSMiklos Szeredi err = lock_request(cs->req); 1006ce534fb0SMiklos Szeredi if (err) 1007ce534fb0SMiklos Szeredi return err; 1008ce534fb0SMiklos Szeredi 1009ce534fb0SMiklos Szeredi return 1; 1010ce534fb0SMiklos Szeredi } 1011ce534fb0SMiklos Szeredi 1012c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page, 1013c3021629SMiklos Szeredi unsigned offset, unsigned count) 1014c3021629SMiklos Szeredi { 1015c3021629SMiklos Szeredi struct pipe_buffer *buf; 10160d8e84b0SMiklos Szeredi int err; 1017c3021629SMiklos Szeredi 1018c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 1019c3021629SMiklos Szeredi return -EIO; 1020c3021629SMiklos Szeredi 1021dc00809aSMiklos Szeredi err = unlock_request(cs->req); 10220d8e84b0SMiklos Szeredi if (err) 10230d8e84b0SMiklos Szeredi return err; 10240d8e84b0SMiklos Szeredi 1025c3021629SMiklos Szeredi fuse_copy_finish(cs); 1026c3021629SMiklos Szeredi 1027c3021629SMiklos Szeredi buf = cs->pipebufs; 102809cbfeafSKirill A. Shutemov get_page(page); 1029c3021629SMiklos Szeredi buf->page = page; 1030c3021629SMiklos Szeredi buf->offset = offset; 1031c3021629SMiklos Szeredi buf->len = count; 1032c3021629SMiklos Szeredi 1033c3021629SMiklos Szeredi cs->pipebufs++; 1034c3021629SMiklos Szeredi cs->nr_segs++; 1035c3021629SMiklos Szeredi cs->len = 0; 1036c3021629SMiklos Szeredi 1037c3021629SMiklos Szeredi return 0; 1038c3021629SMiklos Szeredi } 1039c3021629SMiklos Szeredi 1040334f485dSMiklos Szeredi /* 1041334f485dSMiklos Szeredi * Copy a page in the request to/from the userspace buffer. Must be 1042334f485dSMiklos Szeredi * done atomically 1043334f485dSMiklos Szeredi */ 1044ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep, 1045334f485dSMiklos Szeredi unsigned offset, unsigned count, int zeroing) 1046334f485dSMiklos Szeredi { 1047ce534fb0SMiklos Szeredi int err; 1048ce534fb0SMiklos Szeredi struct page *page = *pagep; 1049ce534fb0SMiklos Szeredi 1050b6777c40SMiklos Szeredi if (page && zeroing && count < PAGE_SIZE) 1051b6777c40SMiklos Szeredi clear_highpage(page); 1052b6777c40SMiklos Szeredi 1053334f485dSMiklos Szeredi while (count) { 1054c3021629SMiklos Szeredi if (cs->write && cs->pipebufs && page) { 1055c3021629SMiklos Szeredi return fuse_ref_page(cs, page, offset, count); 1056c3021629SMiklos Szeredi } else if (!cs->len) { 1057ce534fb0SMiklos Szeredi if (cs->move_pages && page && 1058ce534fb0SMiklos Szeredi offset == 0 && count == PAGE_SIZE) { 1059ce534fb0SMiklos Szeredi err = fuse_try_move_page(cs, pagep); 1060ce534fb0SMiklos Szeredi if (err <= 0) 1061ce534fb0SMiklos Szeredi return err; 1062ce534fb0SMiklos Szeredi } else { 1063ce534fb0SMiklos Szeredi err = fuse_copy_fill(cs); 10641729a16cSMiklos Szeredi if (err) 1065334f485dSMiklos Szeredi return err; 10661729a16cSMiklos Szeredi } 1067ce534fb0SMiklos Szeredi } 1068334f485dSMiklos Szeredi if (page) { 10692408f6efSCong Wang void *mapaddr = kmap_atomic(page); 1070334f485dSMiklos Szeredi void *buf = mapaddr + offset; 1071334f485dSMiklos Szeredi offset += fuse_copy_do(cs, &buf, &count); 10722408f6efSCong Wang kunmap_atomic(mapaddr); 1073334f485dSMiklos Szeredi } else 1074334f485dSMiklos Szeredi offset += fuse_copy_do(cs, NULL, &count); 1075334f485dSMiklos Szeredi } 1076334f485dSMiklos Szeredi if (page && !cs->write) 1077334f485dSMiklos Szeredi flush_dcache_page(page); 1078334f485dSMiklos Szeredi return 0; 1079334f485dSMiklos Szeredi } 1080334f485dSMiklos Szeredi 1081334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */ 1082334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes, 1083334f485dSMiklos Szeredi int zeroing) 1084334f485dSMiklos Szeredi { 1085334f485dSMiklos Szeredi unsigned i; 1086334f485dSMiklos Szeredi struct fuse_req *req = cs->req; 1087334f485dSMiklos Szeredi 1088334f485dSMiklos Szeredi for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) { 1089ce534fb0SMiklos Szeredi int err; 109085f40aecSMaxim Patlasov unsigned offset = req->page_descs[i].offset; 109185f40aecSMaxim Patlasov unsigned count = min(nbytes, req->page_descs[i].length); 1092ce534fb0SMiklos Szeredi 1093ce534fb0SMiklos Szeredi err = fuse_copy_page(cs, &req->pages[i], offset, count, 1094ce534fb0SMiklos Szeredi zeroing); 1095334f485dSMiklos Szeredi if (err) 1096334f485dSMiklos Szeredi return err; 1097334f485dSMiklos Szeredi 1098334f485dSMiklos Szeredi nbytes -= count; 1099334f485dSMiklos Szeredi } 1100334f485dSMiklos Szeredi return 0; 1101334f485dSMiklos Szeredi } 1102334f485dSMiklos Szeredi 1103334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */ 1104334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) 1105334f485dSMiklos Szeredi { 1106334f485dSMiklos Szeredi while (size) { 11071729a16cSMiklos Szeredi if (!cs->len) { 11081729a16cSMiklos Szeredi int err = fuse_copy_fill(cs); 11091729a16cSMiklos Szeredi if (err) 1110334f485dSMiklos Szeredi return err; 11111729a16cSMiklos Szeredi } 1112334f485dSMiklos Szeredi fuse_copy_do(cs, &val, &size); 1113334f485dSMiklos Szeredi } 1114334f485dSMiklos Szeredi return 0; 1115334f485dSMiklos Szeredi } 1116334f485dSMiklos Szeredi 1117334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */ 1118334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs, 1119334f485dSMiklos Szeredi unsigned argpages, struct fuse_arg *args, 1120334f485dSMiklos Szeredi int zeroing) 1121334f485dSMiklos Szeredi { 1122334f485dSMiklos Szeredi int err = 0; 1123334f485dSMiklos Szeredi unsigned i; 1124334f485dSMiklos Szeredi 1125334f485dSMiklos Szeredi for (i = 0; !err && i < numargs; i++) { 1126334f485dSMiklos Szeredi struct fuse_arg *arg = &args[i]; 1127334f485dSMiklos Szeredi if (i == numargs - 1 && argpages) 1128334f485dSMiklos Szeredi err = fuse_copy_pages(cs, arg->size, zeroing); 1129334f485dSMiklos Szeredi else 1130334f485dSMiklos Szeredi err = fuse_copy_one(cs, arg->value, arg->size); 1131334f485dSMiklos Szeredi } 1132334f485dSMiklos Szeredi return err; 1133334f485dSMiklos Szeredi } 1134334f485dSMiklos Szeredi 1135f88996a9SMiklos Szeredi static int forget_pending(struct fuse_iqueue *fiq) 113607e77dcaSMiklos Szeredi { 1137f88996a9SMiklos Szeredi return fiq->forget_list_head.next != NULL; 113807e77dcaSMiklos Szeredi } 113907e77dcaSMiklos Szeredi 1140f88996a9SMiklos Szeredi static int request_pending(struct fuse_iqueue *fiq) 1141a4d27e75SMiklos Szeredi { 1142f88996a9SMiklos Szeredi return !list_empty(&fiq->pending) || !list_empty(&fiq->interrupts) || 1143f88996a9SMiklos Szeredi forget_pending(fiq); 1144a4d27e75SMiklos Szeredi } 1145a4d27e75SMiklos Szeredi 1146334f485dSMiklos Szeredi /* 1147a4d27e75SMiklos Szeredi * Transfer an interrupt request to userspace 1148a4d27e75SMiklos Szeredi * 1149a4d27e75SMiklos Szeredi * Unlike other requests this is assembled on demand, without a need 1150a4d27e75SMiklos Szeredi * to allocate a separate fuse_req structure. 1151a4d27e75SMiklos Szeredi * 1152fd22d62eSMiklos Szeredi * Called with fiq->waitq.lock held, releases it 1153a4d27e75SMiklos Szeredi */ 1154fd22d62eSMiklos Szeredi static int fuse_read_interrupt(struct fuse_iqueue *fiq, 1155fd22d62eSMiklos Szeredi struct fuse_copy_state *cs, 1156c3021629SMiklos Szeredi size_t nbytes, struct fuse_req *req) 1157fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 1158a4d27e75SMiklos Szeredi { 1159a4d27e75SMiklos Szeredi struct fuse_in_header ih; 1160a4d27e75SMiklos Szeredi struct fuse_interrupt_in arg; 1161a4d27e75SMiklos Szeredi unsigned reqsize = sizeof(ih) + sizeof(arg); 1162a4d27e75SMiklos Szeredi int err; 1163a4d27e75SMiklos Szeredi 1164a4d27e75SMiklos Szeredi list_del_init(&req->intr_entry); 1165a4d27e75SMiklos Szeredi memset(&ih, 0, sizeof(ih)); 1166a4d27e75SMiklos Szeredi memset(&arg, 0, sizeof(arg)); 1167a4d27e75SMiklos Szeredi ih.len = reqsize; 1168a4d27e75SMiklos Szeredi ih.opcode = FUSE_INTERRUPT; 11693a5358d1SKirill Tkhai ih.unique = (req->in.h.unique | FUSE_INT_REQ_BIT); 1170a4d27e75SMiklos Szeredi arg.unique = req->in.h.unique; 1171a4d27e75SMiklos Szeredi 11724ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 1173c3021629SMiklos Szeredi if (nbytes < reqsize) 1174a4d27e75SMiklos Szeredi return -EINVAL; 1175a4d27e75SMiklos Szeredi 1176c3021629SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 1177a4d27e75SMiklos Szeredi if (!err) 1178c3021629SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 1179c3021629SMiklos Szeredi fuse_copy_finish(cs); 1180a4d27e75SMiklos Szeredi 1181a4d27e75SMiklos Szeredi return err ? err : reqsize; 1182a4d27e75SMiklos Szeredi } 1183a4d27e75SMiklos Szeredi 1184f88996a9SMiklos Szeredi static struct fuse_forget_link *dequeue_forget(struct fuse_iqueue *fiq, 118502c048b9SMiklos Szeredi unsigned max, 118602c048b9SMiklos Szeredi unsigned *countp) 118707e77dcaSMiklos Szeredi { 1188f88996a9SMiklos Szeredi struct fuse_forget_link *head = fiq->forget_list_head.next; 118902c048b9SMiklos Szeredi struct fuse_forget_link **newhead = &head; 119002c048b9SMiklos Szeredi unsigned count; 119107e77dcaSMiklos Szeredi 119202c048b9SMiklos Szeredi for (count = 0; *newhead != NULL && count < max; count++) 119302c048b9SMiklos Szeredi newhead = &(*newhead)->next; 119402c048b9SMiklos Szeredi 1195f88996a9SMiklos Szeredi fiq->forget_list_head.next = *newhead; 119602c048b9SMiklos Szeredi *newhead = NULL; 1197f88996a9SMiklos Szeredi if (fiq->forget_list_head.next == NULL) 1198f88996a9SMiklos Szeredi fiq->forget_list_tail = &fiq->forget_list_head; 119907e77dcaSMiklos Szeredi 120002c048b9SMiklos Szeredi if (countp != NULL) 120102c048b9SMiklos Szeredi *countp = count; 120202c048b9SMiklos Szeredi 120302c048b9SMiklos Szeredi return head; 120407e77dcaSMiklos Szeredi } 120507e77dcaSMiklos Szeredi 1206fd22d62eSMiklos Szeredi static int fuse_read_single_forget(struct fuse_iqueue *fiq, 120707e77dcaSMiklos Szeredi struct fuse_copy_state *cs, 120807e77dcaSMiklos Szeredi size_t nbytes) 1209fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 121007e77dcaSMiklos Szeredi { 121107e77dcaSMiklos Szeredi int err; 1212f88996a9SMiklos Szeredi struct fuse_forget_link *forget = dequeue_forget(fiq, 1, NULL); 121307e77dcaSMiklos Szeredi struct fuse_forget_in arg = { 121402c048b9SMiklos Szeredi .nlookup = forget->forget_one.nlookup, 121507e77dcaSMiklos Szeredi }; 121607e77dcaSMiklos Szeredi struct fuse_in_header ih = { 121707e77dcaSMiklos Szeredi .opcode = FUSE_FORGET, 121802c048b9SMiklos Szeredi .nodeid = forget->forget_one.nodeid, 1219f88996a9SMiklos Szeredi .unique = fuse_get_unique(fiq), 122007e77dcaSMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 122107e77dcaSMiklos Szeredi }; 122207e77dcaSMiklos Szeredi 12234ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 122407e77dcaSMiklos Szeredi kfree(forget); 122507e77dcaSMiklos Szeredi if (nbytes < ih.len) 122607e77dcaSMiklos Szeredi return -EINVAL; 122707e77dcaSMiklos Szeredi 122807e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 122907e77dcaSMiklos Szeredi if (!err) 123007e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 123107e77dcaSMiklos Szeredi fuse_copy_finish(cs); 123207e77dcaSMiklos Szeredi 123307e77dcaSMiklos Szeredi if (err) 123407e77dcaSMiklos Szeredi return err; 123507e77dcaSMiklos Szeredi 123607e77dcaSMiklos Szeredi return ih.len; 123707e77dcaSMiklos Szeredi } 123807e77dcaSMiklos Szeredi 1239fd22d62eSMiklos Szeredi static int fuse_read_batch_forget(struct fuse_iqueue *fiq, 124002c048b9SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1241fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 124202c048b9SMiklos Szeredi { 124302c048b9SMiklos Szeredi int err; 124402c048b9SMiklos Szeredi unsigned max_forgets; 124502c048b9SMiklos Szeredi unsigned count; 124602c048b9SMiklos Szeredi struct fuse_forget_link *head; 124702c048b9SMiklos Szeredi struct fuse_batch_forget_in arg = { .count = 0 }; 124802c048b9SMiklos Szeredi struct fuse_in_header ih = { 124902c048b9SMiklos Szeredi .opcode = FUSE_BATCH_FORGET, 1250f88996a9SMiklos Szeredi .unique = fuse_get_unique(fiq), 125102c048b9SMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 125202c048b9SMiklos Szeredi }; 125302c048b9SMiklos Szeredi 125402c048b9SMiklos Szeredi if (nbytes < ih.len) { 12554ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 125602c048b9SMiklos Szeredi return -EINVAL; 125702c048b9SMiklos Szeredi } 125802c048b9SMiklos Szeredi 125902c048b9SMiklos Szeredi max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one); 1260f88996a9SMiklos Szeredi head = dequeue_forget(fiq, max_forgets, &count); 12614ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 126202c048b9SMiklos Szeredi 126302c048b9SMiklos Szeredi arg.count = count; 126402c048b9SMiklos Szeredi ih.len += count * sizeof(struct fuse_forget_one); 126502c048b9SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 126602c048b9SMiklos Szeredi if (!err) 126702c048b9SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 126802c048b9SMiklos Szeredi 126902c048b9SMiklos Szeredi while (head) { 127002c048b9SMiklos Szeredi struct fuse_forget_link *forget = head; 127102c048b9SMiklos Szeredi 127202c048b9SMiklos Szeredi if (!err) { 127302c048b9SMiklos Szeredi err = fuse_copy_one(cs, &forget->forget_one, 127402c048b9SMiklos Szeredi sizeof(forget->forget_one)); 127502c048b9SMiklos Szeredi } 127602c048b9SMiklos Szeredi head = forget->next; 127702c048b9SMiklos Szeredi kfree(forget); 127802c048b9SMiklos Szeredi } 127902c048b9SMiklos Szeredi 128002c048b9SMiklos Szeredi fuse_copy_finish(cs); 128102c048b9SMiklos Szeredi 128202c048b9SMiklos Szeredi if (err) 128302c048b9SMiklos Szeredi return err; 128402c048b9SMiklos Szeredi 128502c048b9SMiklos Szeredi return ih.len; 128602c048b9SMiklos Szeredi } 128702c048b9SMiklos Szeredi 1288fd22d62eSMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq, 1289fd22d62eSMiklos Szeredi struct fuse_copy_state *cs, 129002c048b9SMiklos Szeredi size_t nbytes) 1291fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 129202c048b9SMiklos Szeredi { 1293f88996a9SMiklos Szeredi if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL) 1294fd22d62eSMiklos Szeredi return fuse_read_single_forget(fiq, cs, nbytes); 129502c048b9SMiklos Szeredi else 1296fd22d62eSMiklos Szeredi return fuse_read_batch_forget(fiq, cs, nbytes); 129702c048b9SMiklos Szeredi } 129802c048b9SMiklos Szeredi 1299a4d27e75SMiklos Szeredi /* 1300334f485dSMiklos Szeredi * Read a single request into the userspace filesystem's buffer. This 1301334f485dSMiklos Szeredi * function waits until a request is available, then removes it from 1302334f485dSMiklos Szeredi * the pending list and copies request data to userspace buffer. If 1303f9a2842eSMiklos Szeredi * no reply is needed (FORGET) or request has been aborted or there 1304f9a2842eSMiklos Szeredi * was an error during the copying then it's finished by calling 1305334f485dSMiklos Szeredi * request_end(). Otherwise add it to the processing list, and set 1306334f485dSMiklos Szeredi * the 'sent' flag. 1307334f485dSMiklos Szeredi */ 1308c3696046SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, 1309c3021629SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1310334f485dSMiklos Szeredi { 131182cbdcd3SMiklos Szeredi ssize_t err; 1312c3696046SMiklos Szeredi struct fuse_conn *fc = fud->fc; 1313f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 1314c3696046SMiklos Szeredi struct fuse_pqueue *fpq = &fud->pq; 1315334f485dSMiklos Szeredi struct fuse_req *req; 1316334f485dSMiklos Szeredi struct fuse_in *in; 1317334f485dSMiklos Szeredi unsigned reqsize; 1318be2ff42cSKirill Tkhai unsigned int hash; 1319334f485dSMiklos Szeredi 13201d3d752bSMiklos Szeredi restart: 13214ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 1322e5ac1d1eSJeff Dike err = -EAGAIN; 1323e16714d8SMiklos Szeredi if ((file->f_flags & O_NONBLOCK) && fiq->connected && 1324f88996a9SMiklos Szeredi !request_pending(fiq)) 1325e5ac1d1eSJeff Dike goto err_unlock; 1326e5ac1d1eSJeff Dike 13275250921bSMiklos Szeredi err = wait_event_interruptible_exclusive_locked(fiq->waitq, 13285250921bSMiklos Szeredi !fiq->connected || request_pending(fiq)); 13295250921bSMiklos Szeredi if (err) 13305250921bSMiklos Szeredi goto err_unlock; 13315250921bSMiklos Szeredi 13323b7008b2SSzymon Lukasz if (!fiq->connected) { 1333eb98e3bdSMiklos Szeredi err = fc->aborted ? -ECONNABORTED : -ENODEV; 1334334f485dSMiklos Szeredi goto err_unlock; 13353b7008b2SSzymon Lukasz } 1336334f485dSMiklos Szeredi 1337f88996a9SMiklos Szeredi if (!list_empty(&fiq->interrupts)) { 1338f88996a9SMiklos Szeredi req = list_entry(fiq->interrupts.next, struct fuse_req, 1339a4d27e75SMiklos Szeredi intr_entry); 1340fd22d62eSMiklos Szeredi return fuse_read_interrupt(fiq, cs, nbytes, req); 1341a4d27e75SMiklos Szeredi } 1342a4d27e75SMiklos Szeredi 1343f88996a9SMiklos Szeredi if (forget_pending(fiq)) { 1344f88996a9SMiklos Szeredi if (list_empty(&fiq->pending) || fiq->forget_batch-- > 0) 1345fd22d62eSMiklos Szeredi return fuse_read_forget(fc, fiq, cs, nbytes); 134607e77dcaSMiklos Szeredi 1347f88996a9SMiklos Szeredi if (fiq->forget_batch <= -8) 1348f88996a9SMiklos Szeredi fiq->forget_batch = 16; 134907e77dcaSMiklos Szeredi } 135007e77dcaSMiklos Szeredi 1351f88996a9SMiklos Szeredi req = list_entry(fiq->pending.next, struct fuse_req, list); 135233e14b4dSMiklos Szeredi clear_bit(FR_PENDING, &req->flags); 1353ef759258SMiklos Szeredi list_del_init(&req->list); 13544ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 13554ce60812SMiklos Szeredi 1356334f485dSMiklos Szeredi in = &req->in; 13571d3d752bSMiklos Szeredi reqsize = in->h.len; 13585d6d3a30SMiklos Szeredi 13591d3d752bSMiklos Szeredi /* If request is too large, reply with an error and restart the read */ 1360c3021629SMiklos Szeredi if (nbytes < reqsize) { 13611d3d752bSMiklos Szeredi req->out.h.error = -EIO; 13621d3d752bSMiklos Szeredi /* SETXATTR is special, since it may contain too large data */ 13631d3d752bSMiklos Szeredi if (in->h.opcode == FUSE_SETXATTR) 13641d3d752bSMiklos Szeredi req->out.h.error = -E2BIG; 13651d3d752bSMiklos Szeredi request_end(fc, req); 13661d3d752bSMiklos Szeredi goto restart; 13671d3d752bSMiklos Szeredi } 136845a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 136982cbdcd3SMiklos Szeredi list_add(&req->list, &fpq->io); 137045a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 1371c3021629SMiklos Szeredi cs->req = req; 1372c3021629SMiklos Szeredi err = fuse_copy_one(cs, &in->h, sizeof(in->h)); 1373334f485dSMiklos Szeredi if (!err) 1374c3021629SMiklos Szeredi err = fuse_copy_args(cs, in->numargs, in->argpages, 1375334f485dSMiklos Szeredi (struct fuse_arg *) in->args, 0); 1376c3021629SMiklos Szeredi fuse_copy_finish(cs); 137745a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 1378825d6d33SMiklos Szeredi clear_bit(FR_LOCKED, &req->flags); 1379e96edd94SMiklos Szeredi if (!fpq->connected) { 1380eb98e3bdSMiklos Szeredi err = fc->aborted ? -ECONNABORTED : -ENODEV; 138182cbdcd3SMiklos Szeredi goto out_end; 1382c9c9d7dfSMiklos Szeredi } 1383334f485dSMiklos Szeredi if (err) { 1384334f485dSMiklos Szeredi req->out.h.error = -EIO; 138582cbdcd3SMiklos Szeredi goto out_end; 1386334f485dSMiklos Szeredi } 1387825d6d33SMiklos Szeredi if (!test_bit(FR_ISREPLY, &req->flags)) { 138882cbdcd3SMiklos Szeredi err = reqsize; 138982cbdcd3SMiklos Szeredi goto out_end; 139082cbdcd3SMiklos Szeredi } 1391be2ff42cSKirill Tkhai hash = fuse_req_hash(req->in.h.unique); 1392be2ff42cSKirill Tkhai list_move_tail(&req->list, &fpq->processing[hash]); 1393bc78abbdSKirill Tkhai __fuse_get_request(req); 13948f7bb368SMiklos Szeredi set_bit(FR_SENT, &req->flags); 13954c316f2fSMiklos Szeredi spin_unlock(&fpq->lock); 13968f7bb368SMiklos Szeredi /* matches barrier in request_wait_answer() */ 13978f7bb368SMiklos Szeredi smp_mb__after_atomic(); 1398825d6d33SMiklos Szeredi if (test_bit(FR_INTERRUPTED, &req->flags)) 1399f88996a9SMiklos Szeredi queue_interrupt(fiq, req); 1400bc78abbdSKirill Tkhai fuse_put_request(fc, req); 140182cbdcd3SMiklos Szeredi 1402334f485dSMiklos Szeredi return reqsize; 1403334f485dSMiklos Szeredi 140482cbdcd3SMiklos Szeredi out_end: 140577cd9d48SMiklos Szeredi if (!test_bit(FR_PRIVATE, &req->flags)) 140682cbdcd3SMiklos Szeredi list_del_init(&req->list); 140745a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 140882cbdcd3SMiklos Szeredi request_end(fc, req); 140982cbdcd3SMiklos Szeredi return err; 141082cbdcd3SMiklos Szeredi 1411334f485dSMiklos Szeredi err_unlock: 14124ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 1413334f485dSMiklos Szeredi return err; 1414334f485dSMiklos Szeredi } 1415334f485dSMiklos Szeredi 141694e4fe2cSTom Van Braeckel static int fuse_dev_open(struct inode *inode, struct file *file) 141794e4fe2cSTom Van Braeckel { 141894e4fe2cSTom Van Braeckel /* 141994e4fe2cSTom Van Braeckel * The fuse device's file's private_data is used to hold 142094e4fe2cSTom Van Braeckel * the fuse_conn(ection) when it is mounted, and is used to 142194e4fe2cSTom Van Braeckel * keep track of whether the file has been mounted already. 142294e4fe2cSTom Van Braeckel */ 142394e4fe2cSTom Van Braeckel file->private_data = NULL; 142494e4fe2cSTom Van Braeckel return 0; 142594e4fe2cSTom Van Braeckel } 142694e4fe2cSTom Van Braeckel 1427fbdbaccaSAl Viro static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to) 1428c3021629SMiklos Szeredi { 1429c3021629SMiklos Szeredi struct fuse_copy_state cs; 1430c3021629SMiklos Szeredi struct file *file = iocb->ki_filp; 1431cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(file); 1432cc080e9eSMiklos Szeredi 1433cc080e9eSMiklos Szeredi if (!fud) 1434c3021629SMiklos Szeredi return -EPERM; 1435c3021629SMiklos Szeredi 1436fbdbaccaSAl Viro if (!iter_is_iovec(to)) 1437fbdbaccaSAl Viro return -EINVAL; 1438c3021629SMiklos Szeredi 1439dc00809aSMiklos Szeredi fuse_copy_init(&cs, 1, to); 1440fbdbaccaSAl Viro 1441c3696046SMiklos Szeredi return fuse_dev_do_read(fud, file, &cs, iov_iter_count(to)); 1442c3021629SMiklos Szeredi } 1443c3021629SMiklos Szeredi 1444c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, 1445c3021629SMiklos Szeredi struct pipe_inode_info *pipe, 1446c3021629SMiklos Szeredi size_t len, unsigned int flags) 1447c3021629SMiklos Szeredi { 1448d82718e3SAl Viro int total, ret; 1449c3021629SMiklos Szeredi int page_nr = 0; 1450c3021629SMiklos Szeredi struct pipe_buffer *bufs; 1451c3021629SMiklos Szeredi struct fuse_copy_state cs; 1452cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(in); 1453cc080e9eSMiklos Szeredi 1454cc080e9eSMiklos Szeredi if (!fud) 1455c3021629SMiklos Szeredi return -EPERM; 1456c3021629SMiklos Szeredi 1457d6d931adSAndrey Ryabinin bufs = kvmalloc_array(pipe->buffers, sizeof(struct pipe_buffer), 14586da2ec56SKees Cook GFP_KERNEL); 1459c3021629SMiklos Szeredi if (!bufs) 1460c3021629SMiklos Szeredi return -ENOMEM; 1461c3021629SMiklos Szeredi 1462dc00809aSMiklos Szeredi fuse_copy_init(&cs, 1, NULL); 1463c3021629SMiklos Szeredi cs.pipebufs = bufs; 1464c3021629SMiklos Szeredi cs.pipe = pipe; 1465c3696046SMiklos Szeredi ret = fuse_dev_do_read(fud, in, &cs, len); 1466c3021629SMiklos Szeredi if (ret < 0) 1467c3021629SMiklos Szeredi goto out; 1468c3021629SMiklos Szeredi 1469c3021629SMiklos Szeredi if (pipe->nrbufs + cs.nr_segs > pipe->buffers) { 1470c3021629SMiklos Szeredi ret = -EIO; 1471d82718e3SAl Viro goto out; 1472c3021629SMiklos Szeredi } 1473c3021629SMiklos Szeredi 1474d82718e3SAl Viro for (ret = total = 0; page_nr < cs.nr_segs; total += ret) { 147528a625cbSMiklos Szeredi /* 147628a625cbSMiklos Szeredi * Need to be careful about this. Having buf->ops in module 147728a625cbSMiklos Szeredi * code can Oops if the buffer persists after module unload. 147828a625cbSMiklos Szeredi */ 1479d82718e3SAl Viro bufs[page_nr].ops = &nosteal_pipe_buf_ops; 148084588a93SMiklos Szeredi bufs[page_nr].flags = 0; 1481d82718e3SAl Viro ret = add_to_pipe(pipe, &bufs[page_nr++]); 1482d82718e3SAl Viro if (unlikely(ret < 0)) 1483d82718e3SAl Viro break; 1484c3021629SMiklos Szeredi } 1485d82718e3SAl Viro if (total) 1486d82718e3SAl Viro ret = total; 1487c3021629SMiklos Szeredi out: 1488c3021629SMiklos Szeredi for (; page_nr < cs.nr_segs; page_nr++) 148909cbfeafSKirill A. Shutemov put_page(bufs[page_nr].page); 1490c3021629SMiklos Szeredi 1491d6d931adSAndrey Ryabinin kvfree(bufs); 1492c3021629SMiklos Szeredi return ret; 1493c3021629SMiklos Szeredi } 1494c3021629SMiklos Szeredi 149595668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size, 149695668a69STejun Heo struct fuse_copy_state *cs) 149795668a69STejun Heo { 149895668a69STejun Heo struct fuse_notify_poll_wakeup_out outarg; 1499f6d47a17SMiklos Szeredi int err = -EINVAL; 150095668a69STejun Heo 150195668a69STejun Heo if (size != sizeof(outarg)) 1502f6d47a17SMiklos Szeredi goto err; 150395668a69STejun Heo 150495668a69STejun Heo err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 150595668a69STejun Heo if (err) 1506f6d47a17SMiklos Szeredi goto err; 150795668a69STejun Heo 1508f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 150995668a69STejun Heo return fuse_notify_poll_wakeup(fc, &outarg); 1510f6d47a17SMiklos Szeredi 1511f6d47a17SMiklos Szeredi err: 1512f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 1513f6d47a17SMiklos Szeredi return err; 151495668a69STejun Heo } 151595668a69STejun Heo 15163b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size, 15173b463ae0SJohn Muir struct fuse_copy_state *cs) 15183b463ae0SJohn Muir { 15193b463ae0SJohn Muir struct fuse_notify_inval_inode_out outarg; 15203b463ae0SJohn Muir int err = -EINVAL; 15213b463ae0SJohn Muir 15223b463ae0SJohn Muir if (size != sizeof(outarg)) 15233b463ae0SJohn Muir goto err; 15243b463ae0SJohn Muir 15253b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 15263b463ae0SJohn Muir if (err) 15273b463ae0SJohn Muir goto err; 15283b463ae0SJohn Muir fuse_copy_finish(cs); 15293b463ae0SJohn Muir 15303b463ae0SJohn Muir down_read(&fc->killsb); 15313b463ae0SJohn Muir err = -ENOENT; 1532b21dda43SMiklos Szeredi if (fc->sb) { 15333b463ae0SJohn Muir err = fuse_reverse_inval_inode(fc->sb, outarg.ino, 15343b463ae0SJohn Muir outarg.off, outarg.len); 1535b21dda43SMiklos Szeredi } 15363b463ae0SJohn Muir up_read(&fc->killsb); 15373b463ae0SJohn Muir return err; 15383b463ae0SJohn Muir 15393b463ae0SJohn Muir err: 15403b463ae0SJohn Muir fuse_copy_finish(cs); 15413b463ae0SJohn Muir return err; 15423b463ae0SJohn Muir } 15433b463ae0SJohn Muir 15443b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, 15453b463ae0SJohn Muir struct fuse_copy_state *cs) 15463b463ae0SJohn Muir { 15473b463ae0SJohn Muir struct fuse_notify_inval_entry_out outarg; 1548b2d82ee3SFang Wenqi int err = -ENOMEM; 1549b2d82ee3SFang Wenqi char *buf; 15503b463ae0SJohn Muir struct qstr name; 15513b463ae0SJohn Muir 1552b2d82ee3SFang Wenqi buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1553b2d82ee3SFang Wenqi if (!buf) 1554b2d82ee3SFang Wenqi goto err; 1555b2d82ee3SFang Wenqi 1556b2d82ee3SFang Wenqi err = -EINVAL; 15573b463ae0SJohn Muir if (size < sizeof(outarg)) 15583b463ae0SJohn Muir goto err; 15593b463ae0SJohn Muir 15603b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 15613b463ae0SJohn Muir if (err) 15623b463ae0SJohn Muir goto err; 15633b463ae0SJohn Muir 15643b463ae0SJohn Muir err = -ENAMETOOLONG; 15653b463ae0SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 15663b463ae0SJohn Muir goto err; 15673b463ae0SJohn Muir 1568c2183d1eSMiklos Szeredi err = -EINVAL; 1569c2183d1eSMiklos Szeredi if (size != sizeof(outarg) + outarg.namelen + 1) 1570c2183d1eSMiklos Szeredi goto err; 1571c2183d1eSMiklos Szeredi 15723b463ae0SJohn Muir name.name = buf; 15733b463ae0SJohn Muir name.len = outarg.namelen; 15743b463ae0SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 15753b463ae0SJohn Muir if (err) 15763b463ae0SJohn Muir goto err; 15773b463ae0SJohn Muir fuse_copy_finish(cs); 15783b463ae0SJohn Muir buf[outarg.namelen] = 0; 15793b463ae0SJohn Muir 15803b463ae0SJohn Muir down_read(&fc->killsb); 15813b463ae0SJohn Muir err = -ENOENT; 1582b21dda43SMiklos Szeredi if (fc->sb) 1583451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 0, &name); 1584451d0f59SJohn Muir up_read(&fc->killsb); 1585451d0f59SJohn Muir kfree(buf); 1586451d0f59SJohn Muir return err; 1587451d0f59SJohn Muir 1588451d0f59SJohn Muir err: 1589451d0f59SJohn Muir kfree(buf); 1590451d0f59SJohn Muir fuse_copy_finish(cs); 1591451d0f59SJohn Muir return err; 1592451d0f59SJohn Muir } 1593451d0f59SJohn Muir 1594451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size, 1595451d0f59SJohn Muir struct fuse_copy_state *cs) 1596451d0f59SJohn Muir { 1597451d0f59SJohn Muir struct fuse_notify_delete_out outarg; 1598451d0f59SJohn Muir int err = -ENOMEM; 1599451d0f59SJohn Muir char *buf; 1600451d0f59SJohn Muir struct qstr name; 1601451d0f59SJohn Muir 1602451d0f59SJohn Muir buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1603451d0f59SJohn Muir if (!buf) 1604451d0f59SJohn Muir goto err; 1605451d0f59SJohn Muir 1606451d0f59SJohn Muir err = -EINVAL; 1607451d0f59SJohn Muir if (size < sizeof(outarg)) 1608451d0f59SJohn Muir goto err; 1609451d0f59SJohn Muir 1610451d0f59SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1611451d0f59SJohn Muir if (err) 1612451d0f59SJohn Muir goto err; 1613451d0f59SJohn Muir 1614451d0f59SJohn Muir err = -ENAMETOOLONG; 1615451d0f59SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 1616451d0f59SJohn Muir goto err; 1617451d0f59SJohn Muir 1618451d0f59SJohn Muir err = -EINVAL; 1619451d0f59SJohn Muir if (size != sizeof(outarg) + outarg.namelen + 1) 1620451d0f59SJohn Muir goto err; 1621451d0f59SJohn Muir 1622451d0f59SJohn Muir name.name = buf; 1623451d0f59SJohn Muir name.len = outarg.namelen; 1624451d0f59SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 1625451d0f59SJohn Muir if (err) 1626451d0f59SJohn Muir goto err; 1627451d0f59SJohn Muir fuse_copy_finish(cs); 1628451d0f59SJohn Muir buf[outarg.namelen] = 0; 1629451d0f59SJohn Muir 1630451d0f59SJohn Muir down_read(&fc->killsb); 1631451d0f59SJohn Muir err = -ENOENT; 1632451d0f59SJohn Muir if (fc->sb) 1633451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 1634451d0f59SJohn Muir outarg.child, &name); 16353b463ae0SJohn Muir up_read(&fc->killsb); 1636b2d82ee3SFang Wenqi kfree(buf); 16373b463ae0SJohn Muir return err; 16383b463ae0SJohn Muir 16393b463ae0SJohn Muir err: 1640b2d82ee3SFang Wenqi kfree(buf); 16413b463ae0SJohn Muir fuse_copy_finish(cs); 16423b463ae0SJohn Muir return err; 16433b463ae0SJohn Muir } 16443b463ae0SJohn Muir 1645a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, 1646a1d75f25SMiklos Szeredi struct fuse_copy_state *cs) 1647a1d75f25SMiklos Szeredi { 1648a1d75f25SMiklos Szeredi struct fuse_notify_store_out outarg; 1649a1d75f25SMiklos Szeredi struct inode *inode; 1650a1d75f25SMiklos Szeredi struct address_space *mapping; 1651a1d75f25SMiklos Szeredi u64 nodeid; 1652a1d75f25SMiklos Szeredi int err; 1653a1d75f25SMiklos Szeredi pgoff_t index; 1654a1d75f25SMiklos Szeredi unsigned int offset; 1655a1d75f25SMiklos Szeredi unsigned int num; 1656a1d75f25SMiklos Szeredi loff_t file_size; 1657a1d75f25SMiklos Szeredi loff_t end; 1658a1d75f25SMiklos Szeredi 1659a1d75f25SMiklos Szeredi err = -EINVAL; 1660a1d75f25SMiklos Szeredi if (size < sizeof(outarg)) 1661a1d75f25SMiklos Szeredi goto out_finish; 1662a1d75f25SMiklos Szeredi 1663a1d75f25SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1664a1d75f25SMiklos Szeredi if (err) 1665a1d75f25SMiklos Szeredi goto out_finish; 1666a1d75f25SMiklos Szeredi 1667a1d75f25SMiklos Szeredi err = -EINVAL; 1668a1d75f25SMiklos Szeredi if (size - sizeof(outarg) != outarg.size) 1669a1d75f25SMiklos Szeredi goto out_finish; 1670a1d75f25SMiklos Szeredi 1671a1d75f25SMiklos Szeredi nodeid = outarg.nodeid; 1672a1d75f25SMiklos Szeredi 1673a1d75f25SMiklos Szeredi down_read(&fc->killsb); 1674a1d75f25SMiklos Szeredi 1675a1d75f25SMiklos Szeredi err = -ENOENT; 1676a1d75f25SMiklos Szeredi if (!fc->sb) 1677a1d75f25SMiklos Szeredi goto out_up_killsb; 1678a1d75f25SMiklos Szeredi 1679a1d75f25SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 1680a1d75f25SMiklos Szeredi if (!inode) 1681a1d75f25SMiklos Szeredi goto out_up_killsb; 1682a1d75f25SMiklos Szeredi 1683a1d75f25SMiklos Szeredi mapping = inode->i_mapping; 168409cbfeafSKirill A. Shutemov index = outarg.offset >> PAGE_SHIFT; 168509cbfeafSKirill A. Shutemov offset = outarg.offset & ~PAGE_MASK; 1686a1d75f25SMiklos Szeredi file_size = i_size_read(inode); 1687a1d75f25SMiklos Szeredi end = outarg.offset + outarg.size; 1688a1d75f25SMiklos Szeredi if (end > file_size) { 1689a1d75f25SMiklos Szeredi file_size = end; 1690a1d75f25SMiklos Szeredi fuse_write_update_size(inode, file_size); 1691a1d75f25SMiklos Szeredi } 1692a1d75f25SMiklos Szeredi 1693a1d75f25SMiklos Szeredi num = outarg.size; 1694a1d75f25SMiklos Szeredi while (num) { 1695a1d75f25SMiklos Szeredi struct page *page; 1696a1d75f25SMiklos Szeredi unsigned int this_num; 1697a1d75f25SMiklos Szeredi 1698a1d75f25SMiklos Szeredi err = -ENOMEM; 1699a1d75f25SMiklos Szeredi page = find_or_create_page(mapping, index, 1700a1d75f25SMiklos Szeredi mapping_gfp_mask(mapping)); 1701a1d75f25SMiklos Szeredi if (!page) 1702a1d75f25SMiklos Szeredi goto out_iput; 1703a1d75f25SMiklos Szeredi 170409cbfeafSKirill A. Shutemov this_num = min_t(unsigned, num, PAGE_SIZE - offset); 1705a1d75f25SMiklos Szeredi err = fuse_copy_page(cs, &page, offset, this_num, 0); 1706063ec1e5SMiklos Szeredi if (!err && offset == 0 && 170709cbfeafSKirill A. Shutemov (this_num == PAGE_SIZE || file_size == end)) 1708a1d75f25SMiklos Szeredi SetPageUptodate(page); 1709a1d75f25SMiklos Szeredi unlock_page(page); 171009cbfeafSKirill A. Shutemov put_page(page); 1711a1d75f25SMiklos Szeredi 1712a1d75f25SMiklos Szeredi if (err) 1713a1d75f25SMiklos Szeredi goto out_iput; 1714a1d75f25SMiklos Szeredi 1715a1d75f25SMiklos Szeredi num -= this_num; 1716a1d75f25SMiklos Szeredi offset = 0; 1717a1d75f25SMiklos Szeredi index++; 1718a1d75f25SMiklos Szeredi } 1719a1d75f25SMiklos Szeredi 1720a1d75f25SMiklos Szeredi err = 0; 1721a1d75f25SMiklos Szeredi 1722a1d75f25SMiklos Szeredi out_iput: 1723a1d75f25SMiklos Szeredi iput(inode); 1724a1d75f25SMiklos Szeredi out_up_killsb: 1725a1d75f25SMiklos Szeredi up_read(&fc->killsb); 1726a1d75f25SMiklos Szeredi out_finish: 1727a1d75f25SMiklos Szeredi fuse_copy_finish(cs); 1728a1d75f25SMiklos Szeredi return err; 1729a1d75f25SMiklos Szeredi } 1730a1d75f25SMiklos Szeredi 17312d45ba38SMiklos Szeredi static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) 17322d45ba38SMiklos Szeredi { 1733c6f92f9fSMel Gorman release_pages(req->pages, req->num_pages); 17342d45ba38SMiklos Szeredi } 17352d45ba38SMiklos Szeredi 17362d45ba38SMiklos Szeredi static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, 17372d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out *outarg) 17382d45ba38SMiklos Szeredi { 17392d45ba38SMiklos Szeredi int err; 17402d45ba38SMiklos Szeredi struct address_space *mapping = inode->i_mapping; 17412d45ba38SMiklos Szeredi struct fuse_req *req; 17422d45ba38SMiklos Szeredi pgoff_t index; 17432d45ba38SMiklos Szeredi loff_t file_size; 17442d45ba38SMiklos Szeredi unsigned int num; 17452d45ba38SMiklos Szeredi unsigned int offset; 17460157443cSGeert Uytterhoeven size_t total_len = 0; 17475da784ccSConstantine Shulyupin unsigned int num_pages; 17482d45ba38SMiklos Szeredi 174909cbfeafSKirill A. Shutemov offset = outarg->offset & ~PAGE_MASK; 17504d53dc99SMaxim Patlasov file_size = i_size_read(inode); 17514d53dc99SMaxim Patlasov 17524d53dc99SMaxim Patlasov num = outarg->size; 17534d53dc99SMaxim Patlasov if (outarg->offset > file_size) 17544d53dc99SMaxim Patlasov num = 0; 17554d53dc99SMaxim Patlasov else if (outarg->offset + num > file_size) 17564d53dc99SMaxim Patlasov num = file_size - outarg->offset; 17574d53dc99SMaxim Patlasov 17584d53dc99SMaxim Patlasov num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; 17595da784ccSConstantine Shulyupin num_pages = min(num_pages, fc->max_pages); 17604d53dc99SMaxim Patlasov 17614d53dc99SMaxim Patlasov req = fuse_get_req(fc, num_pages); 17624d53dc99SMaxim Patlasov if (IS_ERR(req)) 17634d53dc99SMaxim Patlasov return PTR_ERR(req); 17642d45ba38SMiklos Szeredi 17652d45ba38SMiklos Szeredi req->in.h.opcode = FUSE_NOTIFY_REPLY; 17662d45ba38SMiklos Szeredi req->in.h.nodeid = outarg->nodeid; 17672d45ba38SMiklos Szeredi req->in.numargs = 2; 17682d45ba38SMiklos Szeredi req->in.argpages = 1; 17692d45ba38SMiklos Szeredi req->end = fuse_retrieve_end; 17702d45ba38SMiklos Szeredi 177109cbfeafSKirill A. Shutemov index = outarg->offset >> PAGE_SHIFT; 17722d45ba38SMiklos Szeredi 17734d53dc99SMaxim Patlasov while (num && req->num_pages < num_pages) { 17742d45ba38SMiklos Szeredi struct page *page; 17752d45ba38SMiklos Szeredi unsigned int this_num; 17762d45ba38SMiklos Szeredi 17772d45ba38SMiklos Szeredi page = find_get_page(mapping, index); 17782d45ba38SMiklos Szeredi if (!page) 17792d45ba38SMiklos Szeredi break; 17802d45ba38SMiklos Szeredi 178109cbfeafSKirill A. Shutemov this_num = min_t(unsigned, num, PAGE_SIZE - offset); 17822d45ba38SMiklos Szeredi req->pages[req->num_pages] = page; 178397e1532eSMiklos Szeredi req->page_descs[req->num_pages].offset = offset; 178485f40aecSMaxim Patlasov req->page_descs[req->num_pages].length = this_num; 17852d45ba38SMiklos Szeredi req->num_pages++; 17862d45ba38SMiklos Szeredi 1787c9e67d48SMiklos Szeredi offset = 0; 17882d45ba38SMiklos Szeredi num -= this_num; 17892d45ba38SMiklos Szeredi total_len += this_num; 179048706d0aSMiklos Szeredi index++; 17912d45ba38SMiklos Szeredi } 17922d45ba38SMiklos Szeredi req->misc.retrieve_in.offset = outarg->offset; 17932d45ba38SMiklos Szeredi req->misc.retrieve_in.size = total_len; 17942d45ba38SMiklos Szeredi req->in.args[0].size = sizeof(req->misc.retrieve_in); 17952d45ba38SMiklos Szeredi req->in.args[0].value = &req->misc.retrieve_in; 17962d45ba38SMiklos Szeredi req->in.args[1].size = total_len; 17972d45ba38SMiklos Szeredi 17982d45ba38SMiklos Szeredi err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique); 17997fabaf30SMiklos Szeredi if (err) { 18002d45ba38SMiklos Szeredi fuse_retrieve_end(fc, req); 18017fabaf30SMiklos Szeredi fuse_put_request(fc, req); 18027fabaf30SMiklos Szeredi } 18032d45ba38SMiklos Szeredi 18042d45ba38SMiklos Szeredi return err; 18052d45ba38SMiklos Szeredi } 18062d45ba38SMiklos Szeredi 18072d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, 18082d45ba38SMiklos Szeredi struct fuse_copy_state *cs) 18092d45ba38SMiklos Szeredi { 18102d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out outarg; 18112d45ba38SMiklos Szeredi struct inode *inode; 18122d45ba38SMiklos Szeredi int err; 18132d45ba38SMiklos Szeredi 18142d45ba38SMiklos Szeredi err = -EINVAL; 18152d45ba38SMiklos Szeredi if (size != sizeof(outarg)) 18162d45ba38SMiklos Szeredi goto copy_finish; 18172d45ba38SMiklos Szeredi 18182d45ba38SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 18192d45ba38SMiklos Szeredi if (err) 18202d45ba38SMiklos Szeredi goto copy_finish; 18212d45ba38SMiklos Szeredi 18222d45ba38SMiklos Szeredi fuse_copy_finish(cs); 18232d45ba38SMiklos Szeredi 18242d45ba38SMiklos Szeredi down_read(&fc->killsb); 18252d45ba38SMiklos Szeredi err = -ENOENT; 18262d45ba38SMiklos Szeredi if (fc->sb) { 18272d45ba38SMiklos Szeredi u64 nodeid = outarg.nodeid; 18282d45ba38SMiklos Szeredi 18292d45ba38SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 18302d45ba38SMiklos Szeredi if (inode) { 18312d45ba38SMiklos Szeredi err = fuse_retrieve(fc, inode, &outarg); 18322d45ba38SMiklos Szeredi iput(inode); 18332d45ba38SMiklos Szeredi } 18342d45ba38SMiklos Szeredi } 18352d45ba38SMiklos Szeredi up_read(&fc->killsb); 18362d45ba38SMiklos Szeredi 18372d45ba38SMiklos Szeredi return err; 18382d45ba38SMiklos Szeredi 18392d45ba38SMiklos Szeredi copy_finish: 18402d45ba38SMiklos Szeredi fuse_copy_finish(cs); 18412d45ba38SMiklos Szeredi return err; 18422d45ba38SMiklos Szeredi } 18432d45ba38SMiklos Szeredi 18448599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, 18458599396bSTejun Heo unsigned int size, struct fuse_copy_state *cs) 18468599396bSTejun Heo { 18470d278362SMiklos Szeredi /* Don't try to move pages (yet) */ 18480d278362SMiklos Szeredi cs->move_pages = 0; 18490d278362SMiklos Szeredi 18508599396bSTejun Heo switch (code) { 185195668a69STejun Heo case FUSE_NOTIFY_POLL: 185295668a69STejun Heo return fuse_notify_poll(fc, size, cs); 185395668a69STejun Heo 18543b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_INODE: 18553b463ae0SJohn Muir return fuse_notify_inval_inode(fc, size, cs); 18563b463ae0SJohn Muir 18573b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_ENTRY: 18583b463ae0SJohn Muir return fuse_notify_inval_entry(fc, size, cs); 18593b463ae0SJohn Muir 1860a1d75f25SMiklos Szeredi case FUSE_NOTIFY_STORE: 1861a1d75f25SMiklos Szeredi return fuse_notify_store(fc, size, cs); 1862a1d75f25SMiklos Szeredi 18632d45ba38SMiklos Szeredi case FUSE_NOTIFY_RETRIEVE: 18642d45ba38SMiklos Szeredi return fuse_notify_retrieve(fc, size, cs); 18652d45ba38SMiklos Szeredi 1866451d0f59SJohn Muir case FUSE_NOTIFY_DELETE: 1867451d0f59SJohn Muir return fuse_notify_delete(fc, size, cs); 1868451d0f59SJohn Muir 18698599396bSTejun Heo default: 1870f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 18718599396bSTejun Heo return -EINVAL; 18728599396bSTejun Heo } 18738599396bSTejun Heo } 18748599396bSTejun Heo 1875334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */ 18763a2b5b9cSMiklos Szeredi static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique) 1877334f485dSMiklos Szeredi { 1878be2ff42cSKirill Tkhai unsigned int hash = fuse_req_hash(unique); 1879334f485dSMiklos Szeredi struct fuse_req *req; 188005726acaSDong Fang 1881be2ff42cSKirill Tkhai list_for_each_entry(req, &fpq->processing[hash], list) { 18823a5358d1SKirill Tkhai if (req->in.h.unique == unique) 1883334f485dSMiklos Szeredi return req; 1884334f485dSMiklos Szeredi } 1885334f485dSMiklos Szeredi return NULL; 1886334f485dSMiklos Szeredi } 1887334f485dSMiklos Szeredi 1888334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out, 1889334f485dSMiklos Szeredi unsigned nbytes) 1890334f485dSMiklos Szeredi { 1891334f485dSMiklos Szeredi unsigned reqsize = sizeof(struct fuse_out_header); 1892334f485dSMiklos Szeredi 1893334f485dSMiklos Szeredi if (out->h.error) 1894334f485dSMiklos Szeredi return nbytes != reqsize ? -EINVAL : 0; 1895334f485dSMiklos Szeredi 1896334f485dSMiklos Szeredi reqsize += len_args(out->numargs, out->args); 1897334f485dSMiklos Szeredi 1898334f485dSMiklos Szeredi if (reqsize < nbytes || (reqsize > nbytes && !out->argvar)) 1899334f485dSMiklos Szeredi return -EINVAL; 1900334f485dSMiklos Szeredi else if (reqsize > nbytes) { 1901334f485dSMiklos Szeredi struct fuse_arg *lastarg = &out->args[out->numargs-1]; 1902334f485dSMiklos Szeredi unsigned diffsize = reqsize - nbytes; 1903334f485dSMiklos Szeredi if (diffsize > lastarg->size) 1904334f485dSMiklos Szeredi return -EINVAL; 1905334f485dSMiklos Szeredi lastarg->size -= diffsize; 1906334f485dSMiklos Szeredi } 1907334f485dSMiklos Szeredi return fuse_copy_args(cs, out->numargs, out->argpages, out->args, 1908334f485dSMiklos Szeredi out->page_zeroing); 1909334f485dSMiklos Szeredi } 1910334f485dSMiklos Szeredi 1911334f485dSMiklos Szeredi /* 1912334f485dSMiklos Szeredi * Write a single reply to a request. First the header is copied from 1913334f485dSMiklos Szeredi * the write buffer. The request is then searched on the processing 1914334f485dSMiklos Szeredi * list by the unique ID found in the header. If found, then remove 1915334f485dSMiklos Szeredi * it from the list and copy the rest of the buffer to the request. 1916334f485dSMiklos Szeredi * The request is finished by calling request_end() 1917334f485dSMiklos Szeredi */ 1918c3696046SMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_dev *fud, 1919dd3bb14fSMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1920334f485dSMiklos Szeredi { 1921334f485dSMiklos Szeredi int err; 1922c3696046SMiklos Szeredi struct fuse_conn *fc = fud->fc; 1923c3696046SMiklos Szeredi struct fuse_pqueue *fpq = &fud->pq; 1924334f485dSMiklos Szeredi struct fuse_req *req; 1925334f485dSMiklos Szeredi struct fuse_out_header oh; 1926334f485dSMiklos Szeredi 19277407a10dSKirill Tkhai err = -EINVAL; 1928334f485dSMiklos Szeredi if (nbytes < sizeof(struct fuse_out_header)) 19297407a10dSKirill Tkhai goto out; 1930334f485dSMiklos Szeredi 1931dd3bb14fSMiklos Szeredi err = fuse_copy_one(cs, &oh, sizeof(oh)); 1932334f485dSMiklos Szeredi if (err) 19337407a10dSKirill Tkhai goto copy_finish; 19348599396bSTejun Heo 1935334f485dSMiklos Szeredi err = -EINVAL; 19368599396bSTejun Heo if (oh.len != nbytes) 19377407a10dSKirill Tkhai goto copy_finish; 19388599396bSTejun Heo 19398599396bSTejun Heo /* 19408599396bSTejun Heo * Zero oh.unique indicates unsolicited notification message 19418599396bSTejun Heo * and error contains notification code. 19428599396bSTejun Heo */ 19438599396bSTejun Heo if (!oh.unique) { 1944dd3bb14fSMiklos Szeredi err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs); 19457407a10dSKirill Tkhai goto out; 19468599396bSTejun Heo } 19478599396bSTejun Heo 19488599396bSTejun Heo err = -EINVAL; 19498599396bSTejun Heo if (oh.error <= -1000 || oh.error > 0) 19507407a10dSKirill Tkhai goto copy_finish; 1951334f485dSMiklos Szeredi 195245a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 19537407a10dSKirill Tkhai req = NULL; 19547407a10dSKirill Tkhai if (fpq->connected) 19553a5358d1SKirill Tkhai req = request_find(fpq, oh.unique & ~FUSE_INT_REQ_BIT); 19567407a10dSKirill Tkhai 19577407a10dSKirill Tkhai err = -ENOENT; 19587407a10dSKirill Tkhai if (!req) { 19597407a10dSKirill Tkhai spin_unlock(&fpq->lock); 19607407a10dSKirill Tkhai goto copy_finish; 19617407a10dSKirill Tkhai } 1962334f485dSMiklos Szeredi 19633a5358d1SKirill Tkhai /* Is it an interrupt reply ID? */ 19643a5358d1SKirill Tkhai if (oh.unique & FUSE_INT_REQ_BIT) { 1965d2d2d4fbSKirill Tkhai __fuse_get_request(req); 196645a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 196745a91cb1SMiklos Szeredi 19687407a10dSKirill Tkhai err = 0; 19697407a10dSKirill Tkhai if (nbytes != sizeof(struct fuse_out_header)) 1970a4d27e75SMiklos Szeredi err = -EINVAL; 19717407a10dSKirill Tkhai else if (oh.error == -ENOSYS) 1972a4d27e75SMiklos Szeredi fc->no_interrupt = 1; 1973a4d27e75SMiklos Szeredi else if (oh.error == -EAGAIN) 1974b782911bSKirill Tkhai err = queue_interrupt(&fc->iq, req); 19757407a10dSKirill Tkhai 1976d2d2d4fbSKirill Tkhai fuse_put_request(fc, req); 1977a4d27e75SMiklos Szeredi 19787407a10dSKirill Tkhai goto copy_finish; 1979a4d27e75SMiklos Szeredi } 1980a4d27e75SMiklos Szeredi 198133e14b4dSMiklos Szeredi clear_bit(FR_SENT, &req->flags); 19823a2b5b9cSMiklos Szeredi list_move(&req->list, &fpq->io); 1983334f485dSMiklos Szeredi req->out.h = oh; 1984825d6d33SMiklos Szeredi set_bit(FR_LOCKED, &req->flags); 198545a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 1986dd3bb14fSMiklos Szeredi cs->req = req; 1987ce534fb0SMiklos Szeredi if (!req->out.page_replace) 1988ce534fb0SMiklos Szeredi cs->move_pages = 0; 1989334f485dSMiklos Szeredi 1990dd3bb14fSMiklos Szeredi err = copy_out_args(cs, &req->out, nbytes); 1991dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1992334f485dSMiklos Szeredi 199345a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 1994825d6d33SMiklos Szeredi clear_bit(FR_LOCKED, &req->flags); 1995e96edd94SMiklos Szeredi if (!fpq->connected) 1996334f485dSMiklos Szeredi err = -ENOENT; 19970d8e84b0SMiklos Szeredi else if (err) 1998334f485dSMiklos Szeredi req->out.h.error = -EIO; 199977cd9d48SMiklos Szeredi if (!test_bit(FR_PRIVATE, &req->flags)) 2000f377cb79SMiklos Szeredi list_del_init(&req->list); 200145a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 200246c34a34SMiklos Szeredi 2003334f485dSMiklos Szeredi request_end(fc, req); 20047407a10dSKirill Tkhai out: 2005334f485dSMiklos Szeredi return err ? err : nbytes; 2006334f485dSMiklos Szeredi 20077407a10dSKirill Tkhai copy_finish: 2008dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 20097407a10dSKirill Tkhai goto out; 2010334f485dSMiklos Szeredi } 2011334f485dSMiklos Szeredi 2012fbdbaccaSAl Viro static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from) 2013dd3bb14fSMiklos Szeredi { 2014dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 2015cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(iocb->ki_filp); 2016cc080e9eSMiklos Szeredi 2017cc080e9eSMiklos Szeredi if (!fud) 2018dd3bb14fSMiklos Szeredi return -EPERM; 2019dd3bb14fSMiklos Szeredi 2020fbdbaccaSAl Viro if (!iter_is_iovec(from)) 2021fbdbaccaSAl Viro return -EINVAL; 2022dd3bb14fSMiklos Szeredi 2023dc00809aSMiklos Szeredi fuse_copy_init(&cs, 0, from); 2024fbdbaccaSAl Viro 2025c3696046SMiklos Szeredi return fuse_dev_do_write(fud, &cs, iov_iter_count(from)); 2026dd3bb14fSMiklos Szeredi } 2027dd3bb14fSMiklos Szeredi 2028dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, 2029dd3bb14fSMiklos Szeredi struct file *out, loff_t *ppos, 2030dd3bb14fSMiklos Szeredi size_t len, unsigned int flags) 2031dd3bb14fSMiklos Szeredi { 2032dd3bb14fSMiklos Szeredi unsigned nbuf; 2033dd3bb14fSMiklos Szeredi unsigned idx; 2034dd3bb14fSMiklos Szeredi struct pipe_buffer *bufs; 2035dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 2036cc080e9eSMiklos Szeredi struct fuse_dev *fud; 2037dd3bb14fSMiklos Szeredi size_t rem; 2038dd3bb14fSMiklos Szeredi ssize_t ret; 2039dd3bb14fSMiklos Szeredi 2040cc080e9eSMiklos Szeredi fud = fuse_get_dev(out); 2041cc080e9eSMiklos Szeredi if (!fud) 2042dd3bb14fSMiklos Szeredi return -EPERM; 2043dd3bb14fSMiklos Szeredi 2044a2477b0eSAndrey Ryabinin pipe_lock(pipe); 2045a2477b0eSAndrey Ryabinin 204696354535SAndrey Ryabinin bufs = kvmalloc_array(pipe->nrbufs, sizeof(struct pipe_buffer), 20476da2ec56SKees Cook GFP_KERNEL); 2048a2477b0eSAndrey Ryabinin if (!bufs) { 2049a2477b0eSAndrey Ryabinin pipe_unlock(pipe); 2050dd3bb14fSMiklos Szeredi return -ENOMEM; 2051a2477b0eSAndrey Ryabinin } 2052dd3bb14fSMiklos Szeredi 2053dd3bb14fSMiklos Szeredi nbuf = 0; 2054dd3bb14fSMiklos Szeredi rem = 0; 2055dd3bb14fSMiklos Szeredi for (idx = 0; idx < pipe->nrbufs && rem < len; idx++) 2056dd3bb14fSMiklos Szeredi rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len; 2057dd3bb14fSMiklos Szeredi 2058dd3bb14fSMiklos Szeredi ret = -EINVAL; 2059dd3bb14fSMiklos Szeredi if (rem < len) { 2060dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 2061dd3bb14fSMiklos Szeredi goto out; 2062dd3bb14fSMiklos Szeredi } 2063dd3bb14fSMiklos Szeredi 2064dd3bb14fSMiklos Szeredi rem = len; 2065dd3bb14fSMiklos Szeredi while (rem) { 2066dd3bb14fSMiklos Szeredi struct pipe_buffer *ibuf; 2067dd3bb14fSMiklos Szeredi struct pipe_buffer *obuf; 2068dd3bb14fSMiklos Szeredi 2069dd3bb14fSMiklos Szeredi BUG_ON(nbuf >= pipe->buffers); 2070dd3bb14fSMiklos Szeredi BUG_ON(!pipe->nrbufs); 2071dd3bb14fSMiklos Szeredi ibuf = &pipe->bufs[pipe->curbuf]; 2072dd3bb14fSMiklos Szeredi obuf = &bufs[nbuf]; 2073dd3bb14fSMiklos Szeredi 2074dd3bb14fSMiklos Szeredi if (rem >= ibuf->len) { 2075dd3bb14fSMiklos Szeredi *obuf = *ibuf; 2076dd3bb14fSMiklos Szeredi ibuf->ops = NULL; 2077dd3bb14fSMiklos Szeredi pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); 2078dd3bb14fSMiklos Szeredi pipe->nrbufs--; 2079dd3bb14fSMiklos Szeredi } else { 20807bf2d1dfSMiklos Szeredi pipe_buf_get(pipe, ibuf); 2081dd3bb14fSMiklos Szeredi *obuf = *ibuf; 2082dd3bb14fSMiklos Szeredi obuf->flags &= ~PIPE_BUF_FLAG_GIFT; 2083dd3bb14fSMiklos Szeredi obuf->len = rem; 2084dd3bb14fSMiklos Szeredi ibuf->offset += obuf->len; 2085dd3bb14fSMiklos Szeredi ibuf->len -= obuf->len; 2086dd3bb14fSMiklos Szeredi } 2087dd3bb14fSMiklos Szeredi nbuf++; 2088dd3bb14fSMiklos Szeredi rem -= obuf->len; 2089dd3bb14fSMiklos Szeredi } 2090dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 2091dd3bb14fSMiklos Szeredi 2092dc00809aSMiklos Szeredi fuse_copy_init(&cs, 0, NULL); 2093dd3bb14fSMiklos Szeredi cs.pipebufs = bufs; 20946c09e94aSAl Viro cs.nr_segs = nbuf; 2095dd3bb14fSMiklos Szeredi cs.pipe = pipe; 2096dd3bb14fSMiklos Szeredi 2097ce534fb0SMiklos Szeredi if (flags & SPLICE_F_MOVE) 2098ce534fb0SMiklos Szeredi cs.move_pages = 1; 2099ce534fb0SMiklos Szeredi 2100c3696046SMiklos Szeredi ret = fuse_dev_do_write(fud, &cs, len); 2101dd3bb14fSMiklos Szeredi 21029509941eSJann Horn pipe_lock(pipe); 2103a779638cSMiklos Szeredi for (idx = 0; idx < nbuf; idx++) 2104a779638cSMiklos Szeredi pipe_buf_release(pipe, &bufs[idx]); 21059509941eSJann Horn pipe_unlock(pipe); 2106a779638cSMiklos Szeredi 2107dd3bb14fSMiklos Szeredi out: 2108d6d931adSAndrey Ryabinin kvfree(bufs); 2109dd3bb14fSMiklos Szeredi return ret; 2110dd3bb14fSMiklos Szeredi } 2111dd3bb14fSMiklos Szeredi 2112076ccb76SAl Viro static __poll_t fuse_dev_poll(struct file *file, poll_table *wait) 2113334f485dSMiklos Szeredi { 2114a9a08845SLinus Torvalds __poll_t mask = EPOLLOUT | EPOLLWRNORM; 2115f88996a9SMiklos Szeredi struct fuse_iqueue *fiq; 2116cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(file); 2117cc080e9eSMiklos Szeredi 2118cc080e9eSMiklos Szeredi if (!fud) 2119a9a08845SLinus Torvalds return EPOLLERR; 2120334f485dSMiklos Szeredi 2121cc080e9eSMiklos Szeredi fiq = &fud->fc->iq; 2122f88996a9SMiklos Szeredi poll_wait(file, &fiq->waitq, wait); 2123334f485dSMiklos Szeredi 21244ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 2125e16714d8SMiklos Szeredi if (!fiq->connected) 2126a9a08845SLinus Torvalds mask = EPOLLERR; 2127f88996a9SMiklos Szeredi else if (request_pending(fiq)) 2128a9a08845SLinus Torvalds mask |= EPOLLIN | EPOLLRDNORM; 21294ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 2130334f485dSMiklos Szeredi 2131334f485dSMiklos Szeredi return mask; 2132334f485dSMiklos Szeredi } 2133334f485dSMiklos Szeredi 213434061750SKirill Tkhai /* Abort all requests on the given list (pending or processing) */ 2135334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head) 2136334f485dSMiklos Szeredi { 2137334f485dSMiklos Szeredi while (!list_empty(head)) { 2138334f485dSMiklos Szeredi struct fuse_req *req; 2139334f485dSMiklos Szeredi req = list_entry(head->next, struct fuse_req, list); 2140334f485dSMiklos Szeredi req->out.h.error = -ECONNABORTED; 214133e14b4dSMiklos Szeredi clear_bit(FR_SENT, &req->flags); 2142f377cb79SMiklos Szeredi list_del_init(&req->list); 2143334f485dSMiklos Szeredi request_end(fc, req); 2144334f485dSMiklos Szeredi } 2145334f485dSMiklos Szeredi } 2146334f485dSMiklos Szeredi 2147357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc) 2148357ccf2bSBryan Green { 2149357ccf2bSBryan Green struct rb_node *p; 2150357ccf2bSBryan Green 2151357ccf2bSBryan Green p = rb_first(&fc->polled_files); 2152357ccf2bSBryan Green 2153357ccf2bSBryan Green while (p) { 2154357ccf2bSBryan Green struct fuse_file *ff; 2155357ccf2bSBryan Green ff = rb_entry(p, struct fuse_file, polled_node); 2156357ccf2bSBryan Green wake_up_interruptible_all(&ff->poll_wait); 2157357ccf2bSBryan Green 2158357ccf2bSBryan Green p = rb_next(p); 2159357ccf2bSBryan Green } 2160357ccf2bSBryan Green } 2161357ccf2bSBryan Green 216269a53bf2SMiklos Szeredi /* 216369a53bf2SMiklos Szeredi * Abort all requests. 216469a53bf2SMiklos Szeredi * 2165b716d425SMiklos Szeredi * Emergency exit in case of a malicious or accidental deadlock, or just a hung 2166b716d425SMiklos Szeredi * filesystem. 216769a53bf2SMiklos Szeredi * 2168b716d425SMiklos Szeredi * The same effect is usually achievable through killing the filesystem daemon 2169b716d425SMiklos Szeredi * and all users of the filesystem. The exception is the combination of an 2170b716d425SMiklos Szeredi * asynchronous request and the tricky deadlock (see 2171b716d425SMiklos Szeredi * Documentation/filesystems/fuse.txt). 217269a53bf2SMiklos Szeredi * 2173b716d425SMiklos Szeredi * Aborting requests under I/O goes as follows: 1: Separate out unlocked 2174b716d425SMiklos Szeredi * requests, they should be finished off immediately. Locked requests will be 2175b716d425SMiklos Szeredi * finished after unlock; see unlock_request(). 2: Finish off the unlocked 2176b716d425SMiklos Szeredi * requests. It is possible that some request will finish before we can. This 2177b716d425SMiklos Szeredi * is OK, the request will in that case be removed from the list before we touch 2178b716d425SMiklos Szeredi * it. 217969a53bf2SMiklos Szeredi */ 2180eb98e3bdSMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc) 218169a53bf2SMiklos Szeredi { 2182f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 2183f88996a9SMiklos Szeredi 2184d7133114SMiklos Szeredi spin_lock(&fc->lock); 218569a53bf2SMiklos Szeredi if (fc->connected) { 2186c3696046SMiklos Szeredi struct fuse_dev *fud; 2187b716d425SMiklos Szeredi struct fuse_req *req, *next; 218875f3ee4cSMiklos Szeredi LIST_HEAD(to_end); 2189be2ff42cSKirill Tkhai unsigned int i; 2190b716d425SMiklos Szeredi 219163825b4eSKirill Tkhai /* Background queuing checks fc->connected under bg_lock */ 219263825b4eSKirill Tkhai spin_lock(&fc->bg_lock); 219369a53bf2SMiklos Szeredi fc->connected = 0; 219463825b4eSKirill Tkhai spin_unlock(&fc->bg_lock); 219563825b4eSKirill Tkhai 21969759bd51SMiklos Szeredi fuse_set_initialized(fc); 2197c3696046SMiklos Szeredi list_for_each_entry(fud, &fc->devices, entry) { 2198c3696046SMiklos Szeredi struct fuse_pqueue *fpq = &fud->pq; 2199c3696046SMiklos Szeredi 220045a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 2201e96edd94SMiklos Szeredi fpq->connected = 0; 22023a2b5b9cSMiklos Szeredi list_for_each_entry_safe(req, next, &fpq->io, list) { 2203b716d425SMiklos Szeredi req->out.h.error = -ECONNABORTED; 2204b716d425SMiklos Szeredi spin_lock(&req->waitq.lock); 2205b716d425SMiklos Szeredi set_bit(FR_ABORTED, &req->flags); 220677cd9d48SMiklos Szeredi if (!test_bit(FR_LOCKED, &req->flags)) { 220777cd9d48SMiklos Szeredi set_bit(FR_PRIVATE, &req->flags); 220887114373SMiklos Szeredi __fuse_get_request(req); 220975f3ee4cSMiklos Szeredi list_move(&req->list, &to_end); 221077cd9d48SMiklos Szeredi } 2211b716d425SMiklos Szeredi spin_unlock(&req->waitq.lock); 2212b716d425SMiklos Szeredi } 2213be2ff42cSKirill Tkhai for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) 2214be2ff42cSKirill Tkhai list_splice_tail_init(&fpq->processing[i], 2215be2ff42cSKirill Tkhai &to_end); 221645a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 2217c3696046SMiklos Szeredi } 2218ae2dffa3SKirill Tkhai spin_lock(&fc->bg_lock); 2219ae2dffa3SKirill Tkhai fc->blocked = 0; 222041f98274SMiklos Szeredi fc->max_background = UINT_MAX; 222141f98274SMiklos Szeredi flush_bg_queue(fc); 2222ae2dffa3SKirill Tkhai spin_unlock(&fc->bg_lock); 22238c91189aSMiklos Szeredi 22244ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 22258c91189aSMiklos Szeredi fiq->connected = 0; 222675f3ee4cSMiklos Szeredi list_for_each_entry(req, &fiq->pending, list) 2227a8a86d78STahsin Erdogan clear_bit(FR_PENDING, &req->flags); 222875f3ee4cSMiklos Szeredi list_splice_tail_init(&fiq->pending, &to_end); 22298c91189aSMiklos Szeredi while (forget_pending(fiq)) 22308c91189aSMiklos Szeredi kfree(dequeue_forget(fiq, 1, NULL)); 22314ce60812SMiklos Szeredi wake_up_all_locked(&fiq->waitq); 22324ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 22338c91189aSMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 2234ee314a87SMiklos Szeredi end_polls(fc); 2235ee314a87SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 2236ee314a87SMiklos Szeredi spin_unlock(&fc->lock); 22378c91189aSMiklos Szeredi 223875f3ee4cSMiklos Szeredi end_requests(fc, &to_end); 2239ee314a87SMiklos Szeredi } else { 2240d7133114SMiklos Szeredi spin_unlock(&fc->lock); 224169a53bf2SMiklos Szeredi } 2242ee314a87SMiklos Szeredi } 224308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn); 224469a53bf2SMiklos Szeredi 2245b8f95e5dSMiklos Szeredi void fuse_wait_aborted(struct fuse_conn *fc) 2246b8f95e5dSMiklos Szeredi { 22472d84a2d1SMiklos Szeredi /* matches implicit memory barrier in fuse_drop_waiting() */ 22482d84a2d1SMiklos Szeredi smp_mb(); 2249b8f95e5dSMiklos Szeredi wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0); 2250b8f95e5dSMiklos Szeredi } 2251b8f95e5dSMiklos Szeredi 225208cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file) 2253334f485dSMiklos Szeredi { 2254cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(file); 2255cc080e9eSMiklos Szeredi 2256cc080e9eSMiklos Szeredi if (fud) { 2257cc080e9eSMiklos Szeredi struct fuse_conn *fc = fud->fc; 2258c3696046SMiklos Szeredi struct fuse_pqueue *fpq = &fud->pq; 225945ff350bSMiklos Szeredi LIST_HEAD(to_end); 2260be2ff42cSKirill Tkhai unsigned int i; 2261cc080e9eSMiklos Szeredi 226245ff350bSMiklos Szeredi spin_lock(&fpq->lock); 2263c3696046SMiklos Szeredi WARN_ON(!list_empty(&fpq->io)); 2264be2ff42cSKirill Tkhai for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) 2265be2ff42cSKirill Tkhai list_splice_init(&fpq->processing[i], &to_end); 226645ff350bSMiklos Szeredi spin_unlock(&fpq->lock); 226745ff350bSMiklos Szeredi 226845ff350bSMiklos Szeredi end_requests(fc, &to_end); 226945ff350bSMiklos Szeredi 2270c3696046SMiklos Szeredi /* Are we the last open device? */ 2271c3696046SMiklos Szeredi if (atomic_dec_and_test(&fc->dev_count)) { 2272f88996a9SMiklos Szeredi WARN_ON(fc->iq.fasync != NULL); 2273eb98e3bdSMiklos Szeredi fuse_abort_conn(fc); 2274c3696046SMiklos Szeredi } 2275cc080e9eSMiklos Szeredi fuse_dev_free(fud); 2276385a17bfSJeff Dike } 2277334f485dSMiklos Szeredi return 0; 2278334f485dSMiklos Szeredi } 227908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release); 2280334f485dSMiklos Szeredi 2281385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on) 2282385a17bfSJeff Dike { 2283cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(file); 2284cc080e9eSMiklos Szeredi 2285cc080e9eSMiklos Szeredi if (!fud) 2286a87046d8SMiklos Szeredi return -EPERM; 2287385a17bfSJeff Dike 2288385a17bfSJeff Dike /* No locking - fasync_helper does its own locking */ 2289cc080e9eSMiklos Szeredi return fasync_helper(fd, file, on, &fud->fc->iq.fasync); 2290385a17bfSJeff Dike } 2291385a17bfSJeff Dike 229200c570f4SMiklos Szeredi static int fuse_device_clone(struct fuse_conn *fc, struct file *new) 229300c570f4SMiklos Szeredi { 2294cc080e9eSMiklos Szeredi struct fuse_dev *fud; 2295cc080e9eSMiklos Szeredi 229600c570f4SMiklos Szeredi if (new->private_data) 229700c570f4SMiklos Szeredi return -EINVAL; 229800c570f4SMiklos Szeredi 2299cc080e9eSMiklos Szeredi fud = fuse_dev_alloc(fc); 2300cc080e9eSMiklos Szeredi if (!fud) 2301cc080e9eSMiklos Szeredi return -ENOMEM; 2302cc080e9eSMiklos Szeredi 2303cc080e9eSMiklos Szeredi new->private_data = fud; 2304c3696046SMiklos Szeredi atomic_inc(&fc->dev_count); 230500c570f4SMiklos Szeredi 230600c570f4SMiklos Szeredi return 0; 230700c570f4SMiklos Szeredi } 230800c570f4SMiklos Szeredi 230900c570f4SMiklos Szeredi static long fuse_dev_ioctl(struct file *file, unsigned int cmd, 231000c570f4SMiklos Szeredi unsigned long arg) 231100c570f4SMiklos Szeredi { 231200c570f4SMiklos Szeredi int err = -ENOTTY; 231300c570f4SMiklos Szeredi 231400c570f4SMiklos Szeredi if (cmd == FUSE_DEV_IOC_CLONE) { 231500c570f4SMiklos Szeredi int oldfd; 231600c570f4SMiklos Szeredi 231700c570f4SMiklos Szeredi err = -EFAULT; 231800c570f4SMiklos Szeredi if (!get_user(oldfd, (__u32 __user *) arg)) { 231900c570f4SMiklos Szeredi struct file *old = fget(oldfd); 232000c570f4SMiklos Szeredi 232100c570f4SMiklos Szeredi err = -EINVAL; 232200c570f4SMiklos Szeredi if (old) { 23238ed1f0e2SJann Horn struct fuse_dev *fud = NULL; 23248ed1f0e2SJann Horn 23258ed1f0e2SJann Horn /* 23268ed1f0e2SJann Horn * Check against file->f_op because CUSE 23278ed1f0e2SJann Horn * uses the same ioctl handler. 23288ed1f0e2SJann Horn */ 23298ed1f0e2SJann Horn if (old->f_op == file->f_op && 23308ed1f0e2SJann Horn old->f_cred->user_ns == file->f_cred->user_ns) 23318ed1f0e2SJann Horn fud = fuse_get_dev(old); 233200c570f4SMiklos Szeredi 2333cc080e9eSMiklos Szeredi if (fud) { 233400c570f4SMiklos Szeredi mutex_lock(&fuse_mutex); 2335cc080e9eSMiklos Szeredi err = fuse_device_clone(fud->fc, file); 233600c570f4SMiklos Szeredi mutex_unlock(&fuse_mutex); 233700c570f4SMiklos Szeredi } 233800c570f4SMiklos Szeredi fput(old); 233900c570f4SMiklos Szeredi } 234000c570f4SMiklos Szeredi } 234100c570f4SMiklos Szeredi } 234200c570f4SMiklos Szeredi return err; 234300c570f4SMiklos Szeredi } 234400c570f4SMiklos Szeredi 23454b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = { 2346334f485dSMiklos Szeredi .owner = THIS_MODULE, 234794e4fe2cSTom Van Braeckel .open = fuse_dev_open, 2348334f485dSMiklos Szeredi .llseek = no_llseek, 2349fbdbaccaSAl Viro .read_iter = fuse_dev_read, 2350c3021629SMiklos Szeredi .splice_read = fuse_dev_splice_read, 2351fbdbaccaSAl Viro .write_iter = fuse_dev_write, 2352dd3bb14fSMiklos Szeredi .splice_write = fuse_dev_splice_write, 2353334f485dSMiklos Szeredi .poll = fuse_dev_poll, 2354334f485dSMiklos Szeredi .release = fuse_dev_release, 2355385a17bfSJeff Dike .fasync = fuse_dev_fasync, 235600c570f4SMiklos Szeredi .unlocked_ioctl = fuse_dev_ioctl, 235700c570f4SMiklos Szeredi .compat_ioctl = fuse_dev_ioctl, 2358334f485dSMiklos Szeredi }; 235908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations); 2360334f485dSMiklos Szeredi 2361334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = { 2362334f485dSMiklos Szeredi .minor = FUSE_MINOR, 2363334f485dSMiklos Szeredi .name = "fuse", 2364334f485dSMiklos Szeredi .fops = &fuse_dev_operations, 2365334f485dSMiklos Szeredi }; 2366334f485dSMiklos Szeredi 2367334f485dSMiklos Szeredi int __init fuse_dev_init(void) 2368334f485dSMiklos Szeredi { 2369334f485dSMiklos Szeredi int err = -ENOMEM; 2370334f485dSMiklos Szeredi fuse_req_cachep = kmem_cache_create("fuse_request", 2371334f485dSMiklos Szeredi sizeof(struct fuse_req), 237220c2df83SPaul Mundt 0, 0, NULL); 2373334f485dSMiklos Szeredi if (!fuse_req_cachep) 2374334f485dSMiklos Szeredi goto out; 2375334f485dSMiklos Szeredi 2376334f485dSMiklos Szeredi err = misc_register(&fuse_miscdevice); 2377334f485dSMiklos Szeredi if (err) 2378334f485dSMiklos Szeredi goto out_cache_clean; 2379334f485dSMiklos Szeredi 2380334f485dSMiklos Szeredi return 0; 2381334f485dSMiklos Szeredi 2382334f485dSMiklos Szeredi out_cache_clean: 2383334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2384334f485dSMiklos Szeredi out: 2385334f485dSMiklos Szeredi return err; 2386334f485dSMiklos Szeredi } 2387334f485dSMiklos Szeredi 2388334f485dSMiklos Szeredi void fuse_dev_cleanup(void) 2389334f485dSMiklos Szeredi { 2390334f485dSMiklos Szeredi misc_deregister(&fuse_miscdevice); 2391334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2392334f485dSMiklos Szeredi } 2393