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 28e18b890bSChristoph Lameter static struct kmem_cache *fuse_req_cachep; 29334f485dSMiklos Szeredi 30cc080e9eSMiklos Szeredi static struct fuse_dev *fuse_get_dev(struct file *file) 31334f485dSMiklos Szeredi { 320720b315SMiklos Szeredi /* 330720b315SMiklos Szeredi * Lockless access is OK, because file->private data is set 340720b315SMiklos Szeredi * once during mount and is valid until the file is released. 350720b315SMiklos Szeredi */ 366aa7de05SMark Rutland return READ_ONCE(file->private_data); 37334f485dSMiklos Szeredi } 38334f485dSMiklos Szeredi 394250c066SMaxim Patlasov static void fuse_request_init(struct fuse_req *req, struct page **pages, 40b2430d75SMaxim Patlasov struct fuse_page_desc *page_descs, 414250c066SMaxim Patlasov unsigned npages) 42334f485dSMiklos Szeredi { 43334f485dSMiklos Szeredi memset(req, 0, sizeof(*req)); 444250c066SMaxim Patlasov memset(pages, 0, sizeof(*pages) * npages); 45b2430d75SMaxim Patlasov memset(page_descs, 0, sizeof(*page_descs) * npages); 46334f485dSMiklos Szeredi INIT_LIST_HEAD(&req->list); 47a4d27e75SMiklos Szeredi INIT_LIST_HEAD(&req->intr_entry); 48334f485dSMiklos Szeredi init_waitqueue_head(&req->waitq); 49ec99f6d3SElena Reshetova refcount_set(&req->count, 1); 504250c066SMaxim Patlasov req->pages = pages; 51b2430d75SMaxim Patlasov req->page_descs = page_descs; 524250c066SMaxim Patlasov req->max_pages = npages; 5333e14b4dSMiklos Szeredi __set_bit(FR_PENDING, &req->flags); 54334f485dSMiklos Szeredi } 55334f485dSMiklos Szeredi 564250c066SMaxim Patlasov static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) 57334f485dSMiklos Szeredi { 584250c066SMaxim Patlasov struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, flags); 594250c066SMaxim Patlasov if (req) { 604250c066SMaxim Patlasov struct page **pages; 61b2430d75SMaxim Patlasov struct fuse_page_desc *page_descs; 624250c066SMaxim Patlasov 63b2430d75SMaxim Patlasov if (npages <= FUSE_REQ_INLINE_PAGES) { 644250c066SMaxim Patlasov pages = req->inline_pages; 65b2430d75SMaxim Patlasov page_descs = req->inline_page_descs; 66b2430d75SMaxim Patlasov } else { 674250c066SMaxim Patlasov pages = kmalloc(sizeof(struct page *) * npages, flags); 68b2430d75SMaxim Patlasov page_descs = kmalloc(sizeof(struct fuse_page_desc) * 69b2430d75SMaxim Patlasov npages, flags); 70b2430d75SMaxim Patlasov } 714250c066SMaxim Patlasov 72b2430d75SMaxim Patlasov if (!pages || !page_descs) { 73b2430d75SMaxim Patlasov kfree(pages); 74b2430d75SMaxim Patlasov kfree(page_descs); 754250c066SMaxim Patlasov kmem_cache_free(fuse_req_cachep, req); 764250c066SMaxim Patlasov return NULL; 774250c066SMaxim Patlasov } 784250c066SMaxim Patlasov 79b2430d75SMaxim Patlasov fuse_request_init(req, pages, page_descs, npages); 804250c066SMaxim Patlasov } 81334f485dSMiklos Szeredi return req; 82334f485dSMiklos Szeredi } 834250c066SMaxim Patlasov 844250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc(unsigned npages) 854250c066SMaxim Patlasov { 864250c066SMaxim Patlasov return __fuse_request_alloc(npages, GFP_KERNEL); 874250c066SMaxim Patlasov } 8808cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_alloc); 89334f485dSMiklos Szeredi 904250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc_nofs(unsigned npages) 913be5a52bSMiklos Szeredi { 924250c066SMaxim Patlasov return __fuse_request_alloc(npages, GFP_NOFS); 933be5a52bSMiklos Szeredi } 943be5a52bSMiklos Szeredi 95334f485dSMiklos Szeredi void fuse_request_free(struct fuse_req *req) 96334f485dSMiklos Szeredi { 97b2430d75SMaxim Patlasov if (req->pages != req->inline_pages) { 984250c066SMaxim Patlasov kfree(req->pages); 99b2430d75SMaxim Patlasov kfree(req->page_descs); 100b2430d75SMaxim Patlasov } 101334f485dSMiklos Szeredi kmem_cache_free(fuse_req_cachep, req); 102334f485dSMiklos Szeredi } 103334f485dSMiklos Szeredi 10436cf66edSMaxim Patlasov void __fuse_get_request(struct fuse_req *req) 105334f485dSMiklos Szeredi { 106ec99f6d3SElena Reshetova refcount_inc(&req->count); 107334f485dSMiklos Szeredi } 108334f485dSMiklos Szeredi 109334f485dSMiklos Szeredi /* Must be called with > 1 refcount */ 110334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req) 111334f485dSMiklos Szeredi { 112ec99f6d3SElena Reshetova refcount_dec(&req->count); 113334f485dSMiklos Szeredi } 114334f485dSMiklos Szeredi 1150b6e9ea0SSeth Forshee static void fuse_req_init_context(struct fuse_conn *fc, struct fuse_req *req) 11633649c91SMiklos Szeredi { 117499dcf20SEric W. Biederman req->in.h.uid = from_kuid_munged(&init_user_ns, current_fsuid()); 118499dcf20SEric W. Biederman req->in.h.gid = from_kgid_munged(&init_user_ns, current_fsgid()); 1190b6e9ea0SSeth Forshee req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns); 12033649c91SMiklos Szeredi } 12133649c91SMiklos Szeredi 1229759bd51SMiklos Szeredi void fuse_set_initialized(struct fuse_conn *fc) 1239759bd51SMiklos Szeredi { 1249759bd51SMiklos Szeredi /* Make sure stores before this are seen on another CPU */ 1259759bd51SMiklos Szeredi smp_wmb(); 1269759bd51SMiklos Szeredi fc->initialized = 1; 1279759bd51SMiklos Szeredi } 1289759bd51SMiklos Szeredi 1290aada884SMaxim Patlasov static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background) 1300aada884SMaxim Patlasov { 1310aada884SMaxim Patlasov return !fc->initialized || (for_background && fc->blocked); 1320aada884SMaxim Patlasov } 1330aada884SMaxim Patlasov 1348b41e671SMaxim Patlasov static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages, 1358b41e671SMaxim Patlasov bool for_background) 136334f485dSMiklos Szeredi { 13708a53cdcSMiklos Szeredi struct fuse_req *req; 1380aada884SMaxim Patlasov int err; 1390aada884SMaxim Patlasov atomic_inc(&fc->num_waiting); 1400aada884SMaxim Patlasov 1410aada884SMaxim Patlasov if (fuse_block_alloc(fc, for_background)) { 1429bc5dddaSMiklos Szeredi err = -EINTR; 1437d3a07fcSAl Viro if (wait_event_killable_exclusive(fc->blocked_waitq, 1447d3a07fcSAl Viro !fuse_block_alloc(fc, for_background))) 1459bc5dddaSMiklos Szeredi goto out; 1460aada884SMaxim Patlasov } 1479759bd51SMiklos Szeredi /* Matches smp_wmb() in fuse_set_initialized() */ 1489759bd51SMiklos Szeredi smp_rmb(); 14908a53cdcSMiklos Szeredi 15051eb01e7SMiklos Szeredi err = -ENOTCONN; 15151eb01e7SMiklos Szeredi if (!fc->connected) 15251eb01e7SMiklos Szeredi goto out; 15351eb01e7SMiklos Szeredi 154de155226SMiklos Szeredi err = -ECONNREFUSED; 155de155226SMiklos Szeredi if (fc->conn_error) 156de155226SMiklos Szeredi goto out; 157de155226SMiklos Szeredi 158b111c8c0SMaxim Patlasov req = fuse_request_alloc(npages); 1599bc5dddaSMiklos Szeredi err = -ENOMEM; 160722d2beaSMaxim Patlasov if (!req) { 161722d2beaSMaxim Patlasov if (for_background) 162722d2beaSMaxim Patlasov wake_up(&fc->blocked_waitq); 1639bc5dddaSMiklos Szeredi goto out; 164722d2beaSMaxim Patlasov } 165334f485dSMiklos Szeredi 1660b6e9ea0SSeth Forshee fuse_req_init_context(fc, req); 167825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 168825d6d33SMiklos Szeredi if (for_background) 169825d6d33SMiklos Szeredi __set_bit(FR_BACKGROUND, &req->flags); 170825d6d33SMiklos Szeredi 171334f485dSMiklos Szeredi return req; 1729bc5dddaSMiklos Szeredi 1739bc5dddaSMiklos Szeredi out: 1749bc5dddaSMiklos Szeredi atomic_dec(&fc->num_waiting); 1759bc5dddaSMiklos Szeredi return ERR_PTR(err); 176334f485dSMiklos Szeredi } 1778b41e671SMaxim Patlasov 1788b41e671SMaxim Patlasov struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages) 1798b41e671SMaxim Patlasov { 1808b41e671SMaxim Patlasov return __fuse_get_req(fc, npages, false); 1818b41e671SMaxim Patlasov } 18208cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_get_req); 183334f485dSMiklos Szeredi 1848b41e671SMaxim Patlasov struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc, 1858b41e671SMaxim Patlasov unsigned npages) 1868b41e671SMaxim Patlasov { 1878b41e671SMaxim Patlasov return __fuse_get_req(fc, npages, true); 1888b41e671SMaxim Patlasov } 1898b41e671SMaxim Patlasov EXPORT_SYMBOL_GPL(fuse_get_req_for_background); 1908b41e671SMaxim Patlasov 19133649c91SMiklos Szeredi /* 19233649c91SMiklos Szeredi * Return request in fuse_file->reserved_req. However that may 19333649c91SMiklos Szeredi * currently be in use. If that is the case, wait for it to become 19433649c91SMiklos Szeredi * available. 19533649c91SMiklos Szeredi */ 19633649c91SMiklos Szeredi static struct fuse_req *get_reserved_req(struct fuse_conn *fc, 19733649c91SMiklos Szeredi struct file *file) 19833649c91SMiklos Szeredi { 19933649c91SMiklos Szeredi struct fuse_req *req = NULL; 20033649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 20133649c91SMiklos Szeredi 20233649c91SMiklos Szeredi do { 203de5e3decSMiklos Szeredi wait_event(fc->reserved_req_waitq, ff->reserved_req); 20433649c91SMiklos Szeredi spin_lock(&fc->lock); 20533649c91SMiklos Szeredi if (ff->reserved_req) { 20633649c91SMiklos Szeredi req = ff->reserved_req; 20733649c91SMiklos Szeredi ff->reserved_req = NULL; 208cb0942b8SAl Viro req->stolen_file = get_file(file); 20933649c91SMiklos Szeredi } 21033649c91SMiklos Szeredi spin_unlock(&fc->lock); 21133649c91SMiklos Szeredi } while (!req); 21233649c91SMiklos Szeredi 21333649c91SMiklos Szeredi return req; 21433649c91SMiklos Szeredi } 21533649c91SMiklos Szeredi 21633649c91SMiklos Szeredi /* 21733649c91SMiklos Szeredi * Put stolen request back into fuse_file->reserved_req 21833649c91SMiklos Szeredi */ 21933649c91SMiklos Szeredi static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req) 22033649c91SMiklos Szeredi { 22133649c91SMiklos Szeredi struct file *file = req->stolen_file; 22233649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 22333649c91SMiklos Szeredi 22433649c91SMiklos Szeredi spin_lock(&fc->lock); 225b2430d75SMaxim Patlasov fuse_request_init(req, req->pages, req->page_descs, req->max_pages); 22633649c91SMiklos Szeredi BUG_ON(ff->reserved_req); 22733649c91SMiklos Szeredi ff->reserved_req = req; 228de5e3decSMiklos Szeredi wake_up_all(&fc->reserved_req_waitq); 22933649c91SMiklos Szeredi spin_unlock(&fc->lock); 23033649c91SMiklos Szeredi fput(file); 23133649c91SMiklos Szeredi } 23233649c91SMiklos Szeredi 23333649c91SMiklos Szeredi /* 23433649c91SMiklos Szeredi * Gets a requests for a file operation, always succeeds 23533649c91SMiklos Szeredi * 23633649c91SMiklos Szeredi * This is used for sending the FLUSH request, which must get to 23733649c91SMiklos Szeredi * userspace, due to POSIX locks which may need to be unlocked. 23833649c91SMiklos Szeredi * 23933649c91SMiklos Szeredi * If allocation fails due to OOM, use the reserved request in 24033649c91SMiklos Szeredi * fuse_file. 24133649c91SMiklos Szeredi * 24233649c91SMiklos Szeredi * This is very unlikely to deadlock accidentally, since the 24333649c91SMiklos Szeredi * filesystem should not have it's own file open. If deadlock is 24433649c91SMiklos Szeredi * intentional, it can still be broken by "aborting" the filesystem. 24533649c91SMiklos Szeredi */ 246b111c8c0SMaxim Patlasov struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, 247b111c8c0SMaxim Patlasov struct file *file) 24833649c91SMiklos Szeredi { 24933649c91SMiklos Szeredi struct fuse_req *req; 25033649c91SMiklos Szeredi 25133649c91SMiklos Szeredi atomic_inc(&fc->num_waiting); 2520aada884SMaxim Patlasov wait_event(fc->blocked_waitq, fc->initialized); 2539759bd51SMiklos Szeredi /* Matches smp_wmb() in fuse_set_initialized() */ 2549759bd51SMiklos Szeredi smp_rmb(); 255b111c8c0SMaxim Patlasov req = fuse_request_alloc(0); 25633649c91SMiklos Szeredi if (!req) 25733649c91SMiklos Szeredi req = get_reserved_req(fc, file); 25833649c91SMiklos Szeredi 2590b6e9ea0SSeth Forshee fuse_req_init_context(fc, req); 260825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 261825d6d33SMiklos Szeredi __clear_bit(FR_BACKGROUND, &req->flags); 26233649c91SMiklos Szeredi return req; 26333649c91SMiklos Szeredi } 26433649c91SMiklos Szeredi 265334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) 266334f485dSMiklos Szeredi { 267ec99f6d3SElena Reshetova if (refcount_dec_and_test(&req->count)) { 268825d6d33SMiklos Szeredi if (test_bit(FR_BACKGROUND, &req->flags)) { 269722d2beaSMaxim Patlasov /* 270722d2beaSMaxim Patlasov * We get here in the unlikely case that a background 271722d2beaSMaxim Patlasov * request was allocated but not sent 272722d2beaSMaxim Patlasov */ 273722d2beaSMaxim Patlasov spin_lock(&fc->lock); 274722d2beaSMaxim Patlasov if (!fc->blocked) 275722d2beaSMaxim Patlasov wake_up(&fc->blocked_waitq); 276722d2beaSMaxim Patlasov spin_unlock(&fc->lock); 277722d2beaSMaxim Patlasov } 278722d2beaSMaxim Patlasov 279825d6d33SMiklos Szeredi if (test_bit(FR_WAITING, &req->flags)) { 280825d6d33SMiklos Szeredi __clear_bit(FR_WAITING, &req->flags); 281ce1d5a49SMiklos Szeredi atomic_dec(&fc->num_waiting); 28273e0e738SMiklos Szeredi } 28333649c91SMiklos Szeredi 28433649c91SMiklos Szeredi if (req->stolen_file) 28533649c91SMiklos Szeredi put_reserved_req(fc, req); 28633649c91SMiklos Szeredi else 287ce1d5a49SMiklos Szeredi fuse_request_free(req); 2887128ec2aSMiklos Szeredi } 2897128ec2aSMiklos Szeredi } 29008cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_put_request); 2917128ec2aSMiklos Szeredi 292d12def1bSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args) 293d12def1bSMiklos Szeredi { 294d12def1bSMiklos Szeredi unsigned nbytes = 0; 295d12def1bSMiklos Szeredi unsigned i; 296d12def1bSMiklos Szeredi 297d12def1bSMiklos Szeredi for (i = 0; i < numargs; i++) 298d12def1bSMiklos Szeredi nbytes += args[i].size; 299d12def1bSMiklos Szeredi 300d12def1bSMiklos Szeredi return nbytes; 301d12def1bSMiklos Szeredi } 302d12def1bSMiklos Szeredi 303f88996a9SMiklos Szeredi static u64 fuse_get_unique(struct fuse_iqueue *fiq) 304d12def1bSMiklos Szeredi { 305f88996a9SMiklos Szeredi return ++fiq->reqctr; 306d12def1bSMiklos Szeredi } 307d12def1bSMiklos Szeredi 308f88996a9SMiklos Szeredi static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req) 309d12def1bSMiklos Szeredi { 310d12def1bSMiklos Szeredi req->in.h.len = sizeof(struct fuse_in_header) + 311d12def1bSMiklos Szeredi len_args(req->in.numargs, (struct fuse_arg *) req->in.args); 312f88996a9SMiklos Szeredi list_add_tail(&req->list, &fiq->pending); 3134ce60812SMiklos Szeredi wake_up_locked(&fiq->waitq); 314f88996a9SMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 315d12def1bSMiklos Szeredi } 316d12def1bSMiklos Szeredi 31707e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, 31807e77dcaSMiklos Szeredi u64 nodeid, u64 nlookup) 31907e77dcaSMiklos Szeredi { 320f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 321f88996a9SMiklos Szeredi 32202c048b9SMiklos Szeredi forget->forget_one.nodeid = nodeid; 32302c048b9SMiklos Szeredi forget->forget_one.nlookup = nlookup; 32407e77dcaSMiklos Szeredi 3254ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 326e16714d8SMiklos Szeredi if (fiq->connected) { 327f88996a9SMiklos Szeredi fiq->forget_list_tail->next = forget; 328f88996a9SMiklos Szeredi fiq->forget_list_tail = forget; 3294ce60812SMiklos Szeredi wake_up_locked(&fiq->waitq); 330f88996a9SMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 3315dfcc87fSMiklos Szeredi } else { 3325dfcc87fSMiklos Szeredi kfree(forget); 3335dfcc87fSMiklos Szeredi } 3344ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 33507e77dcaSMiklos Szeredi } 33607e77dcaSMiklos Szeredi 337d12def1bSMiklos Szeredi static void flush_bg_queue(struct fuse_conn *fc) 338d12def1bSMiklos Szeredi { 3397a6d3c8bSCsaba Henk while (fc->active_background < fc->max_background && 340d12def1bSMiklos Szeredi !list_empty(&fc->bg_queue)) { 341d12def1bSMiklos Szeredi struct fuse_req *req; 342f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 343d12def1bSMiklos Szeredi 344d12def1bSMiklos Szeredi req = list_entry(fc->bg_queue.next, struct fuse_req, list); 345d12def1bSMiklos Szeredi list_del(&req->list); 346d12def1bSMiklos Szeredi fc->active_background++; 3474ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 348f88996a9SMiklos Szeredi req->in.h.unique = fuse_get_unique(fiq); 349f88996a9SMiklos Szeredi queue_request(fiq, req); 3504ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 351d12def1bSMiklos Szeredi } 352d12def1bSMiklos Szeredi } 353d12def1bSMiklos Szeredi 3546dbbcb12SMiklos Szeredi /* 355334f485dSMiklos Szeredi * This function is called when a request is finished. Either a reply 356f9a2842eSMiklos Szeredi * has arrived or it was aborted (and not yet sent) or some error 357f43b155aSMiklos Szeredi * occurred during communication with userspace, or the device file 35851eb01e7SMiklos Szeredi * was closed. The requester thread is woken up (if still waiting), 35951eb01e7SMiklos Szeredi * the 'end' callback is called if given, else the reference to the 36051eb01e7SMiklos Szeredi * request is released 361334f485dSMiklos Szeredi */ 362334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req) 363334f485dSMiklos Szeredi { 3644ce60812SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 365365ae710SMiklos Szeredi 366efe2800fSMiklos Szeredi if (test_and_set_bit(FR_FINISHED, &req->flags)) 367365ae710SMiklos Szeredi return; 368365ae710SMiklos Szeredi 3694ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 3700d8e84b0SMiklos Szeredi list_del_init(&req->intr_entry); 3714ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 37233e14b4dSMiklos Szeredi WARN_ON(test_bit(FR_PENDING, &req->flags)); 37333e14b4dSMiklos Szeredi WARN_ON(test_bit(FR_SENT, &req->flags)); 374825d6d33SMiklos Szeredi if (test_bit(FR_BACKGROUND, &req->flags)) { 375efe2800fSMiklos Szeredi spin_lock(&fc->lock); 376825d6d33SMiklos Szeredi clear_bit(FR_BACKGROUND, &req->flags); 377722d2beaSMaxim Patlasov if (fc->num_background == fc->max_background) 37851eb01e7SMiklos Szeredi fc->blocked = 0; 379722d2beaSMaxim Patlasov 380722d2beaSMaxim Patlasov /* Wake up next waiter, if any */ 3813c18ef81SMiklos Szeredi if (!fc->blocked && waitqueue_active(&fc->blocked_waitq)) 382722d2beaSMaxim Patlasov wake_up(&fc->blocked_waitq); 383722d2beaSMaxim Patlasov 3847a6d3c8bSCsaba Henk if (fc->num_background == fc->congestion_threshold && 3857fbbe972SJan Kara fc->connected && fc->sb) { 3865f7f7543SJan Kara clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); 3875f7f7543SJan Kara clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); 388f92b99b9SMiklos Szeredi } 38951eb01e7SMiklos Szeredi fc->num_background--; 390d12def1bSMiklos Szeredi fc->active_background--; 391d12def1bSMiklos Szeredi flush_bg_queue(fc); 392d7133114SMiklos Szeredi spin_unlock(&fc->lock); 393efe2800fSMiklos Szeredi } 39451eb01e7SMiklos Szeredi wake_up(&req->waitq); 3951e6881c3SMiklos Szeredi if (req->end) 3961e6881c3SMiklos Szeredi req->end(fc, req); 397f43b155aSMiklos Szeredi fuse_put_request(fc, req); 398334f485dSMiklos Szeredi } 399334f485dSMiklos Szeredi 400f88996a9SMiklos Szeredi static void queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req) 401a4d27e75SMiklos Szeredi { 4024ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 4036ba4d272SSahitya Tummala if (test_bit(FR_FINISHED, &req->flags)) { 4046ba4d272SSahitya Tummala spin_unlock(&fiq->waitq.lock); 4056ba4d272SSahitya Tummala return; 4066ba4d272SSahitya Tummala } 4078f7bb368SMiklos Szeredi if (list_empty(&req->intr_entry)) { 408f88996a9SMiklos Szeredi list_add_tail(&req->intr_entry, &fiq->interrupts); 4094ce60812SMiklos Szeredi wake_up_locked(&fiq->waitq); 4108f7bb368SMiklos Szeredi } 4114ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 412f88996a9SMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 413a4d27e75SMiklos Szeredi } 414a4d27e75SMiklos Szeredi 4157c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) 416334f485dSMiklos Szeredi { 4174ce60812SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 418c4775267SMiklos Szeredi int err; 419c4775267SMiklos Szeredi 420a4d27e75SMiklos Szeredi if (!fc->no_interrupt) { 421a4d27e75SMiklos Szeredi /* Any signal may interrupt this */ 422c4775267SMiklos Szeredi err = wait_event_interruptible(req->waitq, 42333e14b4dSMiklos Szeredi test_bit(FR_FINISHED, &req->flags)); 424c4775267SMiklos Szeredi if (!err) 425334f485dSMiklos Szeredi return; 426334f485dSMiklos Szeredi 427825d6d33SMiklos Szeredi set_bit(FR_INTERRUPTED, &req->flags); 4288f7bb368SMiklos Szeredi /* matches barrier in fuse_dev_do_read() */ 4298f7bb368SMiklos Szeredi smp_mb__after_atomic(); 43033e14b4dSMiklos Szeredi if (test_bit(FR_SENT, &req->flags)) 4314ce60812SMiklos Szeredi queue_interrupt(fiq, req); 432a4d27e75SMiklos Szeredi } 433a4d27e75SMiklos Szeredi 434825d6d33SMiklos Szeredi if (!test_bit(FR_FORCE, &req->flags)) { 435a4d27e75SMiklos Szeredi /* Only fatal signals may interrupt this */ 4367d3a07fcSAl Viro err = wait_event_killable(req->waitq, 43733e14b4dSMiklos Szeredi test_bit(FR_FINISHED, &req->flags)); 438c4775267SMiklos Szeredi if (!err) 439a4d27e75SMiklos Szeredi return; 440a4d27e75SMiklos Szeredi 4414ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 442a131de0aSMiklos Szeredi /* Request is not yet in userspace, bail out */ 44333e14b4dSMiklos Szeredi if (test_bit(FR_PENDING, &req->flags)) { 444a131de0aSMiklos Szeredi list_del(&req->list); 4454ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 446a131de0aSMiklos Szeredi __fuse_put_request(req); 447334f485dSMiklos Szeredi req->out.h.error = -EINTR; 448a131de0aSMiklos Szeredi return; 449a131de0aSMiklos Szeredi } 4504ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 451a131de0aSMiklos Szeredi } 452a131de0aSMiklos Szeredi 453a131de0aSMiklos Szeredi /* 454a131de0aSMiklos Szeredi * Either request is already in userspace, or it was forced. 455a131de0aSMiklos Szeredi * Wait it out. 456a131de0aSMiklos Szeredi */ 45733e14b4dSMiklos Szeredi wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags)); 458334f485dSMiklos Szeredi } 459334f485dSMiklos Szeredi 4606a4e922cSEric Wong static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 461334f485dSMiklos Szeredi { 462e16714d8SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 463e16714d8SMiklos Szeredi 464825d6d33SMiklos Szeredi BUG_ON(test_bit(FR_BACKGROUND, &req->flags)); 4654ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 466e16714d8SMiklos Szeredi if (!fiq->connected) { 4674ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 468334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 469c4775267SMiklos Szeredi } else { 470f88996a9SMiklos Szeredi req->in.h.unique = fuse_get_unique(fiq); 471f88996a9SMiklos Szeredi queue_request(fiq, req); 472334f485dSMiklos Szeredi /* acquire extra reference, since request is still needed 473334f485dSMiklos Szeredi after request_end() */ 474334f485dSMiklos Szeredi __fuse_get_request(req); 4754ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 476334f485dSMiklos Szeredi 4777c352bdfSMiklos Szeredi request_wait_answer(fc, req); 478c4775267SMiklos Szeredi /* Pairs with smp_wmb() in request_end() */ 479c4775267SMiklos Szeredi smp_rmb(); 480334f485dSMiklos Szeredi } 481334f485dSMiklos Szeredi } 4826a4e922cSEric Wong 4836a4e922cSEric Wong void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 4846a4e922cSEric Wong { 485825d6d33SMiklos Szeredi __set_bit(FR_ISREPLY, &req->flags); 486825d6d33SMiklos Szeredi if (!test_bit(FR_WAITING, &req->flags)) { 487825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 4885437f241SMiklos Szeredi atomic_inc(&fc->num_waiting); 4895437f241SMiklos Szeredi } 4906a4e922cSEric Wong __fuse_request_send(fc, req); 4916a4e922cSEric Wong } 49208cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send); 493334f485dSMiklos Szeredi 49421f62174SMiklos Szeredi static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args) 49521f62174SMiklos Szeredi { 49621f62174SMiklos Szeredi if (fc->minor < 4 && args->in.h.opcode == FUSE_STATFS) 49721f62174SMiklos Szeredi args->out.args[0].size = FUSE_COMPAT_STATFS_SIZE; 49821f62174SMiklos Szeredi 49921f62174SMiklos Szeredi if (fc->minor < 9) { 50021f62174SMiklos Szeredi switch (args->in.h.opcode) { 50121f62174SMiklos Szeredi case FUSE_LOOKUP: 50221f62174SMiklos Szeredi case FUSE_CREATE: 50321f62174SMiklos Szeredi case FUSE_MKNOD: 50421f62174SMiklos Szeredi case FUSE_MKDIR: 50521f62174SMiklos Szeredi case FUSE_SYMLINK: 50621f62174SMiklos Szeredi case FUSE_LINK: 50721f62174SMiklos Szeredi args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; 50821f62174SMiklos Szeredi break; 50921f62174SMiklos Szeredi case FUSE_GETATTR: 51021f62174SMiklos Szeredi case FUSE_SETATTR: 51121f62174SMiklos Szeredi args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; 51221f62174SMiklos Szeredi break; 51321f62174SMiklos Szeredi } 51421f62174SMiklos Szeredi } 51521f62174SMiklos Szeredi if (fc->minor < 12) { 51621f62174SMiklos Szeredi switch (args->in.h.opcode) { 51721f62174SMiklos Szeredi case FUSE_CREATE: 51821f62174SMiklos Szeredi args->in.args[0].size = sizeof(struct fuse_open_in); 51921f62174SMiklos Szeredi break; 52021f62174SMiklos Szeredi case FUSE_MKNOD: 52121f62174SMiklos Szeredi args->in.args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE; 52221f62174SMiklos Szeredi break; 52321f62174SMiklos Szeredi } 52421f62174SMiklos Szeredi } 52521f62174SMiklos Szeredi } 52621f62174SMiklos Szeredi 5277078187aSMiklos Szeredi ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) 5287078187aSMiklos Szeredi { 5297078187aSMiklos Szeredi struct fuse_req *req; 5307078187aSMiklos Szeredi ssize_t ret; 5317078187aSMiklos Szeredi 5327078187aSMiklos Szeredi req = fuse_get_req(fc, 0); 5337078187aSMiklos Szeredi if (IS_ERR(req)) 5347078187aSMiklos Szeredi return PTR_ERR(req); 5357078187aSMiklos Szeredi 53621f62174SMiklos Szeredi /* Needs to be done after fuse_get_req() so that fc->minor is valid */ 53721f62174SMiklos Szeredi fuse_adjust_compat(fc, args); 53821f62174SMiklos Szeredi 5397078187aSMiklos Szeredi req->in.h.opcode = args->in.h.opcode; 5407078187aSMiklos Szeredi req->in.h.nodeid = args->in.h.nodeid; 5417078187aSMiklos Szeredi req->in.numargs = args->in.numargs; 5427078187aSMiklos Szeredi memcpy(req->in.args, args->in.args, 5437078187aSMiklos Szeredi args->in.numargs * sizeof(struct fuse_in_arg)); 5447078187aSMiklos Szeredi req->out.argvar = args->out.argvar; 5457078187aSMiklos Szeredi req->out.numargs = args->out.numargs; 5467078187aSMiklos Szeredi memcpy(req->out.args, args->out.args, 5477078187aSMiklos Szeredi args->out.numargs * sizeof(struct fuse_arg)); 5487078187aSMiklos Szeredi fuse_request_send(fc, req); 5497078187aSMiklos Szeredi ret = req->out.h.error; 5507078187aSMiklos Szeredi if (!ret && args->out.argvar) { 5517078187aSMiklos Szeredi BUG_ON(args->out.numargs != 1); 5527078187aSMiklos Szeredi ret = req->out.args[0].size; 5537078187aSMiklos Szeredi } 5547078187aSMiklos Szeredi fuse_put_request(fc, req); 5557078187aSMiklos Szeredi 5567078187aSMiklos Szeredi return ret; 5577078187aSMiklos Szeredi } 5587078187aSMiklos Szeredi 559f0139aa8SMiklos Szeredi /* 560f0139aa8SMiklos Szeredi * Called under fc->lock 561f0139aa8SMiklos Szeredi * 562f0139aa8SMiklos Szeredi * fc->connected must have been checked previously 563f0139aa8SMiklos Szeredi */ 564f0139aa8SMiklos Szeredi void fuse_request_send_background_locked(struct fuse_conn *fc, 565d12def1bSMiklos Szeredi struct fuse_req *req) 566334f485dSMiklos Szeredi { 567825d6d33SMiklos Szeredi BUG_ON(!test_bit(FR_BACKGROUND, &req->flags)); 568825d6d33SMiklos Szeredi if (!test_bit(FR_WAITING, &req->flags)) { 569825d6d33SMiklos Szeredi __set_bit(FR_WAITING, &req->flags); 5705437f241SMiklos Szeredi atomic_inc(&fc->num_waiting); 5715437f241SMiklos Szeredi } 572825d6d33SMiklos Szeredi __set_bit(FR_ISREPLY, &req->flags); 57351eb01e7SMiklos Szeredi fc->num_background++; 5747a6d3c8bSCsaba Henk if (fc->num_background == fc->max_background) 57551eb01e7SMiklos Szeredi fc->blocked = 1; 5767fbbe972SJan Kara if (fc->num_background == fc->congestion_threshold && fc->sb) { 5775f7f7543SJan Kara set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); 5785f7f7543SJan Kara set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); 579f92b99b9SMiklos Szeredi } 580d12def1bSMiklos Szeredi list_add_tail(&req->list, &fc->bg_queue); 581d12def1bSMiklos Szeredi flush_bg_queue(fc); 582d12def1bSMiklos Szeredi } 58351eb01e7SMiklos Szeredi 584f0139aa8SMiklos Szeredi void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) 585d12def1bSMiklos Szeredi { 58642dc6211SMiklos Szeredi BUG_ON(!req->end); 587d12def1bSMiklos Szeredi spin_lock(&fc->lock); 588d12def1bSMiklos Szeredi if (fc->connected) { 589f0139aa8SMiklos Szeredi fuse_request_send_background_locked(fc, req); 590d7133114SMiklos Szeredi spin_unlock(&fc->lock); 591334f485dSMiklos Szeredi } else { 59242dc6211SMiklos Szeredi spin_unlock(&fc->lock); 593334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 59442dc6211SMiklos Szeredi req->end(fc, req); 59542dc6211SMiklos Szeredi fuse_put_request(fc, req); 596334f485dSMiklos Szeredi } 597334f485dSMiklos Szeredi } 59808cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send_background); 599334f485dSMiklos Szeredi 6002d45ba38SMiklos Szeredi static int fuse_request_send_notify_reply(struct fuse_conn *fc, 6012d45ba38SMiklos Szeredi struct fuse_req *req, u64 unique) 6022d45ba38SMiklos Szeredi { 6032d45ba38SMiklos Szeredi int err = -ENODEV; 604f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 6052d45ba38SMiklos Szeredi 606825d6d33SMiklos Szeredi __clear_bit(FR_ISREPLY, &req->flags); 6072d45ba38SMiklos Szeredi req->in.h.unique = unique; 6084ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 609e16714d8SMiklos Szeredi if (fiq->connected) { 610f88996a9SMiklos Szeredi queue_request(fiq, req); 6112d45ba38SMiklos Szeredi err = 0; 6122d45ba38SMiklos Szeredi } 6134ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 6142d45ba38SMiklos Szeredi 6152d45ba38SMiklos Szeredi return err; 6162d45ba38SMiklos Szeredi } 6172d45ba38SMiklos Szeredi 6180b05b183SAnand V. Avati void fuse_force_forget(struct file *file, u64 nodeid) 6190b05b183SAnand V. Avati { 6206131ffaaSAl Viro struct inode *inode = file_inode(file); 6210b05b183SAnand V. Avati struct fuse_conn *fc = get_fuse_conn(inode); 6220b05b183SAnand V. Avati struct fuse_req *req; 6230b05b183SAnand V. Avati struct fuse_forget_in inarg; 6240b05b183SAnand V. Avati 6250b05b183SAnand V. Avati memset(&inarg, 0, sizeof(inarg)); 6260b05b183SAnand V. Avati inarg.nlookup = 1; 627b111c8c0SMaxim Patlasov req = fuse_get_req_nofail_nopages(fc, file); 6280b05b183SAnand V. Avati req->in.h.opcode = FUSE_FORGET; 6290b05b183SAnand V. Avati req->in.h.nodeid = nodeid; 6300b05b183SAnand V. Avati req->in.numargs = 1; 6310b05b183SAnand V. Avati req->in.args[0].size = sizeof(inarg); 6320b05b183SAnand V. Avati req->in.args[0].value = &inarg; 633825d6d33SMiklos Szeredi __clear_bit(FR_ISREPLY, &req->flags); 6346a4e922cSEric Wong __fuse_request_send(fc, req); 6356a4e922cSEric Wong /* ignore errors */ 6366a4e922cSEric Wong fuse_put_request(fc, req); 6370b05b183SAnand V. Avati } 6380b05b183SAnand V. Avati 6393be5a52bSMiklos Szeredi /* 640334f485dSMiklos Szeredi * Lock the request. Up to the next unlock_request() there mustn't be 641334f485dSMiklos Szeredi * anything that could cause a page-fault. If the request was already 642f9a2842eSMiklos Szeredi * aborted bail out. 643334f485dSMiklos Szeredi */ 644dc00809aSMiklos Szeredi static int lock_request(struct fuse_req *req) 645334f485dSMiklos Szeredi { 646334f485dSMiklos Szeredi int err = 0; 647334f485dSMiklos Szeredi if (req) { 648dc00809aSMiklos Szeredi spin_lock(&req->waitq.lock); 649825d6d33SMiklos Szeredi if (test_bit(FR_ABORTED, &req->flags)) 650334f485dSMiklos Szeredi err = -ENOENT; 651334f485dSMiklos Szeredi else 652825d6d33SMiklos Szeredi set_bit(FR_LOCKED, &req->flags); 653dc00809aSMiklos Szeredi spin_unlock(&req->waitq.lock); 654334f485dSMiklos Szeredi } 655334f485dSMiklos Szeredi return err; 656334f485dSMiklos Szeredi } 657334f485dSMiklos Szeredi 658334f485dSMiklos Szeredi /* 6590d8e84b0SMiklos Szeredi * Unlock request. If it was aborted while locked, caller is responsible 6600d8e84b0SMiklos Szeredi * for unlocking and ending the request. 661334f485dSMiklos Szeredi */ 662dc00809aSMiklos Szeredi static int unlock_request(struct fuse_req *req) 663334f485dSMiklos Szeredi { 6640d8e84b0SMiklos Szeredi int err = 0; 665334f485dSMiklos Szeredi if (req) { 666dc00809aSMiklos Szeredi spin_lock(&req->waitq.lock); 667825d6d33SMiklos Szeredi if (test_bit(FR_ABORTED, &req->flags)) 6680d8e84b0SMiklos Szeredi err = -ENOENT; 6690d8e84b0SMiklos Szeredi else 670825d6d33SMiklos Szeredi clear_bit(FR_LOCKED, &req->flags); 671dc00809aSMiklos Szeredi spin_unlock(&req->waitq.lock); 672334f485dSMiklos Szeredi } 6730d8e84b0SMiklos Szeredi return err; 674334f485dSMiklos Szeredi } 675334f485dSMiklos Szeredi 676334f485dSMiklos Szeredi struct fuse_copy_state { 677334f485dSMiklos Szeredi int write; 678334f485dSMiklos Szeredi struct fuse_req *req; 6796c09e94aSAl Viro struct iov_iter *iter; 680dd3bb14fSMiklos Szeredi struct pipe_buffer *pipebufs; 681dd3bb14fSMiklos Szeredi struct pipe_buffer *currbuf; 682dd3bb14fSMiklos Szeredi struct pipe_inode_info *pipe; 683334f485dSMiklos Szeredi unsigned long nr_segs; 684334f485dSMiklos Szeredi struct page *pg; 685334f485dSMiklos Szeredi unsigned len; 686c55a01d3SMiklos Szeredi unsigned offset; 687ce534fb0SMiklos Szeredi unsigned move_pages:1; 688334f485dSMiklos Szeredi }; 689334f485dSMiklos Szeredi 690dc00809aSMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, int write, 6916c09e94aSAl Viro struct iov_iter *iter) 692334f485dSMiklos Szeredi { 693334f485dSMiklos Szeredi memset(cs, 0, sizeof(*cs)); 694334f485dSMiklos Szeredi cs->write = write; 6956c09e94aSAl Viro cs->iter = iter; 696334f485dSMiklos Szeredi } 697334f485dSMiklos Szeredi 698334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */ 6998bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs) 700334f485dSMiklos Szeredi { 701dd3bb14fSMiklos Szeredi if (cs->currbuf) { 702dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->currbuf; 703dd3bb14fSMiklos Szeredi 704c55a01d3SMiklos Szeredi if (cs->write) 705c3021629SMiklos Szeredi buf->len = PAGE_SIZE - cs->len; 706dd3bb14fSMiklos Szeredi cs->currbuf = NULL; 707c55a01d3SMiklos Szeredi } else if (cs->pg) { 708334f485dSMiklos Szeredi if (cs->write) { 709334f485dSMiklos Szeredi flush_dcache_page(cs->pg); 710334f485dSMiklos Szeredi set_page_dirty_lock(cs->pg); 711334f485dSMiklos Szeredi } 712334f485dSMiklos Szeredi put_page(cs->pg); 713334f485dSMiklos Szeredi } 714c55a01d3SMiklos Szeredi cs->pg = NULL; 715334f485dSMiklos Szeredi } 716334f485dSMiklos Szeredi 717334f485dSMiklos Szeredi /* 718334f485dSMiklos Szeredi * Get another pagefull of userspace buffer, and map it to kernel 719334f485dSMiklos Szeredi * address space, and lock request 720334f485dSMiklos Szeredi */ 721334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs) 722334f485dSMiklos Szeredi { 723c55a01d3SMiklos Szeredi struct page *page; 724334f485dSMiklos Szeredi int err; 725334f485dSMiklos Szeredi 726dc00809aSMiklos Szeredi err = unlock_request(cs->req); 7270d8e84b0SMiklos Szeredi if (err) 7280d8e84b0SMiklos Szeredi return err; 7290d8e84b0SMiklos Szeredi 730334f485dSMiklos Szeredi fuse_copy_finish(cs); 731dd3bb14fSMiklos Szeredi if (cs->pipebufs) { 732dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 733dd3bb14fSMiklos Szeredi 734c3021629SMiklos Szeredi if (!cs->write) { 735fba597dbSMiklos Szeredi err = pipe_buf_confirm(cs->pipe, buf); 736dd3bb14fSMiklos Szeredi if (err) 737dd3bb14fSMiklos Szeredi return err; 738dd3bb14fSMiklos Szeredi 739dd3bb14fSMiklos Szeredi BUG_ON(!cs->nr_segs); 740dd3bb14fSMiklos Szeredi cs->currbuf = buf; 741c55a01d3SMiklos Szeredi cs->pg = buf->page; 742c55a01d3SMiklos Szeredi cs->offset = buf->offset; 743dd3bb14fSMiklos Szeredi cs->len = buf->len; 744dd3bb14fSMiklos Szeredi cs->pipebufs++; 745dd3bb14fSMiklos Szeredi cs->nr_segs--; 746dd3bb14fSMiklos Szeredi } else { 747c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 748c3021629SMiklos Szeredi return -EIO; 749c3021629SMiklos Szeredi 750c3021629SMiklos Szeredi page = alloc_page(GFP_HIGHUSER); 751c3021629SMiklos Szeredi if (!page) 752c3021629SMiklos Szeredi return -ENOMEM; 753c3021629SMiklos Szeredi 754c3021629SMiklos Szeredi buf->page = page; 755c3021629SMiklos Szeredi buf->offset = 0; 756c3021629SMiklos Szeredi buf->len = 0; 757c3021629SMiklos Szeredi 758c3021629SMiklos Szeredi cs->currbuf = buf; 759c55a01d3SMiklos Szeredi cs->pg = page; 760c55a01d3SMiklos Szeredi cs->offset = 0; 761c3021629SMiklos Szeredi cs->len = PAGE_SIZE; 762c3021629SMiklos Szeredi cs->pipebufs++; 763c3021629SMiklos Szeredi cs->nr_segs++; 764c3021629SMiklos Szeredi } 765c3021629SMiklos Szeredi } else { 7666c09e94aSAl Viro size_t off; 7676c09e94aSAl Viro err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off); 768334f485dSMiklos Szeredi if (err < 0) 769334f485dSMiklos Szeredi return err; 7706c09e94aSAl Viro BUG_ON(!err); 7716c09e94aSAl Viro cs->len = err; 7726c09e94aSAl Viro cs->offset = off; 773c55a01d3SMiklos Szeredi cs->pg = page; 7746c09e94aSAl Viro iov_iter_advance(cs->iter, err); 775dd3bb14fSMiklos Szeredi } 776334f485dSMiklos Szeredi 777dc00809aSMiklos Szeredi return lock_request(cs->req); 778334f485dSMiklos Szeredi } 779334f485dSMiklos Szeredi 780334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */ 7818bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size) 782334f485dSMiklos Szeredi { 783334f485dSMiklos Szeredi unsigned ncpy = min(*size, cs->len); 784334f485dSMiklos Szeredi if (val) { 785c55a01d3SMiklos Szeredi void *pgaddr = kmap_atomic(cs->pg); 786c55a01d3SMiklos Szeredi void *buf = pgaddr + cs->offset; 787c55a01d3SMiklos Szeredi 788334f485dSMiklos Szeredi if (cs->write) 789c55a01d3SMiklos Szeredi memcpy(buf, *val, ncpy); 790334f485dSMiklos Szeredi else 791c55a01d3SMiklos Szeredi memcpy(*val, buf, ncpy); 792c55a01d3SMiklos Szeredi 793c55a01d3SMiklos Szeredi kunmap_atomic(pgaddr); 794334f485dSMiklos Szeredi *val += ncpy; 795334f485dSMiklos Szeredi } 796334f485dSMiklos Szeredi *size -= ncpy; 797334f485dSMiklos Szeredi cs->len -= ncpy; 798c55a01d3SMiklos Szeredi cs->offset += ncpy; 799334f485dSMiklos Szeredi return ncpy; 800334f485dSMiklos Szeredi } 801334f485dSMiklos Szeredi 802ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page) 803ce534fb0SMiklos Szeredi { 804ce534fb0SMiklos Szeredi if (page_mapcount(page) || 805ce534fb0SMiklos Szeredi page->mapping != NULL || 806ce534fb0SMiklos Szeredi page_count(page) != 1 || 807ce534fb0SMiklos Szeredi (page->flags & PAGE_FLAGS_CHECK_AT_PREP & 808ce534fb0SMiklos Szeredi ~(1 << PG_locked | 809ce534fb0SMiklos Szeredi 1 << PG_referenced | 810ce534fb0SMiklos Szeredi 1 << PG_uptodate | 811ce534fb0SMiklos Szeredi 1 << PG_lru | 812ce534fb0SMiklos Szeredi 1 << PG_active | 813ce534fb0SMiklos Szeredi 1 << PG_reclaim))) { 814ce534fb0SMiklos Szeredi printk(KERN_WARNING "fuse: trying to steal weird page\n"); 815ce534fb0SMiklos 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); 816ce534fb0SMiklos Szeredi return 1; 817ce534fb0SMiklos Szeredi } 818ce534fb0SMiklos Szeredi return 0; 819ce534fb0SMiklos Szeredi } 820ce534fb0SMiklos Szeredi 821ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) 822ce534fb0SMiklos Szeredi { 823ce534fb0SMiklos Szeredi int err; 824ce534fb0SMiklos Szeredi struct page *oldpage = *pagep; 825ce534fb0SMiklos Szeredi struct page *newpage; 826ce534fb0SMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 827ce534fb0SMiklos Szeredi 828dc00809aSMiklos Szeredi err = unlock_request(cs->req); 8290d8e84b0SMiklos Szeredi if (err) 8300d8e84b0SMiklos Szeredi return err; 8310d8e84b0SMiklos Szeredi 832ce534fb0SMiklos Szeredi fuse_copy_finish(cs); 833ce534fb0SMiklos Szeredi 834fba597dbSMiklos Szeredi err = pipe_buf_confirm(cs->pipe, buf); 835ce534fb0SMiklos Szeredi if (err) 836ce534fb0SMiklos Szeredi return err; 837ce534fb0SMiklos Szeredi 838ce534fb0SMiklos Szeredi BUG_ON(!cs->nr_segs); 839ce534fb0SMiklos Szeredi cs->currbuf = buf; 840ce534fb0SMiklos Szeredi cs->len = buf->len; 841ce534fb0SMiklos Szeredi cs->pipebufs++; 842ce534fb0SMiklos Szeredi cs->nr_segs--; 843ce534fb0SMiklos Szeredi 844ce534fb0SMiklos Szeredi if (cs->len != PAGE_SIZE) 845ce534fb0SMiklos Szeredi goto out_fallback; 846ce534fb0SMiklos Szeredi 847ca76f5b6SMiklos Szeredi if (pipe_buf_steal(cs->pipe, buf) != 0) 848ce534fb0SMiklos Szeredi goto out_fallback; 849ce534fb0SMiklos Szeredi 850ce534fb0SMiklos Szeredi newpage = buf->page; 851ce534fb0SMiklos Szeredi 852aa991b3bSMiklos Szeredi if (!PageUptodate(newpage)) 853aa991b3bSMiklos Szeredi SetPageUptodate(newpage); 854ce534fb0SMiklos Szeredi 855ce534fb0SMiklos Szeredi ClearPageMappedToDisk(newpage); 856ce534fb0SMiklos Szeredi 857ce534fb0SMiklos Szeredi if (fuse_check_page(newpage) != 0) 858ce534fb0SMiklos Szeredi goto out_fallback_unlock; 859ce534fb0SMiklos Szeredi 860ce534fb0SMiklos Szeredi /* 861ce534fb0SMiklos Szeredi * This is a new and locked page, it shouldn't be mapped or 862ce534fb0SMiklos Szeredi * have any special flags on it 863ce534fb0SMiklos Szeredi */ 864ce534fb0SMiklos Szeredi if (WARN_ON(page_mapped(oldpage))) 865ce534fb0SMiklos Szeredi goto out_fallback_unlock; 866ce534fb0SMiklos Szeredi if (WARN_ON(page_has_private(oldpage))) 867ce534fb0SMiklos Szeredi goto out_fallback_unlock; 868ce534fb0SMiklos Szeredi if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage))) 869ce534fb0SMiklos Szeredi goto out_fallback_unlock; 870ce534fb0SMiklos Szeredi if (WARN_ON(PageMlocked(oldpage))) 871ce534fb0SMiklos Szeredi goto out_fallback_unlock; 872ce534fb0SMiklos Szeredi 873ef6a3c63SMiklos Szeredi err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); 874ce534fb0SMiklos Szeredi if (err) { 875ef6a3c63SMiklos Szeredi unlock_page(newpage); 876ef6a3c63SMiklos Szeredi return err; 877ce534fb0SMiklos Szeredi } 878ef6a3c63SMiklos Szeredi 87909cbfeafSKirill A. Shutemov get_page(newpage); 880ce534fb0SMiklos Szeredi 881ce534fb0SMiklos Szeredi if (!(buf->flags & PIPE_BUF_FLAG_LRU)) 882ce534fb0SMiklos Szeredi lru_cache_add_file(newpage); 883ce534fb0SMiklos Szeredi 884ce534fb0SMiklos Szeredi err = 0; 885dc00809aSMiklos Szeredi spin_lock(&cs->req->waitq.lock); 886825d6d33SMiklos Szeredi if (test_bit(FR_ABORTED, &cs->req->flags)) 887ce534fb0SMiklos Szeredi err = -ENOENT; 888ce534fb0SMiklos Szeredi else 889ce534fb0SMiklos Szeredi *pagep = newpage; 890dc00809aSMiklos Szeredi spin_unlock(&cs->req->waitq.lock); 891ce534fb0SMiklos Szeredi 892ce534fb0SMiklos Szeredi if (err) { 893ce534fb0SMiklos Szeredi unlock_page(newpage); 89409cbfeafSKirill A. Shutemov put_page(newpage); 895ce534fb0SMiklos Szeredi return err; 896ce534fb0SMiklos Szeredi } 897ce534fb0SMiklos Szeredi 898ce534fb0SMiklos Szeredi unlock_page(oldpage); 89909cbfeafSKirill A. Shutemov put_page(oldpage); 900ce534fb0SMiklos Szeredi cs->len = 0; 901ce534fb0SMiklos Szeredi 902ce534fb0SMiklos Szeredi return 0; 903ce534fb0SMiklos Szeredi 904ce534fb0SMiklos Szeredi out_fallback_unlock: 905ce534fb0SMiklos Szeredi unlock_page(newpage); 906ce534fb0SMiklos Szeredi out_fallback: 907c55a01d3SMiklos Szeredi cs->pg = buf->page; 908c55a01d3SMiklos Szeredi cs->offset = buf->offset; 909ce534fb0SMiklos Szeredi 910dc00809aSMiklos Szeredi err = lock_request(cs->req); 911ce534fb0SMiklos Szeredi if (err) 912ce534fb0SMiklos Szeredi return err; 913ce534fb0SMiklos Szeredi 914ce534fb0SMiklos Szeredi return 1; 915ce534fb0SMiklos Szeredi } 916ce534fb0SMiklos Szeredi 917c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page, 918c3021629SMiklos Szeredi unsigned offset, unsigned count) 919c3021629SMiklos Szeredi { 920c3021629SMiklos Szeredi struct pipe_buffer *buf; 9210d8e84b0SMiklos Szeredi int err; 922c3021629SMiklos Szeredi 923c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 924c3021629SMiklos Szeredi return -EIO; 925c3021629SMiklos Szeredi 926dc00809aSMiklos Szeredi err = unlock_request(cs->req); 9270d8e84b0SMiklos Szeredi if (err) 9280d8e84b0SMiklos Szeredi return err; 9290d8e84b0SMiklos Szeredi 930c3021629SMiklos Szeredi fuse_copy_finish(cs); 931c3021629SMiklos Szeredi 932c3021629SMiklos Szeredi buf = cs->pipebufs; 93309cbfeafSKirill A. Shutemov get_page(page); 934c3021629SMiklos Szeredi buf->page = page; 935c3021629SMiklos Szeredi buf->offset = offset; 936c3021629SMiklos Szeredi buf->len = count; 937c3021629SMiklos Szeredi 938c3021629SMiklos Szeredi cs->pipebufs++; 939c3021629SMiklos Szeredi cs->nr_segs++; 940c3021629SMiklos Szeredi cs->len = 0; 941c3021629SMiklos Szeredi 942c3021629SMiklos Szeredi return 0; 943c3021629SMiklos Szeredi } 944c3021629SMiklos Szeredi 945334f485dSMiklos Szeredi /* 946334f485dSMiklos Szeredi * Copy a page in the request to/from the userspace buffer. Must be 947334f485dSMiklos Szeredi * done atomically 948334f485dSMiklos Szeredi */ 949ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep, 950334f485dSMiklos Szeredi unsigned offset, unsigned count, int zeroing) 951334f485dSMiklos Szeredi { 952ce534fb0SMiklos Szeredi int err; 953ce534fb0SMiklos Szeredi struct page *page = *pagep; 954ce534fb0SMiklos Szeredi 955b6777c40SMiklos Szeredi if (page && zeroing && count < PAGE_SIZE) 956b6777c40SMiklos Szeredi clear_highpage(page); 957b6777c40SMiklos Szeredi 958334f485dSMiklos Szeredi while (count) { 959c3021629SMiklos Szeredi if (cs->write && cs->pipebufs && page) { 960c3021629SMiklos Szeredi return fuse_ref_page(cs, page, offset, count); 961c3021629SMiklos Szeredi } else if (!cs->len) { 962ce534fb0SMiklos Szeredi if (cs->move_pages && page && 963ce534fb0SMiklos Szeredi offset == 0 && count == PAGE_SIZE) { 964ce534fb0SMiklos Szeredi err = fuse_try_move_page(cs, pagep); 965ce534fb0SMiklos Szeredi if (err <= 0) 966ce534fb0SMiklos Szeredi return err; 967ce534fb0SMiklos Szeredi } else { 968ce534fb0SMiklos Szeredi err = fuse_copy_fill(cs); 9691729a16cSMiklos Szeredi if (err) 970334f485dSMiklos Szeredi return err; 9711729a16cSMiklos Szeredi } 972ce534fb0SMiklos Szeredi } 973334f485dSMiklos Szeredi if (page) { 9742408f6efSCong Wang void *mapaddr = kmap_atomic(page); 975334f485dSMiklos Szeredi void *buf = mapaddr + offset; 976334f485dSMiklos Szeredi offset += fuse_copy_do(cs, &buf, &count); 9772408f6efSCong Wang kunmap_atomic(mapaddr); 978334f485dSMiklos Szeredi } else 979334f485dSMiklos Szeredi offset += fuse_copy_do(cs, NULL, &count); 980334f485dSMiklos Szeredi } 981334f485dSMiklos Szeredi if (page && !cs->write) 982334f485dSMiklos Szeredi flush_dcache_page(page); 983334f485dSMiklos Szeredi return 0; 984334f485dSMiklos Szeredi } 985334f485dSMiklos Szeredi 986334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */ 987334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes, 988334f485dSMiklos Szeredi int zeroing) 989334f485dSMiklos Szeredi { 990334f485dSMiklos Szeredi unsigned i; 991334f485dSMiklos Szeredi struct fuse_req *req = cs->req; 992334f485dSMiklos Szeredi 993334f485dSMiklos Szeredi for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) { 994ce534fb0SMiklos Szeredi int err; 99585f40aecSMaxim Patlasov unsigned offset = req->page_descs[i].offset; 99685f40aecSMaxim Patlasov unsigned count = min(nbytes, req->page_descs[i].length); 997ce534fb0SMiklos Szeredi 998ce534fb0SMiklos Szeredi err = fuse_copy_page(cs, &req->pages[i], offset, count, 999ce534fb0SMiklos Szeredi zeroing); 1000334f485dSMiklos Szeredi if (err) 1001334f485dSMiklos Szeredi return err; 1002334f485dSMiklos Szeredi 1003334f485dSMiklos Szeredi nbytes -= count; 1004334f485dSMiklos Szeredi } 1005334f485dSMiklos Szeredi return 0; 1006334f485dSMiklos Szeredi } 1007334f485dSMiklos Szeredi 1008334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */ 1009334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) 1010334f485dSMiklos Szeredi { 1011334f485dSMiklos Szeredi while (size) { 10121729a16cSMiklos Szeredi if (!cs->len) { 10131729a16cSMiklos Szeredi int err = fuse_copy_fill(cs); 10141729a16cSMiklos Szeredi if (err) 1015334f485dSMiklos Szeredi return err; 10161729a16cSMiklos Szeredi } 1017334f485dSMiklos Szeredi fuse_copy_do(cs, &val, &size); 1018334f485dSMiklos Szeredi } 1019334f485dSMiklos Szeredi return 0; 1020334f485dSMiklos Szeredi } 1021334f485dSMiklos Szeredi 1022334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */ 1023334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs, 1024334f485dSMiklos Szeredi unsigned argpages, struct fuse_arg *args, 1025334f485dSMiklos Szeredi int zeroing) 1026334f485dSMiklos Szeredi { 1027334f485dSMiklos Szeredi int err = 0; 1028334f485dSMiklos Szeredi unsigned i; 1029334f485dSMiklos Szeredi 1030334f485dSMiklos Szeredi for (i = 0; !err && i < numargs; i++) { 1031334f485dSMiklos Szeredi struct fuse_arg *arg = &args[i]; 1032334f485dSMiklos Szeredi if (i == numargs - 1 && argpages) 1033334f485dSMiklos Szeredi err = fuse_copy_pages(cs, arg->size, zeroing); 1034334f485dSMiklos Szeredi else 1035334f485dSMiklos Szeredi err = fuse_copy_one(cs, arg->value, arg->size); 1036334f485dSMiklos Szeredi } 1037334f485dSMiklos Szeredi return err; 1038334f485dSMiklos Szeredi } 1039334f485dSMiklos Szeredi 1040f88996a9SMiklos Szeredi static int forget_pending(struct fuse_iqueue *fiq) 104107e77dcaSMiklos Szeredi { 1042f88996a9SMiklos Szeredi return fiq->forget_list_head.next != NULL; 104307e77dcaSMiklos Szeredi } 104407e77dcaSMiklos Szeredi 1045f88996a9SMiklos Szeredi static int request_pending(struct fuse_iqueue *fiq) 1046a4d27e75SMiklos Szeredi { 1047f88996a9SMiklos Szeredi return !list_empty(&fiq->pending) || !list_empty(&fiq->interrupts) || 1048f88996a9SMiklos Szeredi forget_pending(fiq); 1049a4d27e75SMiklos Szeredi } 1050a4d27e75SMiklos Szeredi 1051334f485dSMiklos Szeredi /* 1052a4d27e75SMiklos Szeredi * Transfer an interrupt request to userspace 1053a4d27e75SMiklos Szeredi * 1054a4d27e75SMiklos Szeredi * Unlike other requests this is assembled on demand, without a need 1055a4d27e75SMiklos Szeredi * to allocate a separate fuse_req structure. 1056a4d27e75SMiklos Szeredi * 1057fd22d62eSMiklos Szeredi * Called with fiq->waitq.lock held, releases it 1058a4d27e75SMiklos Szeredi */ 1059fd22d62eSMiklos Szeredi static int fuse_read_interrupt(struct fuse_iqueue *fiq, 1060fd22d62eSMiklos Szeredi struct fuse_copy_state *cs, 1061c3021629SMiklos Szeredi size_t nbytes, struct fuse_req *req) 1062fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 1063a4d27e75SMiklos Szeredi { 1064a4d27e75SMiklos Szeredi struct fuse_in_header ih; 1065a4d27e75SMiklos Szeredi struct fuse_interrupt_in arg; 1066a4d27e75SMiklos Szeredi unsigned reqsize = sizeof(ih) + sizeof(arg); 1067a4d27e75SMiklos Szeredi int err; 1068a4d27e75SMiklos Szeredi 1069a4d27e75SMiklos Szeredi list_del_init(&req->intr_entry); 10704ce60812SMiklos Szeredi req->intr_unique = fuse_get_unique(fiq); 1071a4d27e75SMiklos Szeredi memset(&ih, 0, sizeof(ih)); 1072a4d27e75SMiklos Szeredi memset(&arg, 0, sizeof(arg)); 1073a4d27e75SMiklos Szeredi ih.len = reqsize; 1074a4d27e75SMiklos Szeredi ih.opcode = FUSE_INTERRUPT; 1075a4d27e75SMiklos Szeredi ih.unique = req->intr_unique; 1076a4d27e75SMiklos Szeredi arg.unique = req->in.h.unique; 1077a4d27e75SMiklos Szeredi 10784ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 1079c3021629SMiklos Szeredi if (nbytes < reqsize) 1080a4d27e75SMiklos Szeredi return -EINVAL; 1081a4d27e75SMiklos Szeredi 1082c3021629SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 1083a4d27e75SMiklos Szeredi if (!err) 1084c3021629SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 1085c3021629SMiklos Szeredi fuse_copy_finish(cs); 1086a4d27e75SMiklos Szeredi 1087a4d27e75SMiklos Szeredi return err ? err : reqsize; 1088a4d27e75SMiklos Szeredi } 1089a4d27e75SMiklos Szeredi 1090f88996a9SMiklos Szeredi static struct fuse_forget_link *dequeue_forget(struct fuse_iqueue *fiq, 109102c048b9SMiklos Szeredi unsigned max, 109202c048b9SMiklos Szeredi unsigned *countp) 109307e77dcaSMiklos Szeredi { 1094f88996a9SMiklos Szeredi struct fuse_forget_link *head = fiq->forget_list_head.next; 109502c048b9SMiklos Szeredi struct fuse_forget_link **newhead = &head; 109602c048b9SMiklos Szeredi unsigned count; 109707e77dcaSMiklos Szeredi 109802c048b9SMiklos Szeredi for (count = 0; *newhead != NULL && count < max; count++) 109902c048b9SMiklos Szeredi newhead = &(*newhead)->next; 110002c048b9SMiklos Szeredi 1101f88996a9SMiklos Szeredi fiq->forget_list_head.next = *newhead; 110202c048b9SMiklos Szeredi *newhead = NULL; 1103f88996a9SMiklos Szeredi if (fiq->forget_list_head.next == NULL) 1104f88996a9SMiklos Szeredi fiq->forget_list_tail = &fiq->forget_list_head; 110507e77dcaSMiklos Szeredi 110602c048b9SMiklos Szeredi if (countp != NULL) 110702c048b9SMiklos Szeredi *countp = count; 110802c048b9SMiklos Szeredi 110902c048b9SMiklos Szeredi return head; 111007e77dcaSMiklos Szeredi } 111107e77dcaSMiklos Szeredi 1112fd22d62eSMiklos Szeredi static int fuse_read_single_forget(struct fuse_iqueue *fiq, 111307e77dcaSMiklos Szeredi struct fuse_copy_state *cs, 111407e77dcaSMiklos Szeredi size_t nbytes) 1115fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 111607e77dcaSMiklos Szeredi { 111707e77dcaSMiklos Szeredi int err; 1118f88996a9SMiklos Szeredi struct fuse_forget_link *forget = dequeue_forget(fiq, 1, NULL); 111907e77dcaSMiklos Szeredi struct fuse_forget_in arg = { 112002c048b9SMiklos Szeredi .nlookup = forget->forget_one.nlookup, 112107e77dcaSMiklos Szeredi }; 112207e77dcaSMiklos Szeredi struct fuse_in_header ih = { 112307e77dcaSMiklos Szeredi .opcode = FUSE_FORGET, 112402c048b9SMiklos Szeredi .nodeid = forget->forget_one.nodeid, 1125f88996a9SMiklos Szeredi .unique = fuse_get_unique(fiq), 112607e77dcaSMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 112707e77dcaSMiklos Szeredi }; 112807e77dcaSMiklos Szeredi 11294ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 113007e77dcaSMiklos Szeredi kfree(forget); 113107e77dcaSMiklos Szeredi if (nbytes < ih.len) 113207e77dcaSMiklos Szeredi return -EINVAL; 113307e77dcaSMiklos Szeredi 113407e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 113507e77dcaSMiklos Szeredi if (!err) 113607e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 113707e77dcaSMiklos Szeredi fuse_copy_finish(cs); 113807e77dcaSMiklos Szeredi 113907e77dcaSMiklos Szeredi if (err) 114007e77dcaSMiklos Szeredi return err; 114107e77dcaSMiklos Szeredi 114207e77dcaSMiklos Szeredi return ih.len; 114307e77dcaSMiklos Szeredi } 114407e77dcaSMiklos Szeredi 1145fd22d62eSMiklos Szeredi static int fuse_read_batch_forget(struct fuse_iqueue *fiq, 114602c048b9SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1147fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 114802c048b9SMiklos Szeredi { 114902c048b9SMiklos Szeredi int err; 115002c048b9SMiklos Szeredi unsigned max_forgets; 115102c048b9SMiklos Szeredi unsigned count; 115202c048b9SMiklos Szeredi struct fuse_forget_link *head; 115302c048b9SMiklos Szeredi struct fuse_batch_forget_in arg = { .count = 0 }; 115402c048b9SMiklos Szeredi struct fuse_in_header ih = { 115502c048b9SMiklos Szeredi .opcode = FUSE_BATCH_FORGET, 1156f88996a9SMiklos Szeredi .unique = fuse_get_unique(fiq), 115702c048b9SMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 115802c048b9SMiklos Szeredi }; 115902c048b9SMiklos Szeredi 116002c048b9SMiklos Szeredi if (nbytes < ih.len) { 11614ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 116202c048b9SMiklos Szeredi return -EINVAL; 116302c048b9SMiklos Szeredi } 116402c048b9SMiklos Szeredi 116502c048b9SMiklos Szeredi max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one); 1166f88996a9SMiklos Szeredi head = dequeue_forget(fiq, max_forgets, &count); 11674ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 116802c048b9SMiklos Szeredi 116902c048b9SMiklos Szeredi arg.count = count; 117002c048b9SMiklos Szeredi ih.len += count * sizeof(struct fuse_forget_one); 117102c048b9SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 117202c048b9SMiklos Szeredi if (!err) 117302c048b9SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 117402c048b9SMiklos Szeredi 117502c048b9SMiklos Szeredi while (head) { 117602c048b9SMiklos Szeredi struct fuse_forget_link *forget = head; 117702c048b9SMiklos Szeredi 117802c048b9SMiklos Szeredi if (!err) { 117902c048b9SMiklos Szeredi err = fuse_copy_one(cs, &forget->forget_one, 118002c048b9SMiklos Szeredi sizeof(forget->forget_one)); 118102c048b9SMiklos Szeredi } 118202c048b9SMiklos Szeredi head = forget->next; 118302c048b9SMiklos Szeredi kfree(forget); 118402c048b9SMiklos Szeredi } 118502c048b9SMiklos Szeredi 118602c048b9SMiklos Szeredi fuse_copy_finish(cs); 118702c048b9SMiklos Szeredi 118802c048b9SMiklos Szeredi if (err) 118902c048b9SMiklos Szeredi return err; 119002c048b9SMiklos Szeredi 119102c048b9SMiklos Szeredi return ih.len; 119202c048b9SMiklos Szeredi } 119302c048b9SMiklos Szeredi 1194fd22d62eSMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq, 1195fd22d62eSMiklos Szeredi struct fuse_copy_state *cs, 119602c048b9SMiklos Szeredi size_t nbytes) 1197fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock) 119802c048b9SMiklos Szeredi { 1199f88996a9SMiklos Szeredi if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL) 1200fd22d62eSMiklos Szeredi return fuse_read_single_forget(fiq, cs, nbytes); 120102c048b9SMiklos Szeredi else 1202fd22d62eSMiklos Szeredi return fuse_read_batch_forget(fiq, cs, nbytes); 120302c048b9SMiklos Szeredi } 120402c048b9SMiklos Szeredi 1205a4d27e75SMiklos Szeredi /* 1206334f485dSMiklos Szeredi * Read a single request into the userspace filesystem's buffer. This 1207334f485dSMiklos Szeredi * function waits until a request is available, then removes it from 1208334f485dSMiklos Szeredi * the pending list and copies request data to userspace buffer. If 1209f9a2842eSMiklos Szeredi * no reply is needed (FORGET) or request has been aborted or there 1210f9a2842eSMiklos Szeredi * was an error during the copying then it's finished by calling 1211334f485dSMiklos Szeredi * request_end(). Otherwise add it to the processing list, and set 1212334f485dSMiklos Szeredi * the 'sent' flag. 1213334f485dSMiklos Szeredi */ 1214c3696046SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, 1215c3021629SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1216334f485dSMiklos Szeredi { 121782cbdcd3SMiklos Szeredi ssize_t err; 1218c3696046SMiklos Szeredi struct fuse_conn *fc = fud->fc; 1219f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 1220c3696046SMiklos Szeredi struct fuse_pqueue *fpq = &fud->pq; 1221334f485dSMiklos Szeredi struct fuse_req *req; 1222334f485dSMiklos Szeredi struct fuse_in *in; 1223334f485dSMiklos Szeredi unsigned reqsize; 1224334f485dSMiklos Szeredi 12251d3d752bSMiklos Szeredi restart: 12264ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 1227e5ac1d1eSJeff Dike err = -EAGAIN; 1228e16714d8SMiklos Szeredi if ((file->f_flags & O_NONBLOCK) && fiq->connected && 1229f88996a9SMiklos Szeredi !request_pending(fiq)) 1230e5ac1d1eSJeff Dike goto err_unlock; 1231e5ac1d1eSJeff Dike 12325250921bSMiklos Szeredi err = wait_event_interruptible_exclusive_locked(fiq->waitq, 12335250921bSMiklos Szeredi !fiq->connected || request_pending(fiq)); 12345250921bSMiklos Szeredi if (err) 12355250921bSMiklos Szeredi goto err_unlock; 12365250921bSMiklos Szeredi 1237334f485dSMiklos Szeredi err = -ENODEV; 1238e16714d8SMiklos Szeredi if (!fiq->connected) 1239334f485dSMiklos Szeredi goto err_unlock; 1240334f485dSMiklos Szeredi 1241f88996a9SMiklos Szeredi if (!list_empty(&fiq->interrupts)) { 1242f88996a9SMiklos Szeredi req = list_entry(fiq->interrupts.next, struct fuse_req, 1243a4d27e75SMiklos Szeredi intr_entry); 1244fd22d62eSMiklos Szeredi return fuse_read_interrupt(fiq, cs, nbytes, req); 1245a4d27e75SMiklos Szeredi } 1246a4d27e75SMiklos Szeredi 1247f88996a9SMiklos Szeredi if (forget_pending(fiq)) { 1248f88996a9SMiklos Szeredi if (list_empty(&fiq->pending) || fiq->forget_batch-- > 0) 1249fd22d62eSMiklos Szeredi return fuse_read_forget(fc, fiq, cs, nbytes); 125007e77dcaSMiklos Szeredi 1251f88996a9SMiklos Szeredi if (fiq->forget_batch <= -8) 1252f88996a9SMiklos Szeredi fiq->forget_batch = 16; 125307e77dcaSMiklos Szeredi } 125407e77dcaSMiklos Szeredi 1255f88996a9SMiklos Szeredi req = list_entry(fiq->pending.next, struct fuse_req, list); 125633e14b4dSMiklos Szeredi clear_bit(FR_PENDING, &req->flags); 1257ef759258SMiklos Szeredi list_del_init(&req->list); 12584ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 12594ce60812SMiklos Szeredi 1260334f485dSMiklos Szeredi in = &req->in; 12611d3d752bSMiklos Szeredi reqsize = in->h.len; 12625d6d3a30SMiklos Szeredi 12635d6d3a30SMiklos Szeredi if (task_active_pid_ns(current) != fc->pid_ns) { 12645d6d3a30SMiklos Szeredi rcu_read_lock(); 12655d6d3a30SMiklos Szeredi in->h.pid = pid_vnr(find_pid_ns(in->h.pid, fc->pid_ns)); 12665d6d3a30SMiklos Szeredi rcu_read_unlock(); 12675d6d3a30SMiklos Szeredi } 12685d6d3a30SMiklos Szeredi 12691d3d752bSMiklos Szeredi /* If request is too large, reply with an error and restart the read */ 1270c3021629SMiklos Szeredi if (nbytes < reqsize) { 12711d3d752bSMiklos Szeredi req->out.h.error = -EIO; 12721d3d752bSMiklos Szeredi /* SETXATTR is special, since it may contain too large data */ 12731d3d752bSMiklos Szeredi if (in->h.opcode == FUSE_SETXATTR) 12741d3d752bSMiklos Szeredi req->out.h.error = -E2BIG; 12751d3d752bSMiklos Szeredi request_end(fc, req); 12761d3d752bSMiklos Szeredi goto restart; 12771d3d752bSMiklos Szeredi } 127845a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 127982cbdcd3SMiklos Szeredi list_add(&req->list, &fpq->io); 128045a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 1281c3021629SMiklos Szeredi cs->req = req; 1282c3021629SMiklos Szeredi err = fuse_copy_one(cs, &in->h, sizeof(in->h)); 1283334f485dSMiklos Szeredi if (!err) 1284c3021629SMiklos Szeredi err = fuse_copy_args(cs, in->numargs, in->argpages, 1285334f485dSMiklos Szeredi (struct fuse_arg *) in->args, 0); 1286c3021629SMiklos Szeredi fuse_copy_finish(cs); 128745a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 1288825d6d33SMiklos Szeredi clear_bit(FR_LOCKED, &req->flags); 1289e96edd94SMiklos Szeredi if (!fpq->connected) { 129082cbdcd3SMiklos Szeredi err = -ENODEV; 129182cbdcd3SMiklos Szeredi goto out_end; 1292c9c9d7dfSMiklos Szeredi } 1293334f485dSMiklos Szeredi if (err) { 1294334f485dSMiklos Szeredi req->out.h.error = -EIO; 129582cbdcd3SMiklos Szeredi goto out_end; 1296334f485dSMiklos Szeredi } 1297825d6d33SMiklos Szeredi if (!test_bit(FR_ISREPLY, &req->flags)) { 129882cbdcd3SMiklos Szeredi err = reqsize; 129982cbdcd3SMiklos Szeredi goto out_end; 130082cbdcd3SMiklos Szeredi } 13013a2b5b9cSMiklos Szeredi list_move_tail(&req->list, &fpq->processing); 130245a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 13038f7bb368SMiklos Szeredi set_bit(FR_SENT, &req->flags); 13048f7bb368SMiklos Szeredi /* matches barrier in request_wait_answer() */ 13058f7bb368SMiklos Szeredi smp_mb__after_atomic(); 1306825d6d33SMiklos Szeredi if (test_bit(FR_INTERRUPTED, &req->flags)) 1307f88996a9SMiklos Szeredi queue_interrupt(fiq, req); 130882cbdcd3SMiklos Szeredi 1309334f485dSMiklos Szeredi return reqsize; 1310334f485dSMiklos Szeredi 131182cbdcd3SMiklos Szeredi out_end: 131277cd9d48SMiklos Szeredi if (!test_bit(FR_PRIVATE, &req->flags)) 131382cbdcd3SMiklos Szeredi list_del_init(&req->list); 131445a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 131582cbdcd3SMiklos Szeredi request_end(fc, req); 131682cbdcd3SMiklos Szeredi return err; 131782cbdcd3SMiklos Szeredi 1318334f485dSMiklos Szeredi err_unlock: 13194ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 1320334f485dSMiklos Szeredi return err; 1321334f485dSMiklos Szeredi } 1322334f485dSMiklos Szeredi 132394e4fe2cSTom Van Braeckel static int fuse_dev_open(struct inode *inode, struct file *file) 132494e4fe2cSTom Van Braeckel { 132594e4fe2cSTom Van Braeckel /* 132694e4fe2cSTom Van Braeckel * The fuse device's file's private_data is used to hold 132794e4fe2cSTom Van Braeckel * the fuse_conn(ection) when it is mounted, and is used to 132894e4fe2cSTom Van Braeckel * keep track of whether the file has been mounted already. 132994e4fe2cSTom Van Braeckel */ 133094e4fe2cSTom Van Braeckel file->private_data = NULL; 133194e4fe2cSTom Van Braeckel return 0; 133294e4fe2cSTom Van Braeckel } 133394e4fe2cSTom Van Braeckel 1334fbdbaccaSAl Viro static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to) 1335c3021629SMiklos Szeredi { 1336c3021629SMiklos Szeredi struct fuse_copy_state cs; 1337c3021629SMiklos Szeredi struct file *file = iocb->ki_filp; 1338cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(file); 1339cc080e9eSMiklos Szeredi 1340cc080e9eSMiklos Szeredi if (!fud) 1341c3021629SMiklos Szeredi return -EPERM; 1342c3021629SMiklos Szeredi 1343fbdbaccaSAl Viro if (!iter_is_iovec(to)) 1344fbdbaccaSAl Viro return -EINVAL; 1345c3021629SMiklos Szeredi 1346dc00809aSMiklos Szeredi fuse_copy_init(&cs, 1, to); 1347fbdbaccaSAl Viro 1348c3696046SMiklos Szeredi return fuse_dev_do_read(fud, file, &cs, iov_iter_count(to)); 1349c3021629SMiklos Szeredi } 1350c3021629SMiklos Szeredi 1351c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, 1352c3021629SMiklos Szeredi struct pipe_inode_info *pipe, 1353c3021629SMiklos Szeredi size_t len, unsigned int flags) 1354c3021629SMiklos Szeredi { 1355d82718e3SAl Viro int total, ret; 1356c3021629SMiklos Szeredi int page_nr = 0; 1357c3021629SMiklos Szeredi struct pipe_buffer *bufs; 1358c3021629SMiklos Szeredi struct fuse_copy_state cs; 1359cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(in); 1360cc080e9eSMiklos Szeredi 1361cc080e9eSMiklos Szeredi if (!fud) 1362c3021629SMiklos Szeredi return -EPERM; 1363c3021629SMiklos Szeredi 1364c3021629SMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1365c3021629SMiklos Szeredi if (!bufs) 1366c3021629SMiklos Szeredi return -ENOMEM; 1367c3021629SMiklos Szeredi 1368dc00809aSMiklos Szeredi fuse_copy_init(&cs, 1, NULL); 1369c3021629SMiklos Szeredi cs.pipebufs = bufs; 1370c3021629SMiklos Szeredi cs.pipe = pipe; 1371c3696046SMiklos Szeredi ret = fuse_dev_do_read(fud, in, &cs, len); 1372c3021629SMiklos Szeredi if (ret < 0) 1373c3021629SMiklos Szeredi goto out; 1374c3021629SMiklos Szeredi 1375c3021629SMiklos Szeredi if (pipe->nrbufs + cs.nr_segs > pipe->buffers) { 1376c3021629SMiklos Szeredi ret = -EIO; 1377d82718e3SAl Viro goto out; 1378c3021629SMiklos Szeredi } 1379c3021629SMiklos Szeredi 1380d82718e3SAl Viro for (ret = total = 0; page_nr < cs.nr_segs; total += ret) { 138128a625cbSMiklos Szeredi /* 138228a625cbSMiklos Szeredi * Need to be careful about this. Having buf->ops in module 138328a625cbSMiklos Szeredi * code can Oops if the buffer persists after module unload. 138428a625cbSMiklos Szeredi */ 1385d82718e3SAl Viro bufs[page_nr].ops = &nosteal_pipe_buf_ops; 138684588a93SMiklos Szeredi bufs[page_nr].flags = 0; 1387d82718e3SAl Viro ret = add_to_pipe(pipe, &bufs[page_nr++]); 1388d82718e3SAl Viro if (unlikely(ret < 0)) 1389d82718e3SAl Viro break; 1390c3021629SMiklos Szeredi } 1391d82718e3SAl Viro if (total) 1392d82718e3SAl Viro ret = total; 1393c3021629SMiklos Szeredi out: 1394c3021629SMiklos Szeredi for (; page_nr < cs.nr_segs; page_nr++) 139509cbfeafSKirill A. Shutemov put_page(bufs[page_nr].page); 1396c3021629SMiklos Szeredi 1397c3021629SMiklos Szeredi kfree(bufs); 1398c3021629SMiklos Szeredi return ret; 1399c3021629SMiklos Szeredi } 1400c3021629SMiklos Szeredi 140195668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size, 140295668a69STejun Heo struct fuse_copy_state *cs) 140395668a69STejun Heo { 140495668a69STejun Heo struct fuse_notify_poll_wakeup_out outarg; 1405f6d47a17SMiklos Szeredi int err = -EINVAL; 140695668a69STejun Heo 140795668a69STejun Heo if (size != sizeof(outarg)) 1408f6d47a17SMiklos Szeredi goto err; 140995668a69STejun Heo 141095668a69STejun Heo err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 141195668a69STejun Heo if (err) 1412f6d47a17SMiklos Szeredi goto err; 141395668a69STejun Heo 1414f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 141595668a69STejun Heo return fuse_notify_poll_wakeup(fc, &outarg); 1416f6d47a17SMiklos Szeredi 1417f6d47a17SMiklos Szeredi err: 1418f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 1419f6d47a17SMiklos Szeredi return err; 142095668a69STejun Heo } 142195668a69STejun Heo 14223b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size, 14233b463ae0SJohn Muir struct fuse_copy_state *cs) 14243b463ae0SJohn Muir { 14253b463ae0SJohn Muir struct fuse_notify_inval_inode_out outarg; 14263b463ae0SJohn Muir int err = -EINVAL; 14273b463ae0SJohn Muir 14283b463ae0SJohn Muir if (size != sizeof(outarg)) 14293b463ae0SJohn Muir goto err; 14303b463ae0SJohn Muir 14313b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 14323b463ae0SJohn Muir if (err) 14333b463ae0SJohn Muir goto err; 14343b463ae0SJohn Muir fuse_copy_finish(cs); 14353b463ae0SJohn Muir 14363b463ae0SJohn Muir down_read(&fc->killsb); 14373b463ae0SJohn Muir err = -ENOENT; 1438b21dda43SMiklos Szeredi if (fc->sb) { 14393b463ae0SJohn Muir err = fuse_reverse_inval_inode(fc->sb, outarg.ino, 14403b463ae0SJohn Muir outarg.off, outarg.len); 1441b21dda43SMiklos Szeredi } 14423b463ae0SJohn Muir up_read(&fc->killsb); 14433b463ae0SJohn Muir return err; 14443b463ae0SJohn Muir 14453b463ae0SJohn Muir err: 14463b463ae0SJohn Muir fuse_copy_finish(cs); 14473b463ae0SJohn Muir return err; 14483b463ae0SJohn Muir } 14493b463ae0SJohn Muir 14503b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, 14513b463ae0SJohn Muir struct fuse_copy_state *cs) 14523b463ae0SJohn Muir { 14533b463ae0SJohn Muir struct fuse_notify_inval_entry_out outarg; 1454b2d82ee3SFang Wenqi int err = -ENOMEM; 1455b2d82ee3SFang Wenqi char *buf; 14563b463ae0SJohn Muir struct qstr name; 14573b463ae0SJohn Muir 1458b2d82ee3SFang Wenqi buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1459b2d82ee3SFang Wenqi if (!buf) 1460b2d82ee3SFang Wenqi goto err; 1461b2d82ee3SFang Wenqi 1462b2d82ee3SFang Wenqi err = -EINVAL; 14633b463ae0SJohn Muir if (size < sizeof(outarg)) 14643b463ae0SJohn Muir goto err; 14653b463ae0SJohn Muir 14663b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 14673b463ae0SJohn Muir if (err) 14683b463ae0SJohn Muir goto err; 14693b463ae0SJohn Muir 14703b463ae0SJohn Muir err = -ENAMETOOLONG; 14713b463ae0SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 14723b463ae0SJohn Muir goto err; 14733b463ae0SJohn Muir 1474c2183d1eSMiklos Szeredi err = -EINVAL; 1475c2183d1eSMiklos Szeredi if (size != sizeof(outarg) + outarg.namelen + 1) 1476c2183d1eSMiklos Szeredi goto err; 1477c2183d1eSMiklos Szeredi 14783b463ae0SJohn Muir name.name = buf; 14793b463ae0SJohn Muir name.len = outarg.namelen; 14803b463ae0SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 14813b463ae0SJohn Muir if (err) 14823b463ae0SJohn Muir goto err; 14833b463ae0SJohn Muir fuse_copy_finish(cs); 14843b463ae0SJohn Muir buf[outarg.namelen] = 0; 14853b463ae0SJohn Muir 14863b463ae0SJohn Muir down_read(&fc->killsb); 14873b463ae0SJohn Muir err = -ENOENT; 1488b21dda43SMiklos Szeredi if (fc->sb) 1489451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 0, &name); 1490451d0f59SJohn Muir up_read(&fc->killsb); 1491451d0f59SJohn Muir kfree(buf); 1492451d0f59SJohn Muir return err; 1493451d0f59SJohn Muir 1494451d0f59SJohn Muir err: 1495451d0f59SJohn Muir kfree(buf); 1496451d0f59SJohn Muir fuse_copy_finish(cs); 1497451d0f59SJohn Muir return err; 1498451d0f59SJohn Muir } 1499451d0f59SJohn Muir 1500451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size, 1501451d0f59SJohn Muir struct fuse_copy_state *cs) 1502451d0f59SJohn Muir { 1503451d0f59SJohn Muir struct fuse_notify_delete_out outarg; 1504451d0f59SJohn Muir int err = -ENOMEM; 1505451d0f59SJohn Muir char *buf; 1506451d0f59SJohn Muir struct qstr name; 1507451d0f59SJohn Muir 1508451d0f59SJohn Muir buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1509451d0f59SJohn Muir if (!buf) 1510451d0f59SJohn Muir goto err; 1511451d0f59SJohn Muir 1512451d0f59SJohn Muir err = -EINVAL; 1513451d0f59SJohn Muir if (size < sizeof(outarg)) 1514451d0f59SJohn Muir goto err; 1515451d0f59SJohn Muir 1516451d0f59SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1517451d0f59SJohn Muir if (err) 1518451d0f59SJohn Muir goto err; 1519451d0f59SJohn Muir 1520451d0f59SJohn Muir err = -ENAMETOOLONG; 1521451d0f59SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 1522451d0f59SJohn Muir goto err; 1523451d0f59SJohn Muir 1524451d0f59SJohn Muir err = -EINVAL; 1525451d0f59SJohn Muir if (size != sizeof(outarg) + outarg.namelen + 1) 1526451d0f59SJohn Muir goto err; 1527451d0f59SJohn Muir 1528451d0f59SJohn Muir name.name = buf; 1529451d0f59SJohn Muir name.len = outarg.namelen; 1530451d0f59SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 1531451d0f59SJohn Muir if (err) 1532451d0f59SJohn Muir goto err; 1533451d0f59SJohn Muir fuse_copy_finish(cs); 1534451d0f59SJohn Muir buf[outarg.namelen] = 0; 1535451d0f59SJohn Muir 1536451d0f59SJohn Muir down_read(&fc->killsb); 1537451d0f59SJohn Muir err = -ENOENT; 1538451d0f59SJohn Muir if (fc->sb) 1539451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 1540451d0f59SJohn Muir outarg.child, &name); 15413b463ae0SJohn Muir up_read(&fc->killsb); 1542b2d82ee3SFang Wenqi kfree(buf); 15433b463ae0SJohn Muir return err; 15443b463ae0SJohn Muir 15453b463ae0SJohn Muir err: 1546b2d82ee3SFang Wenqi kfree(buf); 15473b463ae0SJohn Muir fuse_copy_finish(cs); 15483b463ae0SJohn Muir return err; 15493b463ae0SJohn Muir } 15503b463ae0SJohn Muir 1551a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, 1552a1d75f25SMiklos Szeredi struct fuse_copy_state *cs) 1553a1d75f25SMiklos Szeredi { 1554a1d75f25SMiklos Szeredi struct fuse_notify_store_out outarg; 1555a1d75f25SMiklos Szeredi struct inode *inode; 1556a1d75f25SMiklos Szeredi struct address_space *mapping; 1557a1d75f25SMiklos Szeredi u64 nodeid; 1558a1d75f25SMiklos Szeredi int err; 1559a1d75f25SMiklos Szeredi pgoff_t index; 1560a1d75f25SMiklos Szeredi unsigned int offset; 1561a1d75f25SMiklos Szeredi unsigned int num; 1562a1d75f25SMiklos Szeredi loff_t file_size; 1563a1d75f25SMiklos Szeredi loff_t end; 1564a1d75f25SMiklos Szeredi 1565a1d75f25SMiklos Szeredi err = -EINVAL; 1566a1d75f25SMiklos Szeredi if (size < sizeof(outarg)) 1567a1d75f25SMiklos Szeredi goto out_finish; 1568a1d75f25SMiklos Szeredi 1569a1d75f25SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1570a1d75f25SMiklos Szeredi if (err) 1571a1d75f25SMiklos Szeredi goto out_finish; 1572a1d75f25SMiklos Szeredi 1573a1d75f25SMiklos Szeredi err = -EINVAL; 1574a1d75f25SMiklos Szeredi if (size - sizeof(outarg) != outarg.size) 1575a1d75f25SMiklos Szeredi goto out_finish; 1576a1d75f25SMiklos Szeredi 1577a1d75f25SMiklos Szeredi nodeid = outarg.nodeid; 1578a1d75f25SMiklos Szeredi 1579a1d75f25SMiklos Szeredi down_read(&fc->killsb); 1580a1d75f25SMiklos Szeredi 1581a1d75f25SMiklos Szeredi err = -ENOENT; 1582a1d75f25SMiklos Szeredi if (!fc->sb) 1583a1d75f25SMiklos Szeredi goto out_up_killsb; 1584a1d75f25SMiklos Szeredi 1585a1d75f25SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 1586a1d75f25SMiklos Szeredi if (!inode) 1587a1d75f25SMiklos Szeredi goto out_up_killsb; 1588a1d75f25SMiklos Szeredi 1589a1d75f25SMiklos Szeredi mapping = inode->i_mapping; 159009cbfeafSKirill A. Shutemov index = outarg.offset >> PAGE_SHIFT; 159109cbfeafSKirill A. Shutemov offset = outarg.offset & ~PAGE_MASK; 1592a1d75f25SMiklos Szeredi file_size = i_size_read(inode); 1593a1d75f25SMiklos Szeredi end = outarg.offset + outarg.size; 1594a1d75f25SMiklos Szeredi if (end > file_size) { 1595a1d75f25SMiklos Szeredi file_size = end; 1596a1d75f25SMiklos Szeredi fuse_write_update_size(inode, file_size); 1597a1d75f25SMiklos Szeredi } 1598a1d75f25SMiklos Szeredi 1599a1d75f25SMiklos Szeredi num = outarg.size; 1600a1d75f25SMiklos Szeredi while (num) { 1601a1d75f25SMiklos Szeredi struct page *page; 1602a1d75f25SMiklos Szeredi unsigned int this_num; 1603a1d75f25SMiklos Szeredi 1604a1d75f25SMiklos Szeredi err = -ENOMEM; 1605a1d75f25SMiklos Szeredi page = find_or_create_page(mapping, index, 1606a1d75f25SMiklos Szeredi mapping_gfp_mask(mapping)); 1607a1d75f25SMiklos Szeredi if (!page) 1608a1d75f25SMiklos Szeredi goto out_iput; 1609a1d75f25SMiklos Szeredi 161009cbfeafSKirill A. Shutemov this_num = min_t(unsigned, num, PAGE_SIZE - offset); 1611a1d75f25SMiklos Szeredi err = fuse_copy_page(cs, &page, offset, this_num, 0); 1612063ec1e5SMiklos Szeredi if (!err && offset == 0 && 161309cbfeafSKirill A. Shutemov (this_num == PAGE_SIZE || file_size == end)) 1614a1d75f25SMiklos Szeredi SetPageUptodate(page); 1615a1d75f25SMiklos Szeredi unlock_page(page); 161609cbfeafSKirill A. Shutemov put_page(page); 1617a1d75f25SMiklos Szeredi 1618a1d75f25SMiklos Szeredi if (err) 1619a1d75f25SMiklos Szeredi goto out_iput; 1620a1d75f25SMiklos Szeredi 1621a1d75f25SMiklos Szeredi num -= this_num; 1622a1d75f25SMiklos Szeredi offset = 0; 1623a1d75f25SMiklos Szeredi index++; 1624a1d75f25SMiklos Szeredi } 1625a1d75f25SMiklos Szeredi 1626a1d75f25SMiklos Szeredi err = 0; 1627a1d75f25SMiklos Szeredi 1628a1d75f25SMiklos Szeredi out_iput: 1629a1d75f25SMiklos Szeredi iput(inode); 1630a1d75f25SMiklos Szeredi out_up_killsb: 1631a1d75f25SMiklos Szeredi up_read(&fc->killsb); 1632a1d75f25SMiklos Szeredi out_finish: 1633a1d75f25SMiklos Szeredi fuse_copy_finish(cs); 1634a1d75f25SMiklos Szeredi return err; 1635a1d75f25SMiklos Szeredi } 1636a1d75f25SMiklos Szeredi 16372d45ba38SMiklos Szeredi static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) 16382d45ba38SMiklos Szeredi { 1639c6f92f9fSMel Gorman release_pages(req->pages, req->num_pages); 16402d45ba38SMiklos Szeredi } 16412d45ba38SMiklos Szeredi 16422d45ba38SMiklos Szeredi static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, 16432d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out *outarg) 16442d45ba38SMiklos Szeredi { 16452d45ba38SMiklos Szeredi int err; 16462d45ba38SMiklos Szeredi struct address_space *mapping = inode->i_mapping; 16472d45ba38SMiklos Szeredi struct fuse_req *req; 16482d45ba38SMiklos Szeredi pgoff_t index; 16492d45ba38SMiklos Szeredi loff_t file_size; 16502d45ba38SMiklos Szeredi unsigned int num; 16512d45ba38SMiklos Szeredi unsigned int offset; 16520157443cSGeert Uytterhoeven size_t total_len = 0; 16534d53dc99SMaxim Patlasov int num_pages; 16542d45ba38SMiklos Szeredi 165509cbfeafSKirill A. Shutemov offset = outarg->offset & ~PAGE_MASK; 16564d53dc99SMaxim Patlasov file_size = i_size_read(inode); 16574d53dc99SMaxim Patlasov 16584d53dc99SMaxim Patlasov num = outarg->size; 16594d53dc99SMaxim Patlasov if (outarg->offset > file_size) 16604d53dc99SMaxim Patlasov num = 0; 16614d53dc99SMaxim Patlasov else if (outarg->offset + num > file_size) 16624d53dc99SMaxim Patlasov num = file_size - outarg->offset; 16634d53dc99SMaxim Patlasov 16644d53dc99SMaxim Patlasov num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; 16654d53dc99SMaxim Patlasov num_pages = min(num_pages, FUSE_MAX_PAGES_PER_REQ); 16664d53dc99SMaxim Patlasov 16674d53dc99SMaxim Patlasov req = fuse_get_req(fc, num_pages); 16684d53dc99SMaxim Patlasov if (IS_ERR(req)) 16694d53dc99SMaxim Patlasov return PTR_ERR(req); 16702d45ba38SMiklos Szeredi 16712d45ba38SMiklos Szeredi req->in.h.opcode = FUSE_NOTIFY_REPLY; 16722d45ba38SMiklos Szeredi req->in.h.nodeid = outarg->nodeid; 16732d45ba38SMiklos Szeredi req->in.numargs = 2; 16742d45ba38SMiklos Szeredi req->in.argpages = 1; 1675b2430d75SMaxim Patlasov req->page_descs[0].offset = offset; 16762d45ba38SMiklos Szeredi req->end = fuse_retrieve_end; 16772d45ba38SMiklos Szeredi 167809cbfeafSKirill A. Shutemov index = outarg->offset >> PAGE_SHIFT; 16792d45ba38SMiklos Szeredi 16804d53dc99SMaxim Patlasov while (num && req->num_pages < num_pages) { 16812d45ba38SMiklos Szeredi struct page *page; 16822d45ba38SMiklos Szeredi unsigned int this_num; 16832d45ba38SMiklos Szeredi 16842d45ba38SMiklos Szeredi page = find_get_page(mapping, index); 16852d45ba38SMiklos Szeredi if (!page) 16862d45ba38SMiklos Szeredi break; 16872d45ba38SMiklos Szeredi 168809cbfeafSKirill A. Shutemov this_num = min_t(unsigned, num, PAGE_SIZE - offset); 16892d45ba38SMiklos Szeredi req->pages[req->num_pages] = page; 169085f40aecSMaxim Patlasov req->page_descs[req->num_pages].length = this_num; 16912d45ba38SMiklos Szeredi req->num_pages++; 16922d45ba38SMiklos Szeredi 1693c9e67d48SMiklos Szeredi offset = 0; 16942d45ba38SMiklos Szeredi num -= this_num; 16952d45ba38SMiklos Szeredi total_len += this_num; 169648706d0aSMiklos Szeredi index++; 16972d45ba38SMiklos Szeredi } 16982d45ba38SMiklos Szeredi req->misc.retrieve_in.offset = outarg->offset; 16992d45ba38SMiklos Szeredi req->misc.retrieve_in.size = total_len; 17002d45ba38SMiklos Szeredi req->in.args[0].size = sizeof(req->misc.retrieve_in); 17012d45ba38SMiklos Szeredi req->in.args[0].value = &req->misc.retrieve_in; 17022d45ba38SMiklos Szeredi req->in.args[1].size = total_len; 17032d45ba38SMiklos Szeredi 17042d45ba38SMiklos Szeredi err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique); 17052d45ba38SMiklos Szeredi if (err) 17062d45ba38SMiklos Szeredi fuse_retrieve_end(fc, req); 17072d45ba38SMiklos Szeredi 17082d45ba38SMiklos Szeredi return err; 17092d45ba38SMiklos Szeredi } 17102d45ba38SMiklos Szeredi 17112d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, 17122d45ba38SMiklos Szeredi struct fuse_copy_state *cs) 17132d45ba38SMiklos Szeredi { 17142d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out outarg; 17152d45ba38SMiklos Szeredi struct inode *inode; 17162d45ba38SMiklos Szeredi int err; 17172d45ba38SMiklos Szeredi 17182d45ba38SMiklos Szeredi err = -EINVAL; 17192d45ba38SMiklos Szeredi if (size != sizeof(outarg)) 17202d45ba38SMiklos Szeredi goto copy_finish; 17212d45ba38SMiklos Szeredi 17222d45ba38SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 17232d45ba38SMiklos Szeredi if (err) 17242d45ba38SMiklos Szeredi goto copy_finish; 17252d45ba38SMiklos Szeredi 17262d45ba38SMiklos Szeredi fuse_copy_finish(cs); 17272d45ba38SMiklos Szeredi 17282d45ba38SMiklos Szeredi down_read(&fc->killsb); 17292d45ba38SMiklos Szeredi err = -ENOENT; 17302d45ba38SMiklos Szeredi if (fc->sb) { 17312d45ba38SMiklos Szeredi u64 nodeid = outarg.nodeid; 17322d45ba38SMiklos Szeredi 17332d45ba38SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 17342d45ba38SMiklos Szeredi if (inode) { 17352d45ba38SMiklos Szeredi err = fuse_retrieve(fc, inode, &outarg); 17362d45ba38SMiklos Szeredi iput(inode); 17372d45ba38SMiklos Szeredi } 17382d45ba38SMiklos Szeredi } 17392d45ba38SMiklos Szeredi up_read(&fc->killsb); 17402d45ba38SMiklos Szeredi 17412d45ba38SMiklos Szeredi return err; 17422d45ba38SMiklos Szeredi 17432d45ba38SMiklos Szeredi copy_finish: 17442d45ba38SMiklos Szeredi fuse_copy_finish(cs); 17452d45ba38SMiklos Szeredi return err; 17462d45ba38SMiklos Szeredi } 17472d45ba38SMiklos Szeredi 17488599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, 17498599396bSTejun Heo unsigned int size, struct fuse_copy_state *cs) 17508599396bSTejun Heo { 17510d278362SMiklos Szeredi /* Don't try to move pages (yet) */ 17520d278362SMiklos Szeredi cs->move_pages = 0; 17530d278362SMiklos Szeredi 17548599396bSTejun Heo switch (code) { 175595668a69STejun Heo case FUSE_NOTIFY_POLL: 175695668a69STejun Heo return fuse_notify_poll(fc, size, cs); 175795668a69STejun Heo 17583b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_INODE: 17593b463ae0SJohn Muir return fuse_notify_inval_inode(fc, size, cs); 17603b463ae0SJohn Muir 17613b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_ENTRY: 17623b463ae0SJohn Muir return fuse_notify_inval_entry(fc, size, cs); 17633b463ae0SJohn Muir 1764a1d75f25SMiklos Szeredi case FUSE_NOTIFY_STORE: 1765a1d75f25SMiklos Szeredi return fuse_notify_store(fc, size, cs); 1766a1d75f25SMiklos Szeredi 17672d45ba38SMiklos Szeredi case FUSE_NOTIFY_RETRIEVE: 17682d45ba38SMiklos Szeredi return fuse_notify_retrieve(fc, size, cs); 17692d45ba38SMiklos Szeredi 1770451d0f59SJohn Muir case FUSE_NOTIFY_DELETE: 1771451d0f59SJohn Muir return fuse_notify_delete(fc, size, cs); 1772451d0f59SJohn Muir 17738599396bSTejun Heo default: 1774f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 17758599396bSTejun Heo return -EINVAL; 17768599396bSTejun Heo } 17778599396bSTejun Heo } 17788599396bSTejun Heo 1779334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */ 17803a2b5b9cSMiklos Szeredi static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique) 1781334f485dSMiklos Szeredi { 1782334f485dSMiklos Szeredi struct fuse_req *req; 178305726acaSDong Fang 17843a2b5b9cSMiklos Szeredi list_for_each_entry(req, &fpq->processing, list) { 1785a4d27e75SMiklos Szeredi if (req->in.h.unique == unique || req->intr_unique == unique) 1786334f485dSMiklos Szeredi return req; 1787334f485dSMiklos Szeredi } 1788334f485dSMiklos Szeredi return NULL; 1789334f485dSMiklos Szeredi } 1790334f485dSMiklos Szeredi 1791334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out, 1792334f485dSMiklos Szeredi unsigned nbytes) 1793334f485dSMiklos Szeredi { 1794334f485dSMiklos Szeredi unsigned reqsize = sizeof(struct fuse_out_header); 1795334f485dSMiklos Szeredi 1796334f485dSMiklos Szeredi if (out->h.error) 1797334f485dSMiklos Szeredi return nbytes != reqsize ? -EINVAL : 0; 1798334f485dSMiklos Szeredi 1799334f485dSMiklos Szeredi reqsize += len_args(out->numargs, out->args); 1800334f485dSMiklos Szeredi 1801334f485dSMiklos Szeredi if (reqsize < nbytes || (reqsize > nbytes && !out->argvar)) 1802334f485dSMiklos Szeredi return -EINVAL; 1803334f485dSMiklos Szeredi else if (reqsize > nbytes) { 1804334f485dSMiklos Szeredi struct fuse_arg *lastarg = &out->args[out->numargs-1]; 1805334f485dSMiklos Szeredi unsigned diffsize = reqsize - nbytes; 1806334f485dSMiklos Szeredi if (diffsize > lastarg->size) 1807334f485dSMiklos Szeredi return -EINVAL; 1808334f485dSMiklos Szeredi lastarg->size -= diffsize; 1809334f485dSMiklos Szeredi } 1810334f485dSMiklos Szeredi return fuse_copy_args(cs, out->numargs, out->argpages, out->args, 1811334f485dSMiklos Szeredi out->page_zeroing); 1812334f485dSMiklos Szeredi } 1813334f485dSMiklos Szeredi 1814334f485dSMiklos Szeredi /* 1815334f485dSMiklos Szeredi * Write a single reply to a request. First the header is copied from 1816334f485dSMiklos Szeredi * the write buffer. The request is then searched on the processing 1817334f485dSMiklos Szeredi * list by the unique ID found in the header. If found, then remove 1818334f485dSMiklos Szeredi * it from the list and copy the rest of the buffer to the request. 1819334f485dSMiklos Szeredi * The request is finished by calling request_end() 1820334f485dSMiklos Szeredi */ 1821c3696046SMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_dev *fud, 1822dd3bb14fSMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1823334f485dSMiklos Szeredi { 1824334f485dSMiklos Szeredi int err; 1825c3696046SMiklos Szeredi struct fuse_conn *fc = fud->fc; 1826c3696046SMiklos Szeredi struct fuse_pqueue *fpq = &fud->pq; 1827334f485dSMiklos Szeredi struct fuse_req *req; 1828334f485dSMiklos Szeredi struct fuse_out_header oh; 1829334f485dSMiklos Szeredi 1830334f485dSMiklos Szeredi if (nbytes < sizeof(struct fuse_out_header)) 1831334f485dSMiklos Szeredi return -EINVAL; 1832334f485dSMiklos Szeredi 1833dd3bb14fSMiklos Szeredi err = fuse_copy_one(cs, &oh, sizeof(oh)); 1834334f485dSMiklos Szeredi if (err) 1835334f485dSMiklos Szeredi goto err_finish; 18368599396bSTejun Heo 1837334f485dSMiklos Szeredi err = -EINVAL; 18388599396bSTejun Heo if (oh.len != nbytes) 18398599396bSTejun Heo goto err_finish; 18408599396bSTejun Heo 18418599396bSTejun Heo /* 18428599396bSTejun Heo * Zero oh.unique indicates unsolicited notification message 18438599396bSTejun Heo * and error contains notification code. 18448599396bSTejun Heo */ 18458599396bSTejun Heo if (!oh.unique) { 1846dd3bb14fSMiklos Szeredi err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs); 18478599396bSTejun Heo return err ? err : nbytes; 18488599396bSTejun Heo } 18498599396bSTejun Heo 18508599396bSTejun Heo err = -EINVAL; 18518599396bSTejun Heo if (oh.error <= -1000 || oh.error > 0) 1852334f485dSMiklos Szeredi goto err_finish; 1853334f485dSMiklos Szeredi 185445a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 185569a53bf2SMiklos Szeredi err = -ENOENT; 1856e96edd94SMiklos Szeredi if (!fpq->connected) 185745a91cb1SMiklos Szeredi goto err_unlock_pq; 185869a53bf2SMiklos Szeredi 18593a2b5b9cSMiklos Szeredi req = request_find(fpq, oh.unique); 1860334f485dSMiklos Szeredi if (!req) 186145a91cb1SMiklos Szeredi goto err_unlock_pq; 1862334f485dSMiklos Szeredi 1863a4d27e75SMiklos Szeredi /* Is it an interrupt reply? */ 1864a4d27e75SMiklos Szeredi if (req->intr_unique == oh.unique) { 186545a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 186645a91cb1SMiklos Szeredi 1867a4d27e75SMiklos Szeredi err = -EINVAL; 1868a4d27e75SMiklos Szeredi if (nbytes != sizeof(struct fuse_out_header)) 186946c34a34SMiklos Szeredi goto err_finish; 1870a4d27e75SMiklos Szeredi 1871a4d27e75SMiklos Szeredi if (oh.error == -ENOSYS) 1872a4d27e75SMiklos Szeredi fc->no_interrupt = 1; 1873a4d27e75SMiklos Szeredi else if (oh.error == -EAGAIN) 1874f88996a9SMiklos Szeredi queue_interrupt(&fc->iq, req); 1875a4d27e75SMiklos Szeredi 1876dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1877a4d27e75SMiklos Szeredi return nbytes; 1878a4d27e75SMiklos Szeredi } 1879a4d27e75SMiklos Szeredi 188033e14b4dSMiklos Szeredi clear_bit(FR_SENT, &req->flags); 18813a2b5b9cSMiklos Szeredi list_move(&req->list, &fpq->io); 1882334f485dSMiklos Szeredi req->out.h = oh; 1883825d6d33SMiklos Szeredi set_bit(FR_LOCKED, &req->flags); 188445a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 1885dd3bb14fSMiklos Szeredi cs->req = req; 1886ce534fb0SMiklos Szeredi if (!req->out.page_replace) 1887ce534fb0SMiklos Szeredi cs->move_pages = 0; 1888334f485dSMiklos Szeredi 1889dd3bb14fSMiklos Szeredi err = copy_out_args(cs, &req->out, nbytes); 1890dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1891334f485dSMiklos Szeredi 189245a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 1893825d6d33SMiklos Szeredi clear_bit(FR_LOCKED, &req->flags); 1894e96edd94SMiklos Szeredi if (!fpq->connected) 1895334f485dSMiklos Szeredi err = -ENOENT; 18960d8e84b0SMiklos Szeredi else if (err) 1897334f485dSMiklos Szeredi req->out.h.error = -EIO; 189877cd9d48SMiklos Szeredi if (!test_bit(FR_PRIVATE, &req->flags)) 1899f377cb79SMiklos Szeredi list_del_init(&req->list); 190045a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 190146c34a34SMiklos Szeredi 1902334f485dSMiklos Szeredi request_end(fc, req); 1903334f485dSMiklos Szeredi 1904334f485dSMiklos Szeredi return err ? err : nbytes; 1905334f485dSMiklos Szeredi 190645a91cb1SMiklos Szeredi err_unlock_pq: 190745a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 1908334f485dSMiklos Szeredi err_finish: 1909dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1910334f485dSMiklos Szeredi return err; 1911334f485dSMiklos Szeredi } 1912334f485dSMiklos Szeredi 1913fbdbaccaSAl Viro static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from) 1914dd3bb14fSMiklos Szeredi { 1915dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1916cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(iocb->ki_filp); 1917cc080e9eSMiklos Szeredi 1918cc080e9eSMiklos Szeredi if (!fud) 1919dd3bb14fSMiklos Szeredi return -EPERM; 1920dd3bb14fSMiklos Szeredi 1921fbdbaccaSAl Viro if (!iter_is_iovec(from)) 1922fbdbaccaSAl Viro return -EINVAL; 1923dd3bb14fSMiklos Szeredi 1924dc00809aSMiklos Szeredi fuse_copy_init(&cs, 0, from); 1925fbdbaccaSAl Viro 1926c3696046SMiklos Szeredi return fuse_dev_do_write(fud, &cs, iov_iter_count(from)); 1927dd3bb14fSMiklos Szeredi } 1928dd3bb14fSMiklos Szeredi 1929dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, 1930dd3bb14fSMiklos Szeredi struct file *out, loff_t *ppos, 1931dd3bb14fSMiklos Szeredi size_t len, unsigned int flags) 1932dd3bb14fSMiklos Szeredi { 1933dd3bb14fSMiklos Szeredi unsigned nbuf; 1934dd3bb14fSMiklos Szeredi unsigned idx; 1935dd3bb14fSMiklos Szeredi struct pipe_buffer *bufs; 1936dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1937cc080e9eSMiklos Szeredi struct fuse_dev *fud; 1938dd3bb14fSMiklos Szeredi size_t rem; 1939dd3bb14fSMiklos Szeredi ssize_t ret; 1940dd3bb14fSMiklos Szeredi 1941cc080e9eSMiklos Szeredi fud = fuse_get_dev(out); 1942cc080e9eSMiklos Szeredi if (!fud) 1943dd3bb14fSMiklos Szeredi return -EPERM; 1944dd3bb14fSMiklos Szeredi 1945dd3bb14fSMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1946dd3bb14fSMiklos Szeredi if (!bufs) 1947dd3bb14fSMiklos Szeredi return -ENOMEM; 1948dd3bb14fSMiklos Szeredi 1949dd3bb14fSMiklos Szeredi pipe_lock(pipe); 1950dd3bb14fSMiklos Szeredi nbuf = 0; 1951dd3bb14fSMiklos Szeredi rem = 0; 1952dd3bb14fSMiklos Szeredi for (idx = 0; idx < pipe->nrbufs && rem < len; idx++) 1953dd3bb14fSMiklos Szeredi rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len; 1954dd3bb14fSMiklos Szeredi 1955dd3bb14fSMiklos Szeredi ret = -EINVAL; 1956dd3bb14fSMiklos Szeredi if (rem < len) { 1957dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 1958dd3bb14fSMiklos Szeredi goto out; 1959dd3bb14fSMiklos Szeredi } 1960dd3bb14fSMiklos Szeredi 1961dd3bb14fSMiklos Szeredi rem = len; 1962dd3bb14fSMiklos Szeredi while (rem) { 1963dd3bb14fSMiklos Szeredi struct pipe_buffer *ibuf; 1964dd3bb14fSMiklos Szeredi struct pipe_buffer *obuf; 1965dd3bb14fSMiklos Szeredi 1966dd3bb14fSMiklos Szeredi BUG_ON(nbuf >= pipe->buffers); 1967dd3bb14fSMiklos Szeredi BUG_ON(!pipe->nrbufs); 1968dd3bb14fSMiklos Szeredi ibuf = &pipe->bufs[pipe->curbuf]; 1969dd3bb14fSMiklos Szeredi obuf = &bufs[nbuf]; 1970dd3bb14fSMiklos Szeredi 1971dd3bb14fSMiklos Szeredi if (rem >= ibuf->len) { 1972dd3bb14fSMiklos Szeredi *obuf = *ibuf; 1973dd3bb14fSMiklos Szeredi ibuf->ops = NULL; 1974dd3bb14fSMiklos Szeredi pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); 1975dd3bb14fSMiklos Szeredi pipe->nrbufs--; 1976dd3bb14fSMiklos Szeredi } else { 19777bf2d1dfSMiklos Szeredi pipe_buf_get(pipe, ibuf); 1978dd3bb14fSMiklos Szeredi *obuf = *ibuf; 1979dd3bb14fSMiklos Szeredi obuf->flags &= ~PIPE_BUF_FLAG_GIFT; 1980dd3bb14fSMiklos Szeredi obuf->len = rem; 1981dd3bb14fSMiklos Szeredi ibuf->offset += obuf->len; 1982dd3bb14fSMiklos Szeredi ibuf->len -= obuf->len; 1983dd3bb14fSMiklos Szeredi } 1984dd3bb14fSMiklos Szeredi nbuf++; 1985dd3bb14fSMiklos Szeredi rem -= obuf->len; 1986dd3bb14fSMiklos Szeredi } 1987dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 1988dd3bb14fSMiklos Szeredi 1989dc00809aSMiklos Szeredi fuse_copy_init(&cs, 0, NULL); 1990dd3bb14fSMiklos Szeredi cs.pipebufs = bufs; 19916c09e94aSAl Viro cs.nr_segs = nbuf; 1992dd3bb14fSMiklos Szeredi cs.pipe = pipe; 1993dd3bb14fSMiklos Szeredi 1994ce534fb0SMiklos Szeredi if (flags & SPLICE_F_MOVE) 1995ce534fb0SMiklos Szeredi cs.move_pages = 1; 1996ce534fb0SMiklos Szeredi 1997c3696046SMiklos Szeredi ret = fuse_dev_do_write(fud, &cs, len); 1998dd3bb14fSMiklos Szeredi 1999a779638cSMiklos Szeredi for (idx = 0; idx < nbuf; idx++) 2000a779638cSMiklos Szeredi pipe_buf_release(pipe, &bufs[idx]); 2001a779638cSMiklos Szeredi 2002dd3bb14fSMiklos Szeredi out: 2003dd3bb14fSMiklos Szeredi kfree(bufs); 2004dd3bb14fSMiklos Szeredi return ret; 2005dd3bb14fSMiklos Szeredi } 2006dd3bb14fSMiklos Szeredi 2007076ccb76SAl Viro static __poll_t fuse_dev_poll(struct file *file, poll_table *wait) 2008334f485dSMiklos Szeredi { 2009a9a08845SLinus Torvalds __poll_t mask = EPOLLOUT | EPOLLWRNORM; 2010f88996a9SMiklos Szeredi struct fuse_iqueue *fiq; 2011cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(file); 2012cc080e9eSMiklos Szeredi 2013cc080e9eSMiklos Szeredi if (!fud) 2014a9a08845SLinus Torvalds return EPOLLERR; 2015334f485dSMiklos Szeredi 2016cc080e9eSMiklos Szeredi fiq = &fud->fc->iq; 2017f88996a9SMiklos Szeredi poll_wait(file, &fiq->waitq, wait); 2018334f485dSMiklos Szeredi 20194ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 2020e16714d8SMiklos Szeredi if (!fiq->connected) 2021a9a08845SLinus Torvalds mask = EPOLLERR; 2022f88996a9SMiklos Szeredi else if (request_pending(fiq)) 2023a9a08845SLinus Torvalds mask |= EPOLLIN | EPOLLRDNORM; 20244ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 2025334f485dSMiklos Szeredi 2026334f485dSMiklos Szeredi return mask; 2027334f485dSMiklos Szeredi } 2028334f485dSMiklos Szeredi 202969a53bf2SMiklos Szeredi /* 203069a53bf2SMiklos Szeredi * Abort all requests on the given list (pending or processing) 203169a53bf2SMiklos Szeredi * 2032d7133114SMiklos Szeredi * This function releases and reacquires fc->lock 203369a53bf2SMiklos Szeredi */ 2034334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head) 2035334f485dSMiklos Szeredi { 2036334f485dSMiklos Szeredi while (!list_empty(head)) { 2037334f485dSMiklos Szeredi struct fuse_req *req; 2038334f485dSMiklos Szeredi req = list_entry(head->next, struct fuse_req, list); 2039334f485dSMiklos Szeredi req->out.h.error = -ECONNABORTED; 204033e14b4dSMiklos Szeredi clear_bit(FR_SENT, &req->flags); 2041f377cb79SMiklos Szeredi list_del_init(&req->list); 2042334f485dSMiklos Szeredi request_end(fc, req); 2043334f485dSMiklos Szeredi } 2044334f485dSMiklos Szeredi } 2045334f485dSMiklos Szeredi 2046357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc) 2047357ccf2bSBryan Green { 2048357ccf2bSBryan Green struct rb_node *p; 2049357ccf2bSBryan Green 2050357ccf2bSBryan Green p = rb_first(&fc->polled_files); 2051357ccf2bSBryan Green 2052357ccf2bSBryan Green while (p) { 2053357ccf2bSBryan Green struct fuse_file *ff; 2054357ccf2bSBryan Green ff = rb_entry(p, struct fuse_file, polled_node); 2055357ccf2bSBryan Green wake_up_interruptible_all(&ff->poll_wait); 2056357ccf2bSBryan Green 2057357ccf2bSBryan Green p = rb_next(p); 2058357ccf2bSBryan Green } 2059357ccf2bSBryan Green } 2060357ccf2bSBryan Green 206169a53bf2SMiklos Szeredi /* 206269a53bf2SMiklos Szeredi * Abort all requests. 206369a53bf2SMiklos Szeredi * 2064b716d425SMiklos Szeredi * Emergency exit in case of a malicious or accidental deadlock, or just a hung 2065b716d425SMiklos Szeredi * filesystem. 206669a53bf2SMiklos Szeredi * 2067b716d425SMiklos Szeredi * The same effect is usually achievable through killing the filesystem daemon 2068b716d425SMiklos Szeredi * and all users of the filesystem. The exception is the combination of an 2069b716d425SMiklos Szeredi * asynchronous request and the tricky deadlock (see 2070b716d425SMiklos Szeredi * Documentation/filesystems/fuse.txt). 207169a53bf2SMiklos Szeredi * 2072b716d425SMiklos Szeredi * Aborting requests under I/O goes as follows: 1: Separate out unlocked 2073b716d425SMiklos Szeredi * requests, they should be finished off immediately. Locked requests will be 2074b716d425SMiklos Szeredi * finished after unlock; see unlock_request(). 2: Finish off the unlocked 2075b716d425SMiklos Szeredi * requests. It is possible that some request will finish before we can. This 2076b716d425SMiklos Szeredi * is OK, the request will in that case be removed from the list before we touch 2077b716d425SMiklos Szeredi * it. 207869a53bf2SMiklos Szeredi */ 207969a53bf2SMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc) 208069a53bf2SMiklos Szeredi { 2081f88996a9SMiklos Szeredi struct fuse_iqueue *fiq = &fc->iq; 2082f88996a9SMiklos Szeredi 2083d7133114SMiklos Szeredi spin_lock(&fc->lock); 208469a53bf2SMiklos Szeredi if (fc->connected) { 2085c3696046SMiklos Szeredi struct fuse_dev *fud; 2086b716d425SMiklos Szeredi struct fuse_req *req, *next; 208741f98274SMiklos Szeredi LIST_HEAD(to_end1); 208841f98274SMiklos Szeredi LIST_HEAD(to_end2); 2089b716d425SMiklos Szeredi 209069a53bf2SMiklos Szeredi fc->connected = 0; 209151eb01e7SMiklos Szeredi fc->blocked = 0; 20929759bd51SMiklos Szeredi fuse_set_initialized(fc); 2093c3696046SMiklos Szeredi list_for_each_entry(fud, &fc->devices, entry) { 2094c3696046SMiklos Szeredi struct fuse_pqueue *fpq = &fud->pq; 2095c3696046SMiklos Szeredi 209645a91cb1SMiklos Szeredi spin_lock(&fpq->lock); 2097e96edd94SMiklos Szeredi fpq->connected = 0; 20983a2b5b9cSMiklos Szeredi list_for_each_entry_safe(req, next, &fpq->io, list) { 2099b716d425SMiklos Szeredi req->out.h.error = -ECONNABORTED; 2100b716d425SMiklos Szeredi spin_lock(&req->waitq.lock); 2101b716d425SMiklos Szeredi set_bit(FR_ABORTED, &req->flags); 210277cd9d48SMiklos Szeredi if (!test_bit(FR_LOCKED, &req->flags)) { 210377cd9d48SMiklos Szeredi set_bit(FR_PRIVATE, &req->flags); 210441f98274SMiklos Szeredi list_move(&req->list, &to_end1); 210577cd9d48SMiklos Szeredi } 2106b716d425SMiklos Szeredi spin_unlock(&req->waitq.lock); 2107b716d425SMiklos Szeredi } 210824b4d33dSMiklos Szeredi list_splice_init(&fpq->processing, &to_end2); 210945a91cb1SMiklos Szeredi spin_unlock(&fpq->lock); 2110c3696046SMiklos Szeredi } 211141f98274SMiklos Szeredi fc->max_background = UINT_MAX; 211241f98274SMiklos Szeredi flush_bg_queue(fc); 21138c91189aSMiklos Szeredi 21144ce60812SMiklos Szeredi spin_lock(&fiq->waitq.lock); 21158c91189aSMiklos Szeredi fiq->connected = 0; 2116f88996a9SMiklos Szeredi list_splice_init(&fiq->pending, &to_end2); 2117a8a86d78STahsin Erdogan list_for_each_entry(req, &to_end2, list) 2118a8a86d78STahsin Erdogan clear_bit(FR_PENDING, &req->flags); 21198c91189aSMiklos Szeredi while (forget_pending(fiq)) 21208c91189aSMiklos Szeredi kfree(dequeue_forget(fiq, 1, NULL)); 21214ce60812SMiklos Szeredi wake_up_all_locked(&fiq->waitq); 21224ce60812SMiklos Szeredi spin_unlock(&fiq->waitq.lock); 21238c91189aSMiklos Szeredi kill_fasync(&fiq->fasync, SIGIO, POLL_IN); 2124ee314a87SMiklos Szeredi end_polls(fc); 2125ee314a87SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 2126ee314a87SMiklos Szeredi spin_unlock(&fc->lock); 21278c91189aSMiklos Szeredi 212841f98274SMiklos Szeredi while (!list_empty(&to_end1)) { 212941f98274SMiklos Szeredi req = list_first_entry(&to_end1, struct fuse_req, list); 2130b716d425SMiklos Szeredi __fuse_get_request(req); 2131f377cb79SMiklos Szeredi list_del_init(&req->list); 2132b716d425SMiklos Szeredi request_end(fc, req); 2133b716d425SMiklos Szeredi } 213441f98274SMiklos Szeredi end_requests(fc, &to_end2); 2135ee314a87SMiklos Szeredi } else { 2136d7133114SMiklos Szeredi spin_unlock(&fc->lock); 213769a53bf2SMiklos Szeredi } 2138ee314a87SMiklos Szeredi } 213908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn); 214069a53bf2SMiklos Szeredi 214108cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file) 2142334f485dSMiklos Szeredi { 2143cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(file); 2144cc080e9eSMiklos Szeredi 2145cc080e9eSMiklos Szeredi if (fud) { 2146cc080e9eSMiklos Szeredi struct fuse_conn *fc = fud->fc; 2147c3696046SMiklos Szeredi struct fuse_pqueue *fpq = &fud->pq; 2148cc080e9eSMiklos Szeredi 2149c3696046SMiklos Szeredi WARN_ON(!list_empty(&fpq->io)); 2150c3696046SMiklos Szeredi end_requests(fc, &fpq->processing); 2151c3696046SMiklos Szeredi /* Are we the last open device? */ 2152c3696046SMiklos Szeredi if (atomic_dec_and_test(&fc->dev_count)) { 2153f88996a9SMiklos Szeredi WARN_ON(fc->iq.fasync != NULL); 2154ccd0a0bdSMiklos Szeredi fuse_abort_conn(fc); 2155c3696046SMiklos Szeredi } 2156cc080e9eSMiklos Szeredi fuse_dev_free(fud); 2157385a17bfSJeff Dike } 2158334f485dSMiklos Szeredi return 0; 2159334f485dSMiklos Szeredi } 216008cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release); 2161334f485dSMiklos Szeredi 2162385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on) 2163385a17bfSJeff Dike { 2164cc080e9eSMiklos Szeredi struct fuse_dev *fud = fuse_get_dev(file); 2165cc080e9eSMiklos Szeredi 2166cc080e9eSMiklos Szeredi if (!fud) 2167a87046d8SMiklos Szeredi return -EPERM; 2168385a17bfSJeff Dike 2169385a17bfSJeff Dike /* No locking - fasync_helper does its own locking */ 2170cc080e9eSMiklos Szeredi return fasync_helper(fd, file, on, &fud->fc->iq.fasync); 2171385a17bfSJeff Dike } 2172385a17bfSJeff Dike 217300c570f4SMiklos Szeredi static int fuse_device_clone(struct fuse_conn *fc, struct file *new) 217400c570f4SMiklos Szeredi { 2175cc080e9eSMiklos Szeredi struct fuse_dev *fud; 2176cc080e9eSMiklos Szeredi 217700c570f4SMiklos Szeredi if (new->private_data) 217800c570f4SMiklos Szeredi return -EINVAL; 217900c570f4SMiklos Szeredi 2180cc080e9eSMiklos Szeredi fud = fuse_dev_alloc(fc); 2181cc080e9eSMiklos Szeredi if (!fud) 2182cc080e9eSMiklos Szeredi return -ENOMEM; 2183cc080e9eSMiklos Szeredi 2184cc080e9eSMiklos Szeredi new->private_data = fud; 2185c3696046SMiklos Szeredi atomic_inc(&fc->dev_count); 218600c570f4SMiklos Szeredi 218700c570f4SMiklos Szeredi return 0; 218800c570f4SMiklos Szeredi } 218900c570f4SMiklos Szeredi 219000c570f4SMiklos Szeredi static long fuse_dev_ioctl(struct file *file, unsigned int cmd, 219100c570f4SMiklos Szeredi unsigned long arg) 219200c570f4SMiklos Szeredi { 219300c570f4SMiklos Szeredi int err = -ENOTTY; 219400c570f4SMiklos Szeredi 219500c570f4SMiklos Szeredi if (cmd == FUSE_DEV_IOC_CLONE) { 219600c570f4SMiklos Szeredi int oldfd; 219700c570f4SMiklos Szeredi 219800c570f4SMiklos Szeredi err = -EFAULT; 219900c570f4SMiklos Szeredi if (!get_user(oldfd, (__u32 __user *) arg)) { 220000c570f4SMiklos Szeredi struct file *old = fget(oldfd); 220100c570f4SMiklos Szeredi 220200c570f4SMiklos Szeredi err = -EINVAL; 220300c570f4SMiklos Szeredi if (old) { 22048ed1f0e2SJann Horn struct fuse_dev *fud = NULL; 22058ed1f0e2SJann Horn 22068ed1f0e2SJann Horn /* 22078ed1f0e2SJann Horn * Check against file->f_op because CUSE 22088ed1f0e2SJann Horn * uses the same ioctl handler. 22098ed1f0e2SJann Horn */ 22108ed1f0e2SJann Horn if (old->f_op == file->f_op && 22118ed1f0e2SJann Horn old->f_cred->user_ns == file->f_cred->user_ns) 22128ed1f0e2SJann Horn fud = fuse_get_dev(old); 221300c570f4SMiklos Szeredi 2214cc080e9eSMiklos Szeredi if (fud) { 221500c570f4SMiklos Szeredi mutex_lock(&fuse_mutex); 2216cc080e9eSMiklos Szeredi err = fuse_device_clone(fud->fc, file); 221700c570f4SMiklos Szeredi mutex_unlock(&fuse_mutex); 221800c570f4SMiklos Szeredi } 221900c570f4SMiklos Szeredi fput(old); 222000c570f4SMiklos Szeredi } 222100c570f4SMiklos Szeredi } 222200c570f4SMiklos Szeredi } 222300c570f4SMiklos Szeredi return err; 222400c570f4SMiklos Szeredi } 222500c570f4SMiklos Szeredi 22264b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = { 2227334f485dSMiklos Szeredi .owner = THIS_MODULE, 222894e4fe2cSTom Van Braeckel .open = fuse_dev_open, 2229334f485dSMiklos Szeredi .llseek = no_llseek, 2230fbdbaccaSAl Viro .read_iter = fuse_dev_read, 2231c3021629SMiklos Szeredi .splice_read = fuse_dev_splice_read, 2232fbdbaccaSAl Viro .write_iter = fuse_dev_write, 2233dd3bb14fSMiklos Szeredi .splice_write = fuse_dev_splice_write, 2234334f485dSMiklos Szeredi .poll = fuse_dev_poll, 2235334f485dSMiklos Szeredi .release = fuse_dev_release, 2236385a17bfSJeff Dike .fasync = fuse_dev_fasync, 223700c570f4SMiklos Szeredi .unlocked_ioctl = fuse_dev_ioctl, 223800c570f4SMiklos Szeredi .compat_ioctl = fuse_dev_ioctl, 2239334f485dSMiklos Szeredi }; 224008cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations); 2241334f485dSMiklos Szeredi 2242334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = { 2243334f485dSMiklos Szeredi .minor = FUSE_MINOR, 2244334f485dSMiklos Szeredi .name = "fuse", 2245334f485dSMiklos Szeredi .fops = &fuse_dev_operations, 2246334f485dSMiklos Szeredi }; 2247334f485dSMiklos Szeredi 2248334f485dSMiklos Szeredi int __init fuse_dev_init(void) 2249334f485dSMiklos Szeredi { 2250334f485dSMiklos Szeredi int err = -ENOMEM; 2251334f485dSMiklos Szeredi fuse_req_cachep = kmem_cache_create("fuse_request", 2252334f485dSMiklos Szeredi sizeof(struct fuse_req), 225320c2df83SPaul Mundt 0, 0, NULL); 2254334f485dSMiklos Szeredi if (!fuse_req_cachep) 2255334f485dSMiklos Szeredi goto out; 2256334f485dSMiklos Szeredi 2257334f485dSMiklos Szeredi err = misc_register(&fuse_miscdevice); 2258334f485dSMiklos Szeredi if (err) 2259334f485dSMiklos Szeredi goto out_cache_clean; 2260334f485dSMiklos Szeredi 2261334f485dSMiklos Szeredi return 0; 2262334f485dSMiklos Szeredi 2263334f485dSMiklos Szeredi out_cache_clean: 2264334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2265334f485dSMiklos Szeredi out: 2266334f485dSMiklos Szeredi return err; 2267334f485dSMiklos Szeredi } 2268334f485dSMiklos Szeredi 2269334f485dSMiklos Szeredi void fuse_dev_cleanup(void) 2270334f485dSMiklos Szeredi { 2271334f485dSMiklos Szeredi misc_deregister(&fuse_miscdevice); 2272334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2273334f485dSMiklos Szeredi } 2274