1334f485dSMiklos Szeredi /* 2334f485dSMiklos Szeredi FUSE: Filesystem in Userspace 31729a16cSMiklos Szeredi Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4334f485dSMiklos Szeredi 5334f485dSMiklos Szeredi This program can be distributed under the terms of the GNU GPL. 6334f485dSMiklos Szeredi See the file COPYING. 7334f485dSMiklos Szeredi */ 8334f485dSMiklos Szeredi 9334f485dSMiklos Szeredi #include "fuse_i.h" 10334f485dSMiklos Szeredi 11334f485dSMiklos Szeredi #include <linux/init.h> 12334f485dSMiklos Szeredi #include <linux/module.h> 13334f485dSMiklos Szeredi #include <linux/poll.h> 14334f485dSMiklos Szeredi #include <linux/uio.h> 15334f485dSMiklos Szeredi #include <linux/miscdevice.h> 16334f485dSMiklos Szeredi #include <linux/pagemap.h> 17334f485dSMiklos Szeredi #include <linux/file.h> 18334f485dSMiklos Szeredi #include <linux/slab.h> 19dd3bb14fSMiklos Szeredi #include <linux/pipe_fs_i.h> 20ce534fb0SMiklos Szeredi #include <linux/swap.h> 21ce534fb0SMiklos Szeredi #include <linux/splice.h> 22334f485dSMiklos Szeredi 23334f485dSMiklos Szeredi MODULE_ALIAS_MISCDEV(FUSE_MINOR); 24578454ffSKay Sievers MODULE_ALIAS("devname:fuse"); 25334f485dSMiklos Szeredi 26e18b890bSChristoph Lameter static struct kmem_cache *fuse_req_cachep; 27334f485dSMiklos Szeredi 288bfc016dSMiklos Szeredi static struct fuse_conn *fuse_get_conn(struct file *file) 29334f485dSMiklos Szeredi { 300720b315SMiklos Szeredi /* 310720b315SMiklos Szeredi * Lockless access is OK, because file->private data is set 320720b315SMiklos Szeredi * once during mount and is valid until the file is released. 330720b315SMiklos Szeredi */ 340720b315SMiklos Szeredi return file->private_data; 35334f485dSMiklos Szeredi } 36334f485dSMiklos Szeredi 374250c066SMaxim Patlasov static void fuse_request_init(struct fuse_req *req, struct page **pages, 38b2430d75SMaxim Patlasov struct fuse_page_desc *page_descs, 394250c066SMaxim Patlasov unsigned npages) 40334f485dSMiklos Szeredi { 41334f485dSMiklos Szeredi memset(req, 0, sizeof(*req)); 424250c066SMaxim Patlasov memset(pages, 0, sizeof(*pages) * npages); 43b2430d75SMaxim Patlasov memset(page_descs, 0, sizeof(*page_descs) * npages); 44334f485dSMiklos Szeredi INIT_LIST_HEAD(&req->list); 45a4d27e75SMiklos Szeredi INIT_LIST_HEAD(&req->intr_entry); 46334f485dSMiklos Szeredi init_waitqueue_head(&req->waitq); 47334f485dSMiklos Szeredi atomic_set(&req->count, 1); 484250c066SMaxim Patlasov req->pages = pages; 49b2430d75SMaxim Patlasov req->page_descs = page_descs; 504250c066SMaxim Patlasov req->max_pages = npages; 51334f485dSMiklos Szeredi } 52334f485dSMiklos Szeredi 534250c066SMaxim Patlasov static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) 54334f485dSMiklos Szeredi { 554250c066SMaxim Patlasov struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, flags); 564250c066SMaxim Patlasov if (req) { 574250c066SMaxim Patlasov struct page **pages; 58b2430d75SMaxim Patlasov struct fuse_page_desc *page_descs; 594250c066SMaxim Patlasov 60b2430d75SMaxim Patlasov if (npages <= FUSE_REQ_INLINE_PAGES) { 614250c066SMaxim Patlasov pages = req->inline_pages; 62b2430d75SMaxim Patlasov page_descs = req->inline_page_descs; 63b2430d75SMaxim Patlasov } else { 644250c066SMaxim Patlasov pages = kmalloc(sizeof(struct page *) * npages, flags); 65b2430d75SMaxim Patlasov page_descs = kmalloc(sizeof(struct fuse_page_desc) * 66b2430d75SMaxim Patlasov npages, flags); 67b2430d75SMaxim Patlasov } 684250c066SMaxim Patlasov 69b2430d75SMaxim Patlasov if (!pages || !page_descs) { 70b2430d75SMaxim Patlasov kfree(pages); 71b2430d75SMaxim Patlasov kfree(page_descs); 724250c066SMaxim Patlasov kmem_cache_free(fuse_req_cachep, req); 734250c066SMaxim Patlasov return NULL; 744250c066SMaxim Patlasov } 754250c066SMaxim Patlasov 76b2430d75SMaxim Patlasov fuse_request_init(req, pages, page_descs, npages); 774250c066SMaxim Patlasov } 78334f485dSMiklos Szeredi return req; 79334f485dSMiklos Szeredi } 804250c066SMaxim Patlasov 814250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc(unsigned npages) 824250c066SMaxim Patlasov { 834250c066SMaxim Patlasov return __fuse_request_alloc(npages, GFP_KERNEL); 844250c066SMaxim Patlasov } 8508cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_alloc); 86334f485dSMiklos Szeredi 874250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc_nofs(unsigned npages) 883be5a52bSMiklos Szeredi { 894250c066SMaxim Patlasov return __fuse_request_alloc(npages, GFP_NOFS); 903be5a52bSMiklos Szeredi } 913be5a52bSMiklos Szeredi 92334f485dSMiklos Szeredi void fuse_request_free(struct fuse_req *req) 93334f485dSMiklos Szeredi { 94b2430d75SMaxim Patlasov if (req->pages != req->inline_pages) { 954250c066SMaxim Patlasov kfree(req->pages); 96b2430d75SMaxim Patlasov kfree(req->page_descs); 97b2430d75SMaxim Patlasov } 98334f485dSMiklos Szeredi kmem_cache_free(fuse_req_cachep, req); 99334f485dSMiklos Szeredi } 100334f485dSMiklos Szeredi 1018bfc016dSMiklos Szeredi static void block_sigs(sigset_t *oldset) 102334f485dSMiklos Szeredi { 103334f485dSMiklos Szeredi sigset_t mask; 104334f485dSMiklos Szeredi 105334f485dSMiklos Szeredi siginitsetinv(&mask, sigmask(SIGKILL)); 106334f485dSMiklos Szeredi sigprocmask(SIG_BLOCK, &mask, oldset); 107334f485dSMiklos Szeredi } 108334f485dSMiklos Szeredi 1098bfc016dSMiklos Szeredi static void restore_sigs(sigset_t *oldset) 110334f485dSMiklos Szeredi { 111334f485dSMiklos Szeredi sigprocmask(SIG_SETMASK, oldset, NULL); 112334f485dSMiklos Szeredi } 113334f485dSMiklos Szeredi 114334f485dSMiklos Szeredi static void __fuse_get_request(struct fuse_req *req) 115334f485dSMiklos Szeredi { 116334f485dSMiklos Szeredi atomic_inc(&req->count); 117334f485dSMiklos Szeredi } 118334f485dSMiklos Szeredi 119334f485dSMiklos Szeredi /* Must be called with > 1 refcount */ 120334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req) 121334f485dSMiklos Szeredi { 122334f485dSMiklos Szeredi BUG_ON(atomic_read(&req->count) < 2); 123334f485dSMiklos Szeredi atomic_dec(&req->count); 124334f485dSMiklos Szeredi } 125334f485dSMiklos Szeredi 12633649c91SMiklos Szeredi static void fuse_req_init_context(struct fuse_req *req) 12733649c91SMiklos Szeredi { 128499dcf20SEric W. Biederman req->in.h.uid = from_kuid_munged(&init_user_ns, current_fsuid()); 129499dcf20SEric W. Biederman req->in.h.gid = from_kgid_munged(&init_user_ns, current_fsgid()); 13033649c91SMiklos Szeredi req->in.h.pid = current->pid; 13133649c91SMiklos Szeredi } 13233649c91SMiklos Szeredi 133b111c8c0SMaxim Patlasov struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages) 134334f485dSMiklos Szeredi { 13508a53cdcSMiklos Szeredi struct fuse_req *req; 13608a53cdcSMiklos Szeredi sigset_t oldset; 1379bc5dddaSMiklos Szeredi int intr; 13808a53cdcSMiklos Szeredi int err; 13908a53cdcSMiklos Szeredi 1409bc5dddaSMiklos Szeredi atomic_inc(&fc->num_waiting); 14108a53cdcSMiklos Szeredi block_sigs(&oldset); 1429bc5dddaSMiklos Szeredi intr = wait_event_interruptible(fc->blocked_waitq, !fc->blocked); 14308a53cdcSMiklos Szeredi restore_sigs(&oldset); 1449bc5dddaSMiklos Szeredi err = -EINTR; 1459bc5dddaSMiklos Szeredi if (intr) 1469bc5dddaSMiklos Szeredi goto out; 14708a53cdcSMiklos Szeredi 14851eb01e7SMiklos Szeredi err = -ENOTCONN; 14951eb01e7SMiklos Szeredi if (!fc->connected) 15051eb01e7SMiklos Szeredi goto out; 15151eb01e7SMiklos Szeredi 152b111c8c0SMaxim Patlasov req = fuse_request_alloc(npages); 1539bc5dddaSMiklos Szeredi err = -ENOMEM; 154ce1d5a49SMiklos Szeredi if (!req) 1559bc5dddaSMiklos Szeredi goto out; 156334f485dSMiklos Szeredi 15733649c91SMiklos Szeredi fuse_req_init_context(req); 1589bc5dddaSMiklos Szeredi req->waiting = 1; 159334f485dSMiklos Szeredi return req; 1609bc5dddaSMiklos Szeredi 1619bc5dddaSMiklos Szeredi out: 1629bc5dddaSMiklos Szeredi atomic_dec(&fc->num_waiting); 1639bc5dddaSMiklos Szeredi return ERR_PTR(err); 164334f485dSMiklos Szeredi } 16508cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_get_req); 166334f485dSMiklos Szeredi 16733649c91SMiklos Szeredi /* 16833649c91SMiklos Szeredi * Return request in fuse_file->reserved_req. However that may 16933649c91SMiklos Szeredi * currently be in use. If that is the case, wait for it to become 17033649c91SMiklos Szeredi * available. 17133649c91SMiklos Szeredi */ 17233649c91SMiklos Szeredi static struct fuse_req *get_reserved_req(struct fuse_conn *fc, 17333649c91SMiklos Szeredi struct file *file) 17433649c91SMiklos Szeredi { 17533649c91SMiklos Szeredi struct fuse_req *req = NULL; 17633649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 17733649c91SMiklos Szeredi 17833649c91SMiklos Szeredi do { 179de5e3decSMiklos Szeredi wait_event(fc->reserved_req_waitq, ff->reserved_req); 18033649c91SMiklos Szeredi spin_lock(&fc->lock); 18133649c91SMiklos Szeredi if (ff->reserved_req) { 18233649c91SMiklos Szeredi req = ff->reserved_req; 18333649c91SMiklos Szeredi ff->reserved_req = NULL; 184cb0942b8SAl Viro req->stolen_file = get_file(file); 18533649c91SMiklos Szeredi } 18633649c91SMiklos Szeredi spin_unlock(&fc->lock); 18733649c91SMiklos Szeredi } while (!req); 18833649c91SMiklos Szeredi 18933649c91SMiklos Szeredi return req; 19033649c91SMiklos Szeredi } 19133649c91SMiklos Szeredi 19233649c91SMiklos Szeredi /* 19333649c91SMiklos Szeredi * Put stolen request back into fuse_file->reserved_req 19433649c91SMiklos Szeredi */ 19533649c91SMiklos Szeredi static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req) 19633649c91SMiklos Szeredi { 19733649c91SMiklos Szeredi struct file *file = req->stolen_file; 19833649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 19933649c91SMiklos Szeredi 20033649c91SMiklos Szeredi spin_lock(&fc->lock); 201b2430d75SMaxim Patlasov fuse_request_init(req, req->pages, req->page_descs, req->max_pages); 20233649c91SMiklos Szeredi BUG_ON(ff->reserved_req); 20333649c91SMiklos Szeredi ff->reserved_req = req; 204de5e3decSMiklos Szeredi wake_up_all(&fc->reserved_req_waitq); 20533649c91SMiklos Szeredi spin_unlock(&fc->lock); 20633649c91SMiklos Szeredi fput(file); 20733649c91SMiklos Szeredi } 20833649c91SMiklos Szeredi 20933649c91SMiklos Szeredi /* 21033649c91SMiklos Szeredi * Gets a requests for a file operation, always succeeds 21133649c91SMiklos Szeredi * 21233649c91SMiklos Szeredi * This is used for sending the FLUSH request, which must get to 21333649c91SMiklos Szeredi * userspace, due to POSIX locks which may need to be unlocked. 21433649c91SMiklos Szeredi * 21533649c91SMiklos Szeredi * If allocation fails due to OOM, use the reserved request in 21633649c91SMiklos Szeredi * fuse_file. 21733649c91SMiklos Szeredi * 21833649c91SMiklos Szeredi * This is very unlikely to deadlock accidentally, since the 21933649c91SMiklos Szeredi * filesystem should not have it's own file open. If deadlock is 22033649c91SMiklos Szeredi * intentional, it can still be broken by "aborting" the filesystem. 22133649c91SMiklos Szeredi */ 222b111c8c0SMaxim Patlasov struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, 223b111c8c0SMaxim Patlasov struct file *file) 22433649c91SMiklos Szeredi { 22533649c91SMiklos Szeredi struct fuse_req *req; 22633649c91SMiklos Szeredi 22733649c91SMiklos Szeredi atomic_inc(&fc->num_waiting); 22833649c91SMiklos Szeredi wait_event(fc->blocked_waitq, !fc->blocked); 229b111c8c0SMaxim Patlasov req = fuse_request_alloc(0); 23033649c91SMiklos Szeredi if (!req) 23133649c91SMiklos Szeredi req = get_reserved_req(fc, file); 23233649c91SMiklos Szeredi 23333649c91SMiklos Szeredi fuse_req_init_context(req); 23433649c91SMiklos Szeredi req->waiting = 1; 23533649c91SMiklos Szeredi return req; 23633649c91SMiklos Szeredi } 23733649c91SMiklos Szeredi 238334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) 239334f485dSMiklos Szeredi { 2407128ec2aSMiklos Szeredi if (atomic_dec_and_test(&req->count)) { 2419bc5dddaSMiklos Szeredi if (req->waiting) 242ce1d5a49SMiklos Szeredi atomic_dec(&fc->num_waiting); 24333649c91SMiklos Szeredi 24433649c91SMiklos Szeredi if (req->stolen_file) 24533649c91SMiklos Szeredi put_reserved_req(fc, req); 24633649c91SMiklos Szeredi else 247ce1d5a49SMiklos Szeredi fuse_request_free(req); 2487128ec2aSMiklos Szeredi } 2497128ec2aSMiklos Szeredi } 25008cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_put_request); 2517128ec2aSMiklos Szeredi 252d12def1bSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args) 253d12def1bSMiklos Szeredi { 254d12def1bSMiklos Szeredi unsigned nbytes = 0; 255d12def1bSMiklos Szeredi unsigned i; 256d12def1bSMiklos Szeredi 257d12def1bSMiklos Szeredi for (i = 0; i < numargs; i++) 258d12def1bSMiklos Szeredi nbytes += args[i].size; 259d12def1bSMiklos Szeredi 260d12def1bSMiklos Szeredi return nbytes; 261d12def1bSMiklos Szeredi } 262d12def1bSMiklos Szeredi 263d12def1bSMiklos Szeredi static u64 fuse_get_unique(struct fuse_conn *fc) 264d12def1bSMiklos Szeredi { 265d12def1bSMiklos Szeredi fc->reqctr++; 266d12def1bSMiklos Szeredi /* zero is special */ 267d12def1bSMiklos Szeredi if (fc->reqctr == 0) 268d12def1bSMiklos Szeredi fc->reqctr = 1; 269d12def1bSMiklos Szeredi 270d12def1bSMiklos Szeredi return fc->reqctr; 271d12def1bSMiklos Szeredi } 272d12def1bSMiklos Szeredi 273d12def1bSMiklos Szeredi static void queue_request(struct fuse_conn *fc, struct fuse_req *req) 274d12def1bSMiklos Szeredi { 275d12def1bSMiklos Szeredi req->in.h.len = sizeof(struct fuse_in_header) + 276d12def1bSMiklos Szeredi len_args(req->in.numargs, (struct fuse_arg *) req->in.args); 277d12def1bSMiklos Szeredi list_add_tail(&req->list, &fc->pending); 278d12def1bSMiklos Szeredi req->state = FUSE_REQ_PENDING; 279d12def1bSMiklos Szeredi if (!req->waiting) { 280d12def1bSMiklos Szeredi req->waiting = 1; 281d12def1bSMiklos Szeredi atomic_inc(&fc->num_waiting); 282d12def1bSMiklos Szeredi } 283d12def1bSMiklos Szeredi wake_up(&fc->waitq); 284d12def1bSMiklos Szeredi kill_fasync(&fc->fasync, SIGIO, POLL_IN); 285d12def1bSMiklos Szeredi } 286d12def1bSMiklos Szeredi 28707e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, 28807e77dcaSMiklos Szeredi u64 nodeid, u64 nlookup) 28907e77dcaSMiklos Szeredi { 29002c048b9SMiklos Szeredi forget->forget_one.nodeid = nodeid; 29102c048b9SMiklos Szeredi forget->forget_one.nlookup = nlookup; 29207e77dcaSMiklos Szeredi 29307e77dcaSMiklos Szeredi spin_lock(&fc->lock); 2945dfcc87fSMiklos Szeredi if (fc->connected) { 29507e77dcaSMiklos Szeredi fc->forget_list_tail->next = forget; 29607e77dcaSMiklos Szeredi fc->forget_list_tail = forget; 29707e77dcaSMiklos Szeredi wake_up(&fc->waitq); 29807e77dcaSMiklos Szeredi kill_fasync(&fc->fasync, SIGIO, POLL_IN); 2995dfcc87fSMiklos Szeredi } else { 3005dfcc87fSMiklos Szeredi kfree(forget); 3015dfcc87fSMiklos Szeredi } 30207e77dcaSMiklos Szeredi spin_unlock(&fc->lock); 30307e77dcaSMiklos Szeredi } 30407e77dcaSMiklos Szeredi 305d12def1bSMiklos Szeredi static void flush_bg_queue(struct fuse_conn *fc) 306d12def1bSMiklos Szeredi { 3077a6d3c8bSCsaba Henk while (fc->active_background < fc->max_background && 308d12def1bSMiklos Szeredi !list_empty(&fc->bg_queue)) { 309d12def1bSMiklos Szeredi struct fuse_req *req; 310d12def1bSMiklos Szeredi 311d12def1bSMiklos Szeredi req = list_entry(fc->bg_queue.next, struct fuse_req, list); 312d12def1bSMiklos Szeredi list_del(&req->list); 313d12def1bSMiklos Szeredi fc->active_background++; 3142d45ba38SMiklos Szeredi req->in.h.unique = fuse_get_unique(fc); 315d12def1bSMiklos Szeredi queue_request(fc, req); 316d12def1bSMiklos Szeredi } 317d12def1bSMiklos Szeredi } 318d12def1bSMiklos Szeredi 3196dbbcb12SMiklos Szeredi /* 320334f485dSMiklos Szeredi * This function is called when a request is finished. Either a reply 321f9a2842eSMiklos Szeredi * has arrived or it was aborted (and not yet sent) or some error 322f43b155aSMiklos Szeredi * occurred during communication with userspace, or the device file 32351eb01e7SMiklos Szeredi * was closed. The requester thread is woken up (if still waiting), 32451eb01e7SMiklos Szeredi * the 'end' callback is called if given, else the reference to the 32551eb01e7SMiklos Szeredi * request is released 3267128ec2aSMiklos Szeredi * 327d7133114SMiklos Szeredi * Called with fc->lock, unlocks it 328334f485dSMiklos Szeredi */ 329334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req) 330b9ca67b2SMiklos Szeredi __releases(fc->lock) 331334f485dSMiklos Szeredi { 3327128ec2aSMiklos Szeredi void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; 3337128ec2aSMiklos Szeredi req->end = NULL; 33451eb01e7SMiklos Szeredi list_del(&req->list); 335a4d27e75SMiklos Szeredi list_del(&req->intr_entry); 33651eb01e7SMiklos Szeredi req->state = FUSE_REQ_FINISHED; 33751eb01e7SMiklos Szeredi if (req->background) { 3387a6d3c8bSCsaba Henk if (fc->num_background == fc->max_background) { 33951eb01e7SMiklos Szeredi fc->blocked = 0; 34051eb01e7SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 34151eb01e7SMiklos Szeredi } 3427a6d3c8bSCsaba Henk if (fc->num_background == fc->congestion_threshold && 343a325f9b9STejun Heo fc->connected && fc->bdi_initialized) { 3448aa7e847SJens Axboe clear_bdi_congested(&fc->bdi, BLK_RW_SYNC); 3458aa7e847SJens Axboe clear_bdi_congested(&fc->bdi, BLK_RW_ASYNC); 346f92b99b9SMiklos Szeredi } 34751eb01e7SMiklos Szeredi fc->num_background--; 348d12def1bSMiklos Szeredi fc->active_background--; 349d12def1bSMiklos Szeredi flush_bg_queue(fc); 35051eb01e7SMiklos Szeredi } 351d7133114SMiklos Szeredi spin_unlock(&fc->lock); 35251eb01e7SMiklos Szeredi wake_up(&req->waitq); 35364c6d8edSMiklos Szeredi if (end) 35464c6d8edSMiklos Szeredi end(fc, req); 355f43b155aSMiklos Szeredi fuse_put_request(fc, req); 356334f485dSMiklos Szeredi } 357334f485dSMiklos Szeredi 358a4d27e75SMiklos Szeredi static void wait_answer_interruptible(struct fuse_conn *fc, 359a4d27e75SMiklos Szeredi struct fuse_req *req) 360b9ca67b2SMiklos Szeredi __releases(fc->lock) 361b9ca67b2SMiklos Szeredi __acquires(fc->lock) 362a4d27e75SMiklos Szeredi { 363a4d27e75SMiklos Szeredi if (signal_pending(current)) 364a4d27e75SMiklos Szeredi return; 365a4d27e75SMiklos Szeredi 366a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 367a4d27e75SMiklos Szeredi wait_event_interruptible(req->waitq, req->state == FUSE_REQ_FINISHED); 368a4d27e75SMiklos Szeredi spin_lock(&fc->lock); 369a4d27e75SMiklos Szeredi } 370a4d27e75SMiklos Szeredi 371a4d27e75SMiklos Szeredi static void queue_interrupt(struct fuse_conn *fc, struct fuse_req *req) 372a4d27e75SMiklos Szeredi { 373a4d27e75SMiklos Szeredi list_add_tail(&req->intr_entry, &fc->interrupts); 374a4d27e75SMiklos Szeredi wake_up(&fc->waitq); 375a4d27e75SMiklos Szeredi kill_fasync(&fc->fasync, SIGIO, POLL_IN); 376a4d27e75SMiklos Szeredi } 377a4d27e75SMiklos Szeredi 3787c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) 379b9ca67b2SMiklos Szeredi __releases(fc->lock) 380b9ca67b2SMiklos Szeredi __acquires(fc->lock) 381334f485dSMiklos Szeredi { 382a4d27e75SMiklos Szeredi if (!fc->no_interrupt) { 383a4d27e75SMiklos Szeredi /* Any signal may interrupt this */ 384a4d27e75SMiklos Szeredi wait_answer_interruptible(fc, req); 385334f485dSMiklos Szeredi 386a4d27e75SMiklos Szeredi if (req->aborted) 387a4d27e75SMiklos Szeredi goto aborted; 388a4d27e75SMiklos Szeredi if (req->state == FUSE_REQ_FINISHED) 389334f485dSMiklos Szeredi return; 390334f485dSMiklos Szeredi 391a4d27e75SMiklos Szeredi req->interrupted = 1; 392a4d27e75SMiklos Szeredi if (req->state == FUSE_REQ_SENT) 393a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 394a4d27e75SMiklos Szeredi } 395a4d27e75SMiklos Szeredi 396a131de0aSMiklos Szeredi if (!req->force) { 397a4d27e75SMiklos Szeredi sigset_t oldset; 398a4d27e75SMiklos Szeredi 399a4d27e75SMiklos Szeredi /* Only fatal signals may interrupt this */ 400a4d27e75SMiklos Szeredi block_sigs(&oldset); 401a4d27e75SMiklos Szeredi wait_answer_interruptible(fc, req); 402a4d27e75SMiklos Szeredi restore_sigs(&oldset); 403a4d27e75SMiklos Szeredi 404a4d27e75SMiklos Szeredi if (req->aborted) 405a4d27e75SMiklos Szeredi goto aborted; 406a4d27e75SMiklos Szeredi if (req->state == FUSE_REQ_FINISHED) 407a4d27e75SMiklos Szeredi return; 408a4d27e75SMiklos Szeredi 409a131de0aSMiklos Szeredi /* Request is not yet in userspace, bail out */ 410a131de0aSMiklos Szeredi if (req->state == FUSE_REQ_PENDING) { 411a131de0aSMiklos Szeredi list_del(&req->list); 412a131de0aSMiklos Szeredi __fuse_put_request(req); 413334f485dSMiklos Szeredi req->out.h.error = -EINTR; 414a131de0aSMiklos Szeredi return; 415a131de0aSMiklos Szeredi } 416a131de0aSMiklos Szeredi } 417a131de0aSMiklos Szeredi 418a131de0aSMiklos Szeredi /* 419a131de0aSMiklos Szeredi * Either request is already in userspace, or it was forced. 420a131de0aSMiklos Szeredi * Wait it out. 421a131de0aSMiklos Szeredi */ 422a131de0aSMiklos Szeredi spin_unlock(&fc->lock); 423a131de0aSMiklos Szeredi wait_event(req->waitq, req->state == FUSE_REQ_FINISHED); 424a131de0aSMiklos Szeredi spin_lock(&fc->lock); 425a131de0aSMiklos Szeredi 426a131de0aSMiklos Szeredi if (!req->aborted) 427a131de0aSMiklos Szeredi return; 428a4d27e75SMiklos Szeredi 429a4d27e75SMiklos Szeredi aborted: 430a131de0aSMiklos Szeredi BUG_ON(req->state != FUSE_REQ_FINISHED); 431334f485dSMiklos Szeredi if (req->locked) { 432334f485dSMiklos Szeredi /* This is uninterruptible sleep, because data is 433334f485dSMiklos Szeredi being copied to/from the buffers of req. During 434334f485dSMiklos Szeredi locked state, there mustn't be any filesystem 435334f485dSMiklos Szeredi operation (e.g. page fault), since that could lead 436334f485dSMiklos Szeredi to deadlock */ 437d7133114SMiklos Szeredi spin_unlock(&fc->lock); 438334f485dSMiklos Szeredi wait_event(req->waitq, !req->locked); 439d7133114SMiklos Szeredi spin_lock(&fc->lock); 440334f485dSMiklos Szeredi } 441334f485dSMiklos Szeredi } 442334f485dSMiklos Szeredi 443b93f858aSTejun Heo void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 444334f485dSMiklos Szeredi { 445334f485dSMiklos Szeredi req->isreply = 1; 446d7133114SMiklos Szeredi spin_lock(&fc->lock); 4471e9a4ed9SMiklos Szeredi if (!fc->connected) 448334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 449334f485dSMiklos Szeredi else if (fc->conn_error) 450334f485dSMiklos Szeredi req->out.h.error = -ECONNREFUSED; 451334f485dSMiklos Szeredi else { 4522d45ba38SMiklos Szeredi req->in.h.unique = fuse_get_unique(fc); 453334f485dSMiklos Szeredi queue_request(fc, req); 454334f485dSMiklos Szeredi /* acquire extra reference, since request is still needed 455334f485dSMiklos Szeredi after request_end() */ 456334f485dSMiklos Szeredi __fuse_get_request(req); 457334f485dSMiklos Szeredi 4587c352bdfSMiklos Szeredi request_wait_answer(fc, req); 459334f485dSMiklos Szeredi } 460d7133114SMiklos Szeredi spin_unlock(&fc->lock); 461334f485dSMiklos Szeredi } 46208cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send); 463334f485dSMiklos Szeredi 464b93f858aSTejun Heo static void fuse_request_send_nowait_locked(struct fuse_conn *fc, 465d12def1bSMiklos Szeredi struct fuse_req *req) 466334f485dSMiklos Szeredi { 46751eb01e7SMiklos Szeredi req->background = 1; 46851eb01e7SMiklos Szeredi fc->num_background++; 4697a6d3c8bSCsaba Henk if (fc->num_background == fc->max_background) 47051eb01e7SMiklos Szeredi fc->blocked = 1; 4717a6d3c8bSCsaba Henk if (fc->num_background == fc->congestion_threshold && 472a325f9b9STejun Heo fc->bdi_initialized) { 4738aa7e847SJens Axboe set_bdi_congested(&fc->bdi, BLK_RW_SYNC); 4748aa7e847SJens Axboe set_bdi_congested(&fc->bdi, BLK_RW_ASYNC); 475f92b99b9SMiklos Szeredi } 476d12def1bSMiklos Szeredi list_add_tail(&req->list, &fc->bg_queue); 477d12def1bSMiklos Szeredi flush_bg_queue(fc); 478d12def1bSMiklos Szeredi } 47951eb01e7SMiklos Szeredi 480b93f858aSTejun Heo static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) 481d12def1bSMiklos Szeredi { 482d12def1bSMiklos Szeredi spin_lock(&fc->lock); 483d12def1bSMiklos Szeredi if (fc->connected) { 484b93f858aSTejun Heo fuse_request_send_nowait_locked(fc, req); 485d7133114SMiklos Szeredi spin_unlock(&fc->lock); 486334f485dSMiklos Szeredi } else { 487334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 488334f485dSMiklos Szeredi request_end(fc, req); 489334f485dSMiklos Szeredi } 490334f485dSMiklos Szeredi } 491334f485dSMiklos Szeredi 492b93f858aSTejun Heo void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) 493334f485dSMiklos Szeredi { 494334f485dSMiklos Szeredi req->isreply = 1; 495b93f858aSTejun Heo fuse_request_send_nowait(fc, req); 496334f485dSMiklos Szeredi } 49708cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send_background); 498334f485dSMiklos Szeredi 4992d45ba38SMiklos Szeredi static int fuse_request_send_notify_reply(struct fuse_conn *fc, 5002d45ba38SMiklos Szeredi struct fuse_req *req, u64 unique) 5012d45ba38SMiklos Szeredi { 5022d45ba38SMiklos Szeredi int err = -ENODEV; 5032d45ba38SMiklos Szeredi 5042d45ba38SMiklos Szeredi req->isreply = 0; 5052d45ba38SMiklos Szeredi req->in.h.unique = unique; 5062d45ba38SMiklos Szeredi spin_lock(&fc->lock); 5072d45ba38SMiklos Szeredi if (fc->connected) { 5082d45ba38SMiklos Szeredi queue_request(fc, req); 5092d45ba38SMiklos Szeredi err = 0; 5102d45ba38SMiklos Szeredi } 5112d45ba38SMiklos Szeredi spin_unlock(&fc->lock); 5122d45ba38SMiklos Szeredi 5132d45ba38SMiklos Szeredi return err; 5142d45ba38SMiklos Szeredi } 5152d45ba38SMiklos Szeredi 516334f485dSMiklos Szeredi /* 5173be5a52bSMiklos Szeredi * Called under fc->lock 5183be5a52bSMiklos Szeredi * 5193be5a52bSMiklos Szeredi * fc->connected must have been checked previously 5203be5a52bSMiklos Szeredi */ 521b93f858aSTejun Heo void fuse_request_send_background_locked(struct fuse_conn *fc, 522b93f858aSTejun Heo struct fuse_req *req) 5233be5a52bSMiklos Szeredi { 5243be5a52bSMiklos Szeredi req->isreply = 1; 525b93f858aSTejun Heo fuse_request_send_nowait_locked(fc, req); 5263be5a52bSMiklos Szeredi } 5273be5a52bSMiklos Szeredi 5280b05b183SAnand V. Avati void fuse_force_forget(struct file *file, u64 nodeid) 5290b05b183SAnand V. Avati { 5300b05b183SAnand V. Avati struct inode *inode = file->f_path.dentry->d_inode; 5310b05b183SAnand V. Avati struct fuse_conn *fc = get_fuse_conn(inode); 5320b05b183SAnand V. Avati struct fuse_req *req; 5330b05b183SAnand V. Avati struct fuse_forget_in inarg; 5340b05b183SAnand V. Avati 5350b05b183SAnand V. Avati memset(&inarg, 0, sizeof(inarg)); 5360b05b183SAnand V. Avati inarg.nlookup = 1; 537b111c8c0SMaxim Patlasov req = fuse_get_req_nofail_nopages(fc, file); 5380b05b183SAnand V. Avati req->in.h.opcode = FUSE_FORGET; 5390b05b183SAnand V. Avati req->in.h.nodeid = nodeid; 5400b05b183SAnand V. Avati req->in.numargs = 1; 5410b05b183SAnand V. Avati req->in.args[0].size = sizeof(inarg); 5420b05b183SAnand V. Avati req->in.args[0].value = &inarg; 5430b05b183SAnand V. Avati req->isreply = 0; 5440b05b183SAnand V. Avati fuse_request_send_nowait(fc, req); 5450b05b183SAnand V. Avati } 5460b05b183SAnand V. Avati 5473be5a52bSMiklos Szeredi /* 548334f485dSMiklos Szeredi * Lock the request. Up to the next unlock_request() there mustn't be 549334f485dSMiklos Szeredi * anything that could cause a page-fault. If the request was already 550f9a2842eSMiklos Szeredi * aborted bail out. 551334f485dSMiklos Szeredi */ 552d7133114SMiklos Szeredi static int lock_request(struct fuse_conn *fc, struct fuse_req *req) 553334f485dSMiklos Szeredi { 554334f485dSMiklos Szeredi int err = 0; 555334f485dSMiklos Szeredi if (req) { 556d7133114SMiklos Szeredi spin_lock(&fc->lock); 557f9a2842eSMiklos Szeredi if (req->aborted) 558334f485dSMiklos Szeredi err = -ENOENT; 559334f485dSMiklos Szeredi else 560334f485dSMiklos Szeredi req->locked = 1; 561d7133114SMiklos Szeredi spin_unlock(&fc->lock); 562334f485dSMiklos Szeredi } 563334f485dSMiklos Szeredi return err; 564334f485dSMiklos Szeredi } 565334f485dSMiklos Szeredi 566334f485dSMiklos Szeredi /* 567f9a2842eSMiklos Szeredi * Unlock request. If it was aborted during being locked, the 568334f485dSMiklos Szeredi * requester thread is currently waiting for it to be unlocked, so 569334f485dSMiklos Szeredi * wake it up. 570334f485dSMiklos Szeredi */ 571d7133114SMiklos Szeredi static void unlock_request(struct fuse_conn *fc, struct fuse_req *req) 572334f485dSMiklos Szeredi { 573334f485dSMiklos Szeredi if (req) { 574d7133114SMiklos Szeredi spin_lock(&fc->lock); 575334f485dSMiklos Szeredi req->locked = 0; 576f9a2842eSMiklos Szeredi if (req->aborted) 577334f485dSMiklos Szeredi wake_up(&req->waitq); 578d7133114SMiklos Szeredi spin_unlock(&fc->lock); 579334f485dSMiklos Szeredi } 580334f485dSMiklos Szeredi } 581334f485dSMiklos Szeredi 582334f485dSMiklos Szeredi struct fuse_copy_state { 583d7133114SMiklos Szeredi struct fuse_conn *fc; 584334f485dSMiklos Szeredi int write; 585334f485dSMiklos Szeredi struct fuse_req *req; 586334f485dSMiklos Szeredi const struct iovec *iov; 587dd3bb14fSMiklos Szeredi struct pipe_buffer *pipebufs; 588dd3bb14fSMiklos Szeredi struct pipe_buffer *currbuf; 589dd3bb14fSMiklos Szeredi struct pipe_inode_info *pipe; 590334f485dSMiklos Szeredi unsigned long nr_segs; 591334f485dSMiklos Szeredi unsigned long seglen; 592334f485dSMiklos Szeredi unsigned long addr; 593334f485dSMiklos Szeredi struct page *pg; 594334f485dSMiklos Szeredi void *mapaddr; 595334f485dSMiklos Szeredi void *buf; 596334f485dSMiklos Szeredi unsigned len; 597ce534fb0SMiklos Szeredi unsigned move_pages:1; 598334f485dSMiklos Szeredi }; 599334f485dSMiklos Szeredi 600d7133114SMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc, 601c3021629SMiklos Szeredi int write, 602d7133114SMiklos Szeredi const struct iovec *iov, unsigned long nr_segs) 603334f485dSMiklos Szeredi { 604334f485dSMiklos Szeredi memset(cs, 0, sizeof(*cs)); 605d7133114SMiklos Szeredi cs->fc = fc; 606334f485dSMiklos Szeredi cs->write = write; 607334f485dSMiklos Szeredi cs->iov = iov; 608334f485dSMiklos Szeredi cs->nr_segs = nr_segs; 609334f485dSMiklos Szeredi } 610334f485dSMiklos Szeredi 611334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */ 6128bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs) 613334f485dSMiklos Szeredi { 614dd3bb14fSMiklos Szeredi if (cs->currbuf) { 615dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->currbuf; 616dd3bb14fSMiklos Szeredi 617c3021629SMiklos Szeredi if (!cs->write) { 618dd3bb14fSMiklos Szeredi buf->ops->unmap(cs->pipe, buf, cs->mapaddr); 619c3021629SMiklos Szeredi } else { 6207909b1c6SMiklos Szeredi kunmap(buf->page); 621c3021629SMiklos Szeredi buf->len = PAGE_SIZE - cs->len; 622c3021629SMiklos Szeredi } 623dd3bb14fSMiklos Szeredi cs->currbuf = NULL; 624dd3bb14fSMiklos Szeredi cs->mapaddr = NULL; 625dd3bb14fSMiklos Szeredi } else if (cs->mapaddr) { 6267909b1c6SMiklos Szeredi kunmap(cs->pg); 627334f485dSMiklos Szeredi if (cs->write) { 628334f485dSMiklos Szeredi flush_dcache_page(cs->pg); 629334f485dSMiklos Szeredi set_page_dirty_lock(cs->pg); 630334f485dSMiklos Szeredi } 631334f485dSMiklos Szeredi put_page(cs->pg); 632334f485dSMiklos Szeredi cs->mapaddr = NULL; 633334f485dSMiklos Szeredi } 634334f485dSMiklos Szeredi } 635334f485dSMiklos Szeredi 636334f485dSMiklos Szeredi /* 637334f485dSMiklos Szeredi * Get another pagefull of userspace buffer, and map it to kernel 638334f485dSMiklos Szeredi * address space, and lock request 639334f485dSMiklos Szeredi */ 640334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs) 641334f485dSMiklos Szeredi { 642334f485dSMiklos Szeredi unsigned long offset; 643334f485dSMiklos Szeredi int err; 644334f485dSMiklos Szeredi 645d7133114SMiklos Szeredi unlock_request(cs->fc, cs->req); 646334f485dSMiklos Szeredi fuse_copy_finish(cs); 647dd3bb14fSMiklos Szeredi if (cs->pipebufs) { 648dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 649dd3bb14fSMiklos Szeredi 650c3021629SMiklos Szeredi if (!cs->write) { 651dd3bb14fSMiklos Szeredi err = buf->ops->confirm(cs->pipe, buf); 652dd3bb14fSMiklos Szeredi if (err) 653dd3bb14fSMiklos Szeredi return err; 654dd3bb14fSMiklos Szeredi 655dd3bb14fSMiklos Szeredi BUG_ON(!cs->nr_segs); 656dd3bb14fSMiklos Szeredi cs->currbuf = buf; 6577909b1c6SMiklos Szeredi cs->mapaddr = buf->ops->map(cs->pipe, buf, 0); 658dd3bb14fSMiklos Szeredi cs->len = buf->len; 659dd3bb14fSMiklos Szeredi cs->buf = cs->mapaddr + buf->offset; 660dd3bb14fSMiklos Szeredi cs->pipebufs++; 661dd3bb14fSMiklos Szeredi cs->nr_segs--; 662dd3bb14fSMiklos Szeredi } else { 663c3021629SMiklos Szeredi struct page *page; 664c3021629SMiklos Szeredi 665c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 666c3021629SMiklos Szeredi return -EIO; 667c3021629SMiklos Szeredi 668c3021629SMiklos Szeredi page = alloc_page(GFP_HIGHUSER); 669c3021629SMiklos Szeredi if (!page) 670c3021629SMiklos Szeredi return -ENOMEM; 671c3021629SMiklos Szeredi 672c3021629SMiklos Szeredi buf->page = page; 673c3021629SMiklos Szeredi buf->offset = 0; 674c3021629SMiklos Szeredi buf->len = 0; 675c3021629SMiklos Szeredi 676c3021629SMiklos Szeredi cs->currbuf = buf; 6777909b1c6SMiklos Szeredi cs->mapaddr = kmap(page); 678c3021629SMiklos Szeredi cs->buf = cs->mapaddr; 679c3021629SMiklos Szeredi cs->len = PAGE_SIZE; 680c3021629SMiklos Szeredi cs->pipebufs++; 681c3021629SMiklos Szeredi cs->nr_segs++; 682c3021629SMiklos Szeredi } 683c3021629SMiklos Szeredi } else { 684334f485dSMiklos Szeredi if (!cs->seglen) { 685334f485dSMiklos Szeredi BUG_ON(!cs->nr_segs); 686334f485dSMiklos Szeredi cs->seglen = cs->iov[0].iov_len; 687334f485dSMiklos Szeredi cs->addr = (unsigned long) cs->iov[0].iov_base; 688334f485dSMiklos Szeredi cs->iov++; 689334f485dSMiklos Szeredi cs->nr_segs--; 690334f485dSMiklos Szeredi } 6911bf94ca7SMiklos Szeredi err = get_user_pages_fast(cs->addr, 1, cs->write, &cs->pg); 692334f485dSMiklos Szeredi if (err < 0) 693334f485dSMiklos Szeredi return err; 694334f485dSMiklos Szeredi BUG_ON(err != 1); 695334f485dSMiklos Szeredi offset = cs->addr % PAGE_SIZE; 6967909b1c6SMiklos Szeredi cs->mapaddr = kmap(cs->pg); 697334f485dSMiklos Szeredi cs->buf = cs->mapaddr + offset; 698334f485dSMiklos Szeredi cs->len = min(PAGE_SIZE - offset, cs->seglen); 699334f485dSMiklos Szeredi cs->seglen -= cs->len; 700334f485dSMiklos Szeredi cs->addr += cs->len; 701dd3bb14fSMiklos Szeredi } 702334f485dSMiklos Szeredi 703d7133114SMiklos Szeredi return lock_request(cs->fc, cs->req); 704334f485dSMiklos Szeredi } 705334f485dSMiklos Szeredi 706334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */ 7078bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size) 708334f485dSMiklos Szeredi { 709334f485dSMiklos Szeredi unsigned ncpy = min(*size, cs->len); 710334f485dSMiklos Szeredi if (val) { 711334f485dSMiklos Szeredi if (cs->write) 712334f485dSMiklos Szeredi memcpy(cs->buf, *val, ncpy); 713334f485dSMiklos Szeredi else 714334f485dSMiklos Szeredi memcpy(*val, cs->buf, ncpy); 715334f485dSMiklos Szeredi *val += ncpy; 716334f485dSMiklos Szeredi } 717334f485dSMiklos Szeredi *size -= ncpy; 718334f485dSMiklos Szeredi cs->len -= ncpy; 719334f485dSMiklos Szeredi cs->buf += ncpy; 720334f485dSMiklos Szeredi return ncpy; 721334f485dSMiklos Szeredi } 722334f485dSMiklos Szeredi 723ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page) 724ce534fb0SMiklos Szeredi { 725ce534fb0SMiklos Szeredi if (page_mapcount(page) || 726ce534fb0SMiklos Szeredi page->mapping != NULL || 727ce534fb0SMiklos Szeredi page_count(page) != 1 || 728ce534fb0SMiklos Szeredi (page->flags & PAGE_FLAGS_CHECK_AT_PREP & 729ce534fb0SMiklos Szeredi ~(1 << PG_locked | 730ce534fb0SMiklos Szeredi 1 << PG_referenced | 731ce534fb0SMiklos Szeredi 1 << PG_uptodate | 732ce534fb0SMiklos Szeredi 1 << PG_lru | 733ce534fb0SMiklos Szeredi 1 << PG_active | 734ce534fb0SMiklos Szeredi 1 << PG_reclaim))) { 735ce534fb0SMiklos Szeredi printk(KERN_WARNING "fuse: trying to steal weird page\n"); 736ce534fb0SMiklos 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); 737ce534fb0SMiklos Szeredi return 1; 738ce534fb0SMiklos Szeredi } 739ce534fb0SMiklos Szeredi return 0; 740ce534fb0SMiklos Szeredi } 741ce534fb0SMiklos Szeredi 742ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) 743ce534fb0SMiklos Szeredi { 744ce534fb0SMiklos Szeredi int err; 745ce534fb0SMiklos Szeredi struct page *oldpage = *pagep; 746ce534fb0SMiklos Szeredi struct page *newpage; 747ce534fb0SMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 748ce534fb0SMiklos Szeredi 749ce534fb0SMiklos Szeredi unlock_request(cs->fc, cs->req); 750ce534fb0SMiklos Szeredi fuse_copy_finish(cs); 751ce534fb0SMiklos Szeredi 752ce534fb0SMiklos Szeredi err = buf->ops->confirm(cs->pipe, buf); 753ce534fb0SMiklos Szeredi if (err) 754ce534fb0SMiklos Szeredi return err; 755ce534fb0SMiklos Szeredi 756ce534fb0SMiklos Szeredi BUG_ON(!cs->nr_segs); 757ce534fb0SMiklos Szeredi cs->currbuf = buf; 758ce534fb0SMiklos Szeredi cs->len = buf->len; 759ce534fb0SMiklos Szeredi cs->pipebufs++; 760ce534fb0SMiklos Szeredi cs->nr_segs--; 761ce534fb0SMiklos Szeredi 762ce534fb0SMiklos Szeredi if (cs->len != PAGE_SIZE) 763ce534fb0SMiklos Szeredi goto out_fallback; 764ce534fb0SMiklos Szeredi 765ce534fb0SMiklos Szeredi if (buf->ops->steal(cs->pipe, buf) != 0) 766ce534fb0SMiklos Szeredi goto out_fallback; 767ce534fb0SMiklos Szeredi 768ce534fb0SMiklos Szeredi newpage = buf->page; 769ce534fb0SMiklos Szeredi 770ce534fb0SMiklos Szeredi if (WARN_ON(!PageUptodate(newpage))) 771ce534fb0SMiklos Szeredi return -EIO; 772ce534fb0SMiklos Szeredi 773ce534fb0SMiklos Szeredi ClearPageMappedToDisk(newpage); 774ce534fb0SMiklos Szeredi 775ce534fb0SMiklos Szeredi if (fuse_check_page(newpage) != 0) 776ce534fb0SMiklos Szeredi goto out_fallback_unlock; 777ce534fb0SMiklos Szeredi 778ce534fb0SMiklos Szeredi /* 779ce534fb0SMiklos Szeredi * This is a new and locked page, it shouldn't be mapped or 780ce534fb0SMiklos Szeredi * have any special flags on it 781ce534fb0SMiklos Szeredi */ 782ce534fb0SMiklos Szeredi if (WARN_ON(page_mapped(oldpage))) 783ce534fb0SMiklos Szeredi goto out_fallback_unlock; 784ce534fb0SMiklos Szeredi if (WARN_ON(page_has_private(oldpage))) 785ce534fb0SMiklos Szeredi goto out_fallback_unlock; 786ce534fb0SMiklos Szeredi if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage))) 787ce534fb0SMiklos Szeredi goto out_fallback_unlock; 788ce534fb0SMiklos Szeredi if (WARN_ON(PageMlocked(oldpage))) 789ce534fb0SMiklos Szeredi goto out_fallback_unlock; 790ce534fb0SMiklos Szeredi 791ef6a3c63SMiklos Szeredi err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); 792ce534fb0SMiklos Szeredi if (err) { 793ef6a3c63SMiklos Szeredi unlock_page(newpage); 794ef6a3c63SMiklos Szeredi return err; 795ce534fb0SMiklos Szeredi } 796ef6a3c63SMiklos Szeredi 797ce534fb0SMiklos Szeredi page_cache_get(newpage); 798ce534fb0SMiklos Szeredi 799ce534fb0SMiklos Szeredi if (!(buf->flags & PIPE_BUF_FLAG_LRU)) 800ce534fb0SMiklos Szeredi lru_cache_add_file(newpage); 801ce534fb0SMiklos Szeredi 802ce534fb0SMiklos Szeredi err = 0; 803ce534fb0SMiklos Szeredi spin_lock(&cs->fc->lock); 804ce534fb0SMiklos Szeredi if (cs->req->aborted) 805ce534fb0SMiklos Szeredi err = -ENOENT; 806ce534fb0SMiklos Szeredi else 807ce534fb0SMiklos Szeredi *pagep = newpage; 808ce534fb0SMiklos Szeredi spin_unlock(&cs->fc->lock); 809ce534fb0SMiklos Szeredi 810ce534fb0SMiklos Szeredi if (err) { 811ce534fb0SMiklos Szeredi unlock_page(newpage); 812ce534fb0SMiklos Szeredi page_cache_release(newpage); 813ce534fb0SMiklos Szeredi return err; 814ce534fb0SMiklos Szeredi } 815ce534fb0SMiklos Szeredi 816ce534fb0SMiklos Szeredi unlock_page(oldpage); 817ce534fb0SMiklos Szeredi page_cache_release(oldpage); 818ce534fb0SMiklos Szeredi cs->len = 0; 819ce534fb0SMiklos Szeredi 820ce534fb0SMiklos Szeredi return 0; 821ce534fb0SMiklos Szeredi 822ce534fb0SMiklos Szeredi out_fallback_unlock: 823ce534fb0SMiklos Szeredi unlock_page(newpage); 824ce534fb0SMiklos Szeredi out_fallback: 825ce534fb0SMiklos Szeredi cs->mapaddr = buf->ops->map(cs->pipe, buf, 1); 826ce534fb0SMiklos Szeredi cs->buf = cs->mapaddr + buf->offset; 827ce534fb0SMiklos Szeredi 828ce534fb0SMiklos Szeredi err = lock_request(cs->fc, cs->req); 829ce534fb0SMiklos Szeredi if (err) 830ce534fb0SMiklos Szeredi return err; 831ce534fb0SMiklos Szeredi 832ce534fb0SMiklos Szeredi return 1; 833ce534fb0SMiklos Szeredi } 834ce534fb0SMiklos Szeredi 835c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page, 836c3021629SMiklos Szeredi unsigned offset, unsigned count) 837c3021629SMiklos Szeredi { 838c3021629SMiklos Szeredi struct pipe_buffer *buf; 839c3021629SMiklos Szeredi 840c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 841c3021629SMiklos Szeredi return -EIO; 842c3021629SMiklos Szeredi 843c3021629SMiklos Szeredi unlock_request(cs->fc, cs->req); 844c3021629SMiklos Szeredi fuse_copy_finish(cs); 845c3021629SMiklos Szeredi 846c3021629SMiklos Szeredi buf = cs->pipebufs; 847c3021629SMiklos Szeredi page_cache_get(page); 848c3021629SMiklos Szeredi buf->page = page; 849c3021629SMiklos Szeredi buf->offset = offset; 850c3021629SMiklos Szeredi buf->len = count; 851c3021629SMiklos Szeredi 852c3021629SMiklos Szeredi cs->pipebufs++; 853c3021629SMiklos Szeredi cs->nr_segs++; 854c3021629SMiklos Szeredi cs->len = 0; 855c3021629SMiklos Szeredi 856c3021629SMiklos Szeredi return 0; 857c3021629SMiklos Szeredi } 858c3021629SMiklos Szeredi 859334f485dSMiklos Szeredi /* 860334f485dSMiklos Szeredi * Copy a page in the request to/from the userspace buffer. Must be 861334f485dSMiklos Szeredi * done atomically 862334f485dSMiklos Szeredi */ 863ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep, 864334f485dSMiklos Szeredi unsigned offset, unsigned count, int zeroing) 865334f485dSMiklos Szeredi { 866ce534fb0SMiklos Szeredi int err; 867ce534fb0SMiklos Szeredi struct page *page = *pagep; 868ce534fb0SMiklos Szeredi 869b6777c40SMiklos Szeredi if (page && zeroing && count < PAGE_SIZE) 870b6777c40SMiklos Szeredi clear_highpage(page); 871b6777c40SMiklos Szeredi 872334f485dSMiklos Szeredi while (count) { 873c3021629SMiklos Szeredi if (cs->write && cs->pipebufs && page) { 874c3021629SMiklos Szeredi return fuse_ref_page(cs, page, offset, count); 875c3021629SMiklos Szeredi } else if (!cs->len) { 876ce534fb0SMiklos Szeredi if (cs->move_pages && page && 877ce534fb0SMiklos Szeredi offset == 0 && count == PAGE_SIZE) { 878ce534fb0SMiklos Szeredi err = fuse_try_move_page(cs, pagep); 879ce534fb0SMiklos Szeredi if (err <= 0) 880ce534fb0SMiklos Szeredi return err; 881ce534fb0SMiklos Szeredi } else { 882ce534fb0SMiklos Szeredi err = fuse_copy_fill(cs); 8831729a16cSMiklos Szeredi if (err) 884334f485dSMiklos Szeredi return err; 8851729a16cSMiklos Szeredi } 886ce534fb0SMiklos Szeredi } 887334f485dSMiklos Szeredi if (page) { 8882408f6efSCong Wang void *mapaddr = kmap_atomic(page); 889334f485dSMiklos Szeredi void *buf = mapaddr + offset; 890334f485dSMiklos Szeredi offset += fuse_copy_do(cs, &buf, &count); 8912408f6efSCong Wang kunmap_atomic(mapaddr); 892334f485dSMiklos Szeredi } else 893334f485dSMiklos Szeredi offset += fuse_copy_do(cs, NULL, &count); 894334f485dSMiklos Szeredi } 895334f485dSMiklos Szeredi if (page && !cs->write) 896334f485dSMiklos Szeredi flush_dcache_page(page); 897334f485dSMiklos Szeredi return 0; 898334f485dSMiklos Szeredi } 899334f485dSMiklos Szeredi 900334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */ 901334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes, 902334f485dSMiklos Szeredi int zeroing) 903334f485dSMiklos Szeredi { 904334f485dSMiklos Szeredi unsigned i; 905334f485dSMiklos Szeredi struct fuse_req *req = cs->req; 906334f485dSMiklos Szeredi 907334f485dSMiklos Szeredi for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) { 908ce534fb0SMiklos Szeredi int err; 90985f40aecSMaxim Patlasov unsigned offset = req->page_descs[i].offset; 91085f40aecSMaxim Patlasov unsigned count = min(nbytes, req->page_descs[i].length); 911ce534fb0SMiklos Szeredi 912ce534fb0SMiklos Szeredi err = fuse_copy_page(cs, &req->pages[i], offset, count, 913ce534fb0SMiklos Szeredi zeroing); 914334f485dSMiklos Szeredi if (err) 915334f485dSMiklos Szeredi return err; 916334f485dSMiklos Szeredi 917334f485dSMiklos Szeredi nbytes -= count; 918334f485dSMiklos Szeredi } 919334f485dSMiklos Szeredi return 0; 920334f485dSMiklos Szeredi } 921334f485dSMiklos Szeredi 922334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */ 923334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) 924334f485dSMiklos Szeredi { 925334f485dSMiklos Szeredi while (size) { 9261729a16cSMiklos Szeredi if (!cs->len) { 9271729a16cSMiklos Szeredi int err = fuse_copy_fill(cs); 9281729a16cSMiklos Szeredi if (err) 929334f485dSMiklos Szeredi return err; 9301729a16cSMiklos Szeredi } 931334f485dSMiklos Szeredi fuse_copy_do(cs, &val, &size); 932334f485dSMiklos Szeredi } 933334f485dSMiklos Szeredi return 0; 934334f485dSMiklos Szeredi } 935334f485dSMiklos Szeredi 936334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */ 937334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs, 938334f485dSMiklos Szeredi unsigned argpages, struct fuse_arg *args, 939334f485dSMiklos Szeredi int zeroing) 940334f485dSMiklos Szeredi { 941334f485dSMiklos Szeredi int err = 0; 942334f485dSMiklos Szeredi unsigned i; 943334f485dSMiklos Szeredi 944334f485dSMiklos Szeredi for (i = 0; !err && i < numargs; i++) { 945334f485dSMiklos Szeredi struct fuse_arg *arg = &args[i]; 946334f485dSMiklos Szeredi if (i == numargs - 1 && argpages) 947334f485dSMiklos Szeredi err = fuse_copy_pages(cs, arg->size, zeroing); 948334f485dSMiklos Szeredi else 949334f485dSMiklos Szeredi err = fuse_copy_one(cs, arg->value, arg->size); 950334f485dSMiklos Szeredi } 951334f485dSMiklos Szeredi return err; 952334f485dSMiklos Szeredi } 953334f485dSMiklos Szeredi 95407e77dcaSMiklos Szeredi static int forget_pending(struct fuse_conn *fc) 95507e77dcaSMiklos Szeredi { 95607e77dcaSMiklos Szeredi return fc->forget_list_head.next != NULL; 95707e77dcaSMiklos Szeredi } 95807e77dcaSMiklos Szeredi 959a4d27e75SMiklos Szeredi static int request_pending(struct fuse_conn *fc) 960a4d27e75SMiklos Szeredi { 96107e77dcaSMiklos Szeredi return !list_empty(&fc->pending) || !list_empty(&fc->interrupts) || 96207e77dcaSMiklos Szeredi forget_pending(fc); 963a4d27e75SMiklos Szeredi } 964a4d27e75SMiklos Szeredi 965334f485dSMiklos Szeredi /* Wait until a request is available on the pending list */ 966334f485dSMiklos Szeredi static void request_wait(struct fuse_conn *fc) 967b9ca67b2SMiklos Szeredi __releases(fc->lock) 968b9ca67b2SMiklos Szeredi __acquires(fc->lock) 969334f485dSMiklos Szeredi { 970334f485dSMiklos Szeredi DECLARE_WAITQUEUE(wait, current); 971334f485dSMiklos Szeredi 972334f485dSMiklos Szeredi add_wait_queue_exclusive(&fc->waitq, &wait); 973a4d27e75SMiklos Szeredi while (fc->connected && !request_pending(fc)) { 974334f485dSMiklos Szeredi set_current_state(TASK_INTERRUPTIBLE); 975334f485dSMiklos Szeredi if (signal_pending(current)) 976334f485dSMiklos Szeredi break; 977334f485dSMiklos Szeredi 978d7133114SMiklos Szeredi spin_unlock(&fc->lock); 979334f485dSMiklos Szeredi schedule(); 980d7133114SMiklos Szeredi spin_lock(&fc->lock); 981334f485dSMiklos Szeredi } 982334f485dSMiklos Szeredi set_current_state(TASK_RUNNING); 983334f485dSMiklos Szeredi remove_wait_queue(&fc->waitq, &wait); 984334f485dSMiklos Szeredi } 985334f485dSMiklos Szeredi 986334f485dSMiklos Szeredi /* 987a4d27e75SMiklos Szeredi * Transfer an interrupt request to userspace 988a4d27e75SMiklos Szeredi * 989a4d27e75SMiklos Szeredi * Unlike other requests this is assembled on demand, without a need 990a4d27e75SMiklos Szeredi * to allocate a separate fuse_req structure. 991a4d27e75SMiklos Szeredi * 992a4d27e75SMiklos Szeredi * Called with fc->lock held, releases it 993a4d27e75SMiklos Szeredi */ 994c3021629SMiklos Szeredi static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_copy_state *cs, 995c3021629SMiklos Szeredi size_t nbytes, struct fuse_req *req) 996b9ca67b2SMiklos Szeredi __releases(fc->lock) 997a4d27e75SMiklos Szeredi { 998a4d27e75SMiklos Szeredi struct fuse_in_header ih; 999a4d27e75SMiklos Szeredi struct fuse_interrupt_in arg; 1000a4d27e75SMiklos Szeredi unsigned reqsize = sizeof(ih) + sizeof(arg); 1001a4d27e75SMiklos Szeredi int err; 1002a4d27e75SMiklos Szeredi 1003a4d27e75SMiklos Szeredi list_del_init(&req->intr_entry); 1004a4d27e75SMiklos Szeredi req->intr_unique = fuse_get_unique(fc); 1005a4d27e75SMiklos Szeredi memset(&ih, 0, sizeof(ih)); 1006a4d27e75SMiklos Szeredi memset(&arg, 0, sizeof(arg)); 1007a4d27e75SMiklos Szeredi ih.len = reqsize; 1008a4d27e75SMiklos Szeredi ih.opcode = FUSE_INTERRUPT; 1009a4d27e75SMiklos Szeredi ih.unique = req->intr_unique; 1010a4d27e75SMiklos Szeredi arg.unique = req->in.h.unique; 1011a4d27e75SMiklos Szeredi 1012a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 1013c3021629SMiklos Szeredi if (nbytes < reqsize) 1014a4d27e75SMiklos Szeredi return -EINVAL; 1015a4d27e75SMiklos Szeredi 1016c3021629SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 1017a4d27e75SMiklos Szeredi if (!err) 1018c3021629SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 1019c3021629SMiklos Szeredi fuse_copy_finish(cs); 1020a4d27e75SMiklos Szeredi 1021a4d27e75SMiklos Szeredi return err ? err : reqsize; 1022a4d27e75SMiklos Szeredi } 1023a4d27e75SMiklos Szeredi 102402c048b9SMiklos Szeredi static struct fuse_forget_link *dequeue_forget(struct fuse_conn *fc, 102502c048b9SMiklos Szeredi unsigned max, 102602c048b9SMiklos Szeredi unsigned *countp) 102707e77dcaSMiklos Szeredi { 102802c048b9SMiklos Szeredi struct fuse_forget_link *head = fc->forget_list_head.next; 102902c048b9SMiklos Szeredi struct fuse_forget_link **newhead = &head; 103002c048b9SMiklos Szeredi unsigned count; 103107e77dcaSMiklos Szeredi 103202c048b9SMiklos Szeredi for (count = 0; *newhead != NULL && count < max; count++) 103302c048b9SMiklos Szeredi newhead = &(*newhead)->next; 103402c048b9SMiklos Szeredi 103502c048b9SMiklos Szeredi fc->forget_list_head.next = *newhead; 103602c048b9SMiklos Szeredi *newhead = NULL; 103707e77dcaSMiklos Szeredi if (fc->forget_list_head.next == NULL) 103807e77dcaSMiklos Szeredi fc->forget_list_tail = &fc->forget_list_head; 103907e77dcaSMiklos Szeredi 104002c048b9SMiklos Szeredi if (countp != NULL) 104102c048b9SMiklos Szeredi *countp = count; 104202c048b9SMiklos Szeredi 104302c048b9SMiklos Szeredi return head; 104407e77dcaSMiklos Szeredi } 104507e77dcaSMiklos Szeredi 104607e77dcaSMiklos Szeredi static int fuse_read_single_forget(struct fuse_conn *fc, 104707e77dcaSMiklos Szeredi struct fuse_copy_state *cs, 104807e77dcaSMiklos Szeredi size_t nbytes) 104907e77dcaSMiklos Szeredi __releases(fc->lock) 105007e77dcaSMiklos Szeredi { 105107e77dcaSMiklos Szeredi int err; 105202c048b9SMiklos Szeredi struct fuse_forget_link *forget = dequeue_forget(fc, 1, NULL); 105307e77dcaSMiklos Szeredi struct fuse_forget_in arg = { 105402c048b9SMiklos Szeredi .nlookup = forget->forget_one.nlookup, 105507e77dcaSMiklos Szeredi }; 105607e77dcaSMiklos Szeredi struct fuse_in_header ih = { 105707e77dcaSMiklos Szeredi .opcode = FUSE_FORGET, 105802c048b9SMiklos Szeredi .nodeid = forget->forget_one.nodeid, 105907e77dcaSMiklos Szeredi .unique = fuse_get_unique(fc), 106007e77dcaSMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 106107e77dcaSMiklos Szeredi }; 106207e77dcaSMiklos Szeredi 106307e77dcaSMiklos Szeredi spin_unlock(&fc->lock); 106407e77dcaSMiklos Szeredi kfree(forget); 106507e77dcaSMiklos Szeredi if (nbytes < ih.len) 106607e77dcaSMiklos Szeredi return -EINVAL; 106707e77dcaSMiklos Szeredi 106807e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 106907e77dcaSMiklos Szeredi if (!err) 107007e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 107107e77dcaSMiklos Szeredi fuse_copy_finish(cs); 107207e77dcaSMiklos Szeredi 107307e77dcaSMiklos Szeredi if (err) 107407e77dcaSMiklos Szeredi return err; 107507e77dcaSMiklos Szeredi 107607e77dcaSMiklos Szeredi return ih.len; 107707e77dcaSMiklos Szeredi } 107807e77dcaSMiklos Szeredi 107902c048b9SMiklos Szeredi static int fuse_read_batch_forget(struct fuse_conn *fc, 108002c048b9SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 108102c048b9SMiklos Szeredi __releases(fc->lock) 108202c048b9SMiklos Szeredi { 108302c048b9SMiklos Szeredi int err; 108402c048b9SMiklos Szeredi unsigned max_forgets; 108502c048b9SMiklos Szeredi unsigned count; 108602c048b9SMiklos Szeredi struct fuse_forget_link *head; 108702c048b9SMiklos Szeredi struct fuse_batch_forget_in arg = { .count = 0 }; 108802c048b9SMiklos Szeredi struct fuse_in_header ih = { 108902c048b9SMiklos Szeredi .opcode = FUSE_BATCH_FORGET, 109002c048b9SMiklos Szeredi .unique = fuse_get_unique(fc), 109102c048b9SMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 109202c048b9SMiklos Szeredi }; 109302c048b9SMiklos Szeredi 109402c048b9SMiklos Szeredi if (nbytes < ih.len) { 109502c048b9SMiklos Szeredi spin_unlock(&fc->lock); 109602c048b9SMiklos Szeredi return -EINVAL; 109702c048b9SMiklos Szeredi } 109802c048b9SMiklos Szeredi 109902c048b9SMiklos Szeredi max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one); 110002c048b9SMiklos Szeredi head = dequeue_forget(fc, max_forgets, &count); 110102c048b9SMiklos Szeredi spin_unlock(&fc->lock); 110202c048b9SMiklos Szeredi 110302c048b9SMiklos Szeredi arg.count = count; 110402c048b9SMiklos Szeredi ih.len += count * sizeof(struct fuse_forget_one); 110502c048b9SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 110602c048b9SMiklos Szeredi if (!err) 110702c048b9SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 110802c048b9SMiklos Szeredi 110902c048b9SMiklos Szeredi while (head) { 111002c048b9SMiklos Szeredi struct fuse_forget_link *forget = head; 111102c048b9SMiklos Szeredi 111202c048b9SMiklos Szeredi if (!err) { 111302c048b9SMiklos Szeredi err = fuse_copy_one(cs, &forget->forget_one, 111402c048b9SMiklos Szeredi sizeof(forget->forget_one)); 111502c048b9SMiklos Szeredi } 111602c048b9SMiklos Szeredi head = forget->next; 111702c048b9SMiklos Szeredi kfree(forget); 111802c048b9SMiklos Szeredi } 111902c048b9SMiklos Szeredi 112002c048b9SMiklos Szeredi fuse_copy_finish(cs); 112102c048b9SMiklos Szeredi 112202c048b9SMiklos Szeredi if (err) 112302c048b9SMiklos Szeredi return err; 112402c048b9SMiklos Szeredi 112502c048b9SMiklos Szeredi return ih.len; 112602c048b9SMiklos Szeredi } 112702c048b9SMiklos Szeredi 112802c048b9SMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_copy_state *cs, 112902c048b9SMiklos Szeredi size_t nbytes) 113002c048b9SMiklos Szeredi __releases(fc->lock) 113102c048b9SMiklos Szeredi { 113202c048b9SMiklos Szeredi if (fc->minor < 16 || fc->forget_list_head.next->next == NULL) 113302c048b9SMiklos Szeredi return fuse_read_single_forget(fc, cs, nbytes); 113402c048b9SMiklos Szeredi else 113502c048b9SMiklos Szeredi return fuse_read_batch_forget(fc, cs, nbytes); 113602c048b9SMiklos Szeredi } 113702c048b9SMiklos Szeredi 1138a4d27e75SMiklos Szeredi /* 1139334f485dSMiklos Szeredi * Read a single request into the userspace filesystem's buffer. This 1140334f485dSMiklos Szeredi * function waits until a request is available, then removes it from 1141334f485dSMiklos Szeredi * the pending list and copies request data to userspace buffer. If 1142f9a2842eSMiklos Szeredi * no reply is needed (FORGET) or request has been aborted or there 1143f9a2842eSMiklos Szeredi * was an error during the copying then it's finished by calling 1144334f485dSMiklos Szeredi * request_end(). Otherwise add it to the processing list, and set 1145334f485dSMiklos Szeredi * the 'sent' flag. 1146334f485dSMiklos Szeredi */ 1147c3021629SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file, 1148c3021629SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1149334f485dSMiklos Szeredi { 1150334f485dSMiklos Szeredi int err; 1151334f485dSMiklos Szeredi struct fuse_req *req; 1152334f485dSMiklos Szeredi struct fuse_in *in; 1153334f485dSMiklos Szeredi unsigned reqsize; 1154334f485dSMiklos Szeredi 11551d3d752bSMiklos Szeredi restart: 1156d7133114SMiklos Szeredi spin_lock(&fc->lock); 1157e5ac1d1eSJeff Dike err = -EAGAIN; 1158e5ac1d1eSJeff Dike if ((file->f_flags & O_NONBLOCK) && fc->connected && 1159a4d27e75SMiklos Szeredi !request_pending(fc)) 1160e5ac1d1eSJeff Dike goto err_unlock; 1161e5ac1d1eSJeff Dike 1162334f485dSMiklos Szeredi request_wait(fc); 1163334f485dSMiklos Szeredi err = -ENODEV; 11649ba7cbbaSMiklos Szeredi if (!fc->connected) 1165334f485dSMiklos Szeredi goto err_unlock; 1166334f485dSMiklos Szeredi err = -ERESTARTSYS; 1167a4d27e75SMiklos Szeredi if (!request_pending(fc)) 1168334f485dSMiklos Szeredi goto err_unlock; 1169334f485dSMiklos Szeredi 1170a4d27e75SMiklos Szeredi if (!list_empty(&fc->interrupts)) { 1171a4d27e75SMiklos Szeredi req = list_entry(fc->interrupts.next, struct fuse_req, 1172a4d27e75SMiklos Szeredi intr_entry); 1173c3021629SMiklos Szeredi return fuse_read_interrupt(fc, cs, nbytes, req); 1174a4d27e75SMiklos Szeredi } 1175a4d27e75SMiklos Szeredi 117607e77dcaSMiklos Szeredi if (forget_pending(fc)) { 117707e77dcaSMiklos Szeredi if (list_empty(&fc->pending) || fc->forget_batch-- > 0) 117802c048b9SMiklos Szeredi return fuse_read_forget(fc, cs, nbytes); 117907e77dcaSMiklos Szeredi 118007e77dcaSMiklos Szeredi if (fc->forget_batch <= -8) 118107e77dcaSMiklos Szeredi fc->forget_batch = 16; 118207e77dcaSMiklos Szeredi } 118307e77dcaSMiklos Szeredi 1184334f485dSMiklos Szeredi req = list_entry(fc->pending.next, struct fuse_req, list); 118583cfd493SMiklos Szeredi req->state = FUSE_REQ_READING; 1186d77a1d5bSMiklos Szeredi list_move(&req->list, &fc->io); 1187334f485dSMiklos Szeredi 1188334f485dSMiklos Szeredi in = &req->in; 11891d3d752bSMiklos Szeredi reqsize = in->h.len; 11901d3d752bSMiklos Szeredi /* If request is too large, reply with an error and restart the read */ 1191c3021629SMiklos Szeredi if (nbytes < reqsize) { 11921d3d752bSMiklos Szeredi req->out.h.error = -EIO; 11931d3d752bSMiklos Szeredi /* SETXATTR is special, since it may contain too large data */ 11941d3d752bSMiklos Szeredi if (in->h.opcode == FUSE_SETXATTR) 11951d3d752bSMiklos Szeredi req->out.h.error = -E2BIG; 11961d3d752bSMiklos Szeredi request_end(fc, req); 11971d3d752bSMiklos Szeredi goto restart; 11981d3d752bSMiklos Szeredi } 1199d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1200c3021629SMiklos Szeredi cs->req = req; 1201c3021629SMiklos Szeredi err = fuse_copy_one(cs, &in->h, sizeof(in->h)); 1202334f485dSMiklos Szeredi if (!err) 1203c3021629SMiklos Szeredi err = fuse_copy_args(cs, in->numargs, in->argpages, 1204334f485dSMiklos Szeredi (struct fuse_arg *) in->args, 0); 1205c3021629SMiklos Szeredi fuse_copy_finish(cs); 1206d7133114SMiklos Szeredi spin_lock(&fc->lock); 1207334f485dSMiklos Szeredi req->locked = 0; 1208c9c9d7dfSMiklos Szeredi if (req->aborted) { 1209c9c9d7dfSMiklos Szeredi request_end(fc, req); 1210c9c9d7dfSMiklos Szeredi return -ENODEV; 1211c9c9d7dfSMiklos Szeredi } 1212334f485dSMiklos Szeredi if (err) { 1213334f485dSMiklos Szeredi req->out.h.error = -EIO; 1214334f485dSMiklos Szeredi request_end(fc, req); 1215334f485dSMiklos Szeredi return err; 1216334f485dSMiklos Szeredi } 1217334f485dSMiklos Szeredi if (!req->isreply) 1218334f485dSMiklos Szeredi request_end(fc, req); 1219334f485dSMiklos Szeredi else { 122083cfd493SMiklos Szeredi req->state = FUSE_REQ_SENT; 1221d77a1d5bSMiklos Szeredi list_move_tail(&req->list, &fc->processing); 1222a4d27e75SMiklos Szeredi if (req->interrupted) 1223a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 1224d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1225334f485dSMiklos Szeredi } 1226334f485dSMiklos Szeredi return reqsize; 1227334f485dSMiklos Szeredi 1228334f485dSMiklos Szeredi err_unlock: 1229d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1230334f485dSMiklos Szeredi return err; 1231334f485dSMiklos Szeredi } 1232334f485dSMiklos Szeredi 1233c3021629SMiklos Szeredi static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, 1234c3021629SMiklos Szeredi unsigned long nr_segs, loff_t pos) 1235c3021629SMiklos Szeredi { 1236c3021629SMiklos Szeredi struct fuse_copy_state cs; 1237c3021629SMiklos Szeredi struct file *file = iocb->ki_filp; 1238c3021629SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 1239c3021629SMiklos Szeredi if (!fc) 1240c3021629SMiklos Szeredi return -EPERM; 1241c3021629SMiklos Szeredi 1242c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 1, iov, nr_segs); 1243c3021629SMiklos Szeredi 1244c3021629SMiklos Szeredi return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs)); 1245c3021629SMiklos Szeredi } 1246c3021629SMiklos Szeredi 1247c3021629SMiklos Szeredi static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe, 1248c3021629SMiklos Szeredi struct pipe_buffer *buf) 1249c3021629SMiklos Szeredi { 1250c3021629SMiklos Szeredi return 1; 1251c3021629SMiklos Szeredi } 1252c3021629SMiklos Szeredi 1253c3021629SMiklos Szeredi static const struct pipe_buf_operations fuse_dev_pipe_buf_ops = { 1254c3021629SMiklos Szeredi .can_merge = 0, 1255c3021629SMiklos Szeredi .map = generic_pipe_buf_map, 1256c3021629SMiklos Szeredi .unmap = generic_pipe_buf_unmap, 1257c3021629SMiklos Szeredi .confirm = generic_pipe_buf_confirm, 1258c3021629SMiklos Szeredi .release = generic_pipe_buf_release, 1259c3021629SMiklos Szeredi .steal = fuse_dev_pipe_buf_steal, 1260c3021629SMiklos Szeredi .get = generic_pipe_buf_get, 1261c3021629SMiklos Szeredi }; 1262c3021629SMiklos Szeredi 1263c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, 1264c3021629SMiklos Szeredi struct pipe_inode_info *pipe, 1265c3021629SMiklos Szeredi size_t len, unsigned int flags) 1266c3021629SMiklos Szeredi { 1267c3021629SMiklos Szeredi int ret; 1268c3021629SMiklos Szeredi int page_nr = 0; 1269c3021629SMiklos Szeredi int do_wakeup = 0; 1270c3021629SMiklos Szeredi struct pipe_buffer *bufs; 1271c3021629SMiklos Szeredi struct fuse_copy_state cs; 1272c3021629SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(in); 1273c3021629SMiklos Szeredi if (!fc) 1274c3021629SMiklos Szeredi return -EPERM; 1275c3021629SMiklos Szeredi 1276c3021629SMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1277c3021629SMiklos Szeredi if (!bufs) 1278c3021629SMiklos Szeredi return -ENOMEM; 1279c3021629SMiklos Szeredi 1280c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 1, NULL, 0); 1281c3021629SMiklos Szeredi cs.pipebufs = bufs; 1282c3021629SMiklos Szeredi cs.pipe = pipe; 1283c3021629SMiklos Szeredi ret = fuse_dev_do_read(fc, in, &cs, len); 1284c3021629SMiklos Szeredi if (ret < 0) 1285c3021629SMiklos Szeredi goto out; 1286c3021629SMiklos Szeredi 1287c3021629SMiklos Szeredi ret = 0; 1288c3021629SMiklos Szeredi pipe_lock(pipe); 1289c3021629SMiklos Szeredi 1290c3021629SMiklos Szeredi if (!pipe->readers) { 1291c3021629SMiklos Szeredi send_sig(SIGPIPE, current, 0); 1292c3021629SMiklos Szeredi if (!ret) 1293c3021629SMiklos Szeredi ret = -EPIPE; 1294c3021629SMiklos Szeredi goto out_unlock; 1295c3021629SMiklos Szeredi } 1296c3021629SMiklos Szeredi 1297c3021629SMiklos Szeredi if (pipe->nrbufs + cs.nr_segs > pipe->buffers) { 1298c3021629SMiklos Szeredi ret = -EIO; 1299c3021629SMiklos Szeredi goto out_unlock; 1300c3021629SMiklos Szeredi } 1301c3021629SMiklos Szeredi 1302c3021629SMiklos Szeredi while (page_nr < cs.nr_segs) { 1303c3021629SMiklos Szeredi int newbuf = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); 1304c3021629SMiklos Szeredi struct pipe_buffer *buf = pipe->bufs + newbuf; 1305c3021629SMiklos Szeredi 1306c3021629SMiklos Szeredi buf->page = bufs[page_nr].page; 1307c3021629SMiklos Szeredi buf->offset = bufs[page_nr].offset; 1308c3021629SMiklos Szeredi buf->len = bufs[page_nr].len; 1309c3021629SMiklos Szeredi buf->ops = &fuse_dev_pipe_buf_ops; 1310c3021629SMiklos Szeredi 1311c3021629SMiklos Szeredi pipe->nrbufs++; 1312c3021629SMiklos Szeredi page_nr++; 1313c3021629SMiklos Szeredi ret += buf->len; 1314c3021629SMiklos Szeredi 1315c3021629SMiklos Szeredi if (pipe->inode) 1316c3021629SMiklos Szeredi do_wakeup = 1; 1317c3021629SMiklos Szeredi } 1318c3021629SMiklos Szeredi 1319c3021629SMiklos Szeredi out_unlock: 1320c3021629SMiklos Szeredi pipe_unlock(pipe); 1321c3021629SMiklos Szeredi 1322c3021629SMiklos Szeredi if (do_wakeup) { 1323c3021629SMiklos Szeredi smp_mb(); 1324c3021629SMiklos Szeredi if (waitqueue_active(&pipe->wait)) 1325c3021629SMiklos Szeredi wake_up_interruptible(&pipe->wait); 1326c3021629SMiklos Szeredi kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); 1327c3021629SMiklos Szeredi } 1328c3021629SMiklos Szeredi 1329c3021629SMiklos Szeredi out: 1330c3021629SMiklos Szeredi for (; page_nr < cs.nr_segs; page_nr++) 1331c3021629SMiklos Szeredi page_cache_release(bufs[page_nr].page); 1332c3021629SMiklos Szeredi 1333c3021629SMiklos Szeredi kfree(bufs); 1334c3021629SMiklos Szeredi return ret; 1335c3021629SMiklos Szeredi } 1336c3021629SMiklos Szeredi 133795668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size, 133895668a69STejun Heo struct fuse_copy_state *cs) 133995668a69STejun Heo { 134095668a69STejun Heo struct fuse_notify_poll_wakeup_out outarg; 1341f6d47a17SMiklos Szeredi int err = -EINVAL; 134295668a69STejun Heo 134395668a69STejun Heo if (size != sizeof(outarg)) 1344f6d47a17SMiklos Szeredi goto err; 134595668a69STejun Heo 134695668a69STejun Heo err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 134795668a69STejun Heo if (err) 1348f6d47a17SMiklos Szeredi goto err; 134995668a69STejun Heo 1350f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 135195668a69STejun Heo return fuse_notify_poll_wakeup(fc, &outarg); 1352f6d47a17SMiklos Szeredi 1353f6d47a17SMiklos Szeredi err: 1354f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 1355f6d47a17SMiklos Szeredi return err; 135695668a69STejun Heo } 135795668a69STejun Heo 13583b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size, 13593b463ae0SJohn Muir struct fuse_copy_state *cs) 13603b463ae0SJohn Muir { 13613b463ae0SJohn Muir struct fuse_notify_inval_inode_out outarg; 13623b463ae0SJohn Muir int err = -EINVAL; 13633b463ae0SJohn Muir 13643b463ae0SJohn Muir if (size != sizeof(outarg)) 13653b463ae0SJohn Muir goto err; 13663b463ae0SJohn Muir 13673b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 13683b463ae0SJohn Muir if (err) 13693b463ae0SJohn Muir goto err; 13703b463ae0SJohn Muir fuse_copy_finish(cs); 13713b463ae0SJohn Muir 13723b463ae0SJohn Muir down_read(&fc->killsb); 13733b463ae0SJohn Muir err = -ENOENT; 1374b21dda43SMiklos Szeredi if (fc->sb) { 13753b463ae0SJohn Muir err = fuse_reverse_inval_inode(fc->sb, outarg.ino, 13763b463ae0SJohn Muir outarg.off, outarg.len); 1377b21dda43SMiklos Szeredi } 13783b463ae0SJohn Muir up_read(&fc->killsb); 13793b463ae0SJohn Muir return err; 13803b463ae0SJohn Muir 13813b463ae0SJohn Muir err: 13823b463ae0SJohn Muir fuse_copy_finish(cs); 13833b463ae0SJohn Muir return err; 13843b463ae0SJohn Muir } 13853b463ae0SJohn Muir 13863b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, 13873b463ae0SJohn Muir struct fuse_copy_state *cs) 13883b463ae0SJohn Muir { 13893b463ae0SJohn Muir struct fuse_notify_inval_entry_out outarg; 1390b2d82ee3SFang Wenqi int err = -ENOMEM; 1391b2d82ee3SFang Wenqi char *buf; 13923b463ae0SJohn Muir struct qstr name; 13933b463ae0SJohn Muir 1394b2d82ee3SFang Wenqi buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1395b2d82ee3SFang Wenqi if (!buf) 1396b2d82ee3SFang Wenqi goto err; 1397b2d82ee3SFang Wenqi 1398b2d82ee3SFang Wenqi err = -EINVAL; 13993b463ae0SJohn Muir if (size < sizeof(outarg)) 14003b463ae0SJohn Muir goto err; 14013b463ae0SJohn Muir 14023b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 14033b463ae0SJohn Muir if (err) 14043b463ae0SJohn Muir goto err; 14053b463ae0SJohn Muir 14063b463ae0SJohn Muir err = -ENAMETOOLONG; 14073b463ae0SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 14083b463ae0SJohn Muir goto err; 14093b463ae0SJohn Muir 1410c2183d1eSMiklos Szeredi err = -EINVAL; 1411c2183d1eSMiklos Szeredi if (size != sizeof(outarg) + outarg.namelen + 1) 1412c2183d1eSMiklos Szeredi goto err; 1413c2183d1eSMiklos Szeredi 14143b463ae0SJohn Muir name.name = buf; 14153b463ae0SJohn Muir name.len = outarg.namelen; 14163b463ae0SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 14173b463ae0SJohn Muir if (err) 14183b463ae0SJohn Muir goto err; 14193b463ae0SJohn Muir fuse_copy_finish(cs); 14203b463ae0SJohn Muir buf[outarg.namelen] = 0; 14213b463ae0SJohn Muir name.hash = full_name_hash(name.name, name.len); 14223b463ae0SJohn Muir 14233b463ae0SJohn Muir down_read(&fc->killsb); 14243b463ae0SJohn Muir err = -ENOENT; 1425b21dda43SMiklos Szeredi if (fc->sb) 1426451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 0, &name); 1427451d0f59SJohn Muir up_read(&fc->killsb); 1428451d0f59SJohn Muir kfree(buf); 1429451d0f59SJohn Muir return err; 1430451d0f59SJohn Muir 1431451d0f59SJohn Muir err: 1432451d0f59SJohn Muir kfree(buf); 1433451d0f59SJohn Muir fuse_copy_finish(cs); 1434451d0f59SJohn Muir return err; 1435451d0f59SJohn Muir } 1436451d0f59SJohn Muir 1437451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size, 1438451d0f59SJohn Muir struct fuse_copy_state *cs) 1439451d0f59SJohn Muir { 1440451d0f59SJohn Muir struct fuse_notify_delete_out outarg; 1441451d0f59SJohn Muir int err = -ENOMEM; 1442451d0f59SJohn Muir char *buf; 1443451d0f59SJohn Muir struct qstr name; 1444451d0f59SJohn Muir 1445451d0f59SJohn Muir buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1446451d0f59SJohn Muir if (!buf) 1447451d0f59SJohn Muir goto err; 1448451d0f59SJohn Muir 1449451d0f59SJohn Muir err = -EINVAL; 1450451d0f59SJohn Muir if (size < sizeof(outarg)) 1451451d0f59SJohn Muir goto err; 1452451d0f59SJohn Muir 1453451d0f59SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1454451d0f59SJohn Muir if (err) 1455451d0f59SJohn Muir goto err; 1456451d0f59SJohn Muir 1457451d0f59SJohn Muir err = -ENAMETOOLONG; 1458451d0f59SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 1459451d0f59SJohn Muir goto err; 1460451d0f59SJohn Muir 1461451d0f59SJohn Muir err = -EINVAL; 1462451d0f59SJohn Muir if (size != sizeof(outarg) + outarg.namelen + 1) 1463451d0f59SJohn Muir goto err; 1464451d0f59SJohn Muir 1465451d0f59SJohn Muir name.name = buf; 1466451d0f59SJohn Muir name.len = outarg.namelen; 1467451d0f59SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 1468451d0f59SJohn Muir if (err) 1469451d0f59SJohn Muir goto err; 1470451d0f59SJohn Muir fuse_copy_finish(cs); 1471451d0f59SJohn Muir buf[outarg.namelen] = 0; 1472451d0f59SJohn Muir name.hash = full_name_hash(name.name, name.len); 1473451d0f59SJohn Muir 1474451d0f59SJohn Muir down_read(&fc->killsb); 1475451d0f59SJohn Muir err = -ENOENT; 1476451d0f59SJohn Muir if (fc->sb) 1477451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 1478451d0f59SJohn Muir outarg.child, &name); 14793b463ae0SJohn Muir up_read(&fc->killsb); 1480b2d82ee3SFang Wenqi kfree(buf); 14813b463ae0SJohn Muir return err; 14823b463ae0SJohn Muir 14833b463ae0SJohn Muir err: 1484b2d82ee3SFang Wenqi kfree(buf); 14853b463ae0SJohn Muir fuse_copy_finish(cs); 14863b463ae0SJohn Muir return err; 14873b463ae0SJohn Muir } 14883b463ae0SJohn Muir 1489a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, 1490a1d75f25SMiklos Szeredi struct fuse_copy_state *cs) 1491a1d75f25SMiklos Szeredi { 1492a1d75f25SMiklos Szeredi struct fuse_notify_store_out outarg; 1493a1d75f25SMiklos Szeredi struct inode *inode; 1494a1d75f25SMiklos Szeredi struct address_space *mapping; 1495a1d75f25SMiklos Szeredi u64 nodeid; 1496a1d75f25SMiklos Szeredi int err; 1497a1d75f25SMiklos Szeredi pgoff_t index; 1498a1d75f25SMiklos Szeredi unsigned int offset; 1499a1d75f25SMiklos Szeredi unsigned int num; 1500a1d75f25SMiklos Szeredi loff_t file_size; 1501a1d75f25SMiklos Szeredi loff_t end; 1502a1d75f25SMiklos Szeredi 1503a1d75f25SMiklos Szeredi err = -EINVAL; 1504a1d75f25SMiklos Szeredi if (size < sizeof(outarg)) 1505a1d75f25SMiklos Szeredi goto out_finish; 1506a1d75f25SMiklos Szeredi 1507a1d75f25SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1508a1d75f25SMiklos Szeredi if (err) 1509a1d75f25SMiklos Szeredi goto out_finish; 1510a1d75f25SMiklos Szeredi 1511a1d75f25SMiklos Szeredi err = -EINVAL; 1512a1d75f25SMiklos Szeredi if (size - sizeof(outarg) != outarg.size) 1513a1d75f25SMiklos Szeredi goto out_finish; 1514a1d75f25SMiklos Szeredi 1515a1d75f25SMiklos Szeredi nodeid = outarg.nodeid; 1516a1d75f25SMiklos Szeredi 1517a1d75f25SMiklos Szeredi down_read(&fc->killsb); 1518a1d75f25SMiklos Szeredi 1519a1d75f25SMiklos Szeredi err = -ENOENT; 1520a1d75f25SMiklos Szeredi if (!fc->sb) 1521a1d75f25SMiklos Szeredi goto out_up_killsb; 1522a1d75f25SMiklos Szeredi 1523a1d75f25SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 1524a1d75f25SMiklos Szeredi if (!inode) 1525a1d75f25SMiklos Szeredi goto out_up_killsb; 1526a1d75f25SMiklos Szeredi 1527a1d75f25SMiklos Szeredi mapping = inode->i_mapping; 1528a1d75f25SMiklos Szeredi index = outarg.offset >> PAGE_CACHE_SHIFT; 1529a1d75f25SMiklos Szeredi offset = outarg.offset & ~PAGE_CACHE_MASK; 1530a1d75f25SMiklos Szeredi file_size = i_size_read(inode); 1531a1d75f25SMiklos Szeredi end = outarg.offset + outarg.size; 1532a1d75f25SMiklos Szeredi if (end > file_size) { 1533a1d75f25SMiklos Szeredi file_size = end; 1534a1d75f25SMiklos Szeredi fuse_write_update_size(inode, file_size); 1535a1d75f25SMiklos Szeredi } 1536a1d75f25SMiklos Szeredi 1537a1d75f25SMiklos Szeredi num = outarg.size; 1538a1d75f25SMiklos Szeredi while (num) { 1539a1d75f25SMiklos Szeredi struct page *page; 1540a1d75f25SMiklos Szeredi unsigned int this_num; 1541a1d75f25SMiklos Szeredi 1542a1d75f25SMiklos Szeredi err = -ENOMEM; 1543a1d75f25SMiklos Szeredi page = find_or_create_page(mapping, index, 1544a1d75f25SMiklos Szeredi mapping_gfp_mask(mapping)); 1545a1d75f25SMiklos Szeredi if (!page) 1546a1d75f25SMiklos Szeredi goto out_iput; 1547a1d75f25SMiklos Szeredi 1548a1d75f25SMiklos Szeredi this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 1549a1d75f25SMiklos Szeredi err = fuse_copy_page(cs, &page, offset, this_num, 0); 1550a1d75f25SMiklos Szeredi if (!err && offset == 0 && (num != 0 || file_size == end)) 1551a1d75f25SMiklos Szeredi SetPageUptodate(page); 1552a1d75f25SMiklos Szeredi unlock_page(page); 1553a1d75f25SMiklos Szeredi page_cache_release(page); 1554a1d75f25SMiklos Szeredi 1555a1d75f25SMiklos Szeredi if (err) 1556a1d75f25SMiklos Szeredi goto out_iput; 1557a1d75f25SMiklos Szeredi 1558a1d75f25SMiklos Szeredi num -= this_num; 1559a1d75f25SMiklos Szeredi offset = 0; 1560a1d75f25SMiklos Szeredi index++; 1561a1d75f25SMiklos Szeredi } 1562a1d75f25SMiklos Szeredi 1563a1d75f25SMiklos Szeredi err = 0; 1564a1d75f25SMiklos Szeredi 1565a1d75f25SMiklos Szeredi out_iput: 1566a1d75f25SMiklos Szeredi iput(inode); 1567a1d75f25SMiklos Szeredi out_up_killsb: 1568a1d75f25SMiklos Szeredi up_read(&fc->killsb); 1569a1d75f25SMiklos Szeredi out_finish: 1570a1d75f25SMiklos Szeredi fuse_copy_finish(cs); 1571a1d75f25SMiklos Szeredi return err; 1572a1d75f25SMiklos Szeredi } 1573a1d75f25SMiklos Szeredi 15742d45ba38SMiklos Szeredi static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) 15752d45ba38SMiklos Szeredi { 15760be8557bSMiklos Szeredi release_pages(req->pages, req->num_pages, 0); 15772d45ba38SMiklos Szeredi } 15782d45ba38SMiklos Szeredi 15792d45ba38SMiklos Szeredi static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, 15802d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out *outarg) 15812d45ba38SMiklos Szeredi { 15822d45ba38SMiklos Szeredi int err; 15832d45ba38SMiklos Szeredi struct address_space *mapping = inode->i_mapping; 15842d45ba38SMiklos Szeredi struct fuse_req *req; 15852d45ba38SMiklos Szeredi pgoff_t index; 15862d45ba38SMiklos Szeredi loff_t file_size; 15872d45ba38SMiklos Szeredi unsigned int num; 15882d45ba38SMiklos Szeredi unsigned int offset; 15890157443cSGeert Uytterhoeven size_t total_len = 0; 15904d53dc99SMaxim Patlasov int num_pages; 15912d45ba38SMiklos Szeredi 15922d45ba38SMiklos Szeredi offset = outarg->offset & ~PAGE_CACHE_MASK; 15934d53dc99SMaxim Patlasov file_size = i_size_read(inode); 15944d53dc99SMaxim Patlasov 15954d53dc99SMaxim Patlasov num = outarg->size; 15964d53dc99SMaxim Patlasov if (outarg->offset > file_size) 15974d53dc99SMaxim Patlasov num = 0; 15984d53dc99SMaxim Patlasov else if (outarg->offset + num > file_size) 15994d53dc99SMaxim Patlasov num = file_size - outarg->offset; 16004d53dc99SMaxim Patlasov 16014d53dc99SMaxim Patlasov num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; 16024d53dc99SMaxim Patlasov num_pages = min(num_pages, FUSE_MAX_PAGES_PER_REQ); 16034d53dc99SMaxim Patlasov 16044d53dc99SMaxim Patlasov req = fuse_get_req(fc, num_pages); 16054d53dc99SMaxim Patlasov if (IS_ERR(req)) 16064d53dc99SMaxim Patlasov return PTR_ERR(req); 16072d45ba38SMiklos Szeredi 16082d45ba38SMiklos Szeredi req->in.h.opcode = FUSE_NOTIFY_REPLY; 16092d45ba38SMiklos Szeredi req->in.h.nodeid = outarg->nodeid; 16102d45ba38SMiklos Szeredi req->in.numargs = 2; 16112d45ba38SMiklos Szeredi req->in.argpages = 1; 1612b2430d75SMaxim Patlasov req->page_descs[0].offset = offset; 16132d45ba38SMiklos Szeredi req->end = fuse_retrieve_end; 16142d45ba38SMiklos Szeredi 16152d45ba38SMiklos Szeredi index = outarg->offset >> PAGE_CACHE_SHIFT; 16162d45ba38SMiklos Szeredi 16174d53dc99SMaxim Patlasov while (num && req->num_pages < num_pages) { 16182d45ba38SMiklos Szeredi struct page *page; 16192d45ba38SMiklos Szeredi unsigned int this_num; 16202d45ba38SMiklos Szeredi 16212d45ba38SMiklos Szeredi page = find_get_page(mapping, index); 16222d45ba38SMiklos Szeredi if (!page) 16232d45ba38SMiklos Szeredi break; 16242d45ba38SMiklos Szeredi 16252d45ba38SMiklos Szeredi this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 16262d45ba38SMiklos Szeredi req->pages[req->num_pages] = page; 162785f40aecSMaxim Patlasov req->page_descs[req->num_pages].length = this_num; 16282d45ba38SMiklos Szeredi req->num_pages++; 16292d45ba38SMiklos Szeredi 1630c9e67d48SMiklos Szeredi offset = 0; 16312d45ba38SMiklos Szeredi num -= this_num; 16322d45ba38SMiklos Szeredi total_len += this_num; 163348706d0aSMiklos Szeredi index++; 16342d45ba38SMiklos Szeredi } 16352d45ba38SMiklos Szeredi req->misc.retrieve_in.offset = outarg->offset; 16362d45ba38SMiklos Szeredi req->misc.retrieve_in.size = total_len; 16372d45ba38SMiklos Szeredi req->in.args[0].size = sizeof(req->misc.retrieve_in); 16382d45ba38SMiklos Szeredi req->in.args[0].value = &req->misc.retrieve_in; 16392d45ba38SMiklos Szeredi req->in.args[1].size = total_len; 16402d45ba38SMiklos Szeredi 16412d45ba38SMiklos Szeredi err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique); 16422d45ba38SMiklos Szeredi if (err) 16432d45ba38SMiklos Szeredi fuse_retrieve_end(fc, req); 16442d45ba38SMiklos Szeredi 16452d45ba38SMiklos Szeredi return err; 16462d45ba38SMiklos Szeredi } 16472d45ba38SMiklos Szeredi 16482d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, 16492d45ba38SMiklos Szeredi struct fuse_copy_state *cs) 16502d45ba38SMiklos Szeredi { 16512d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out outarg; 16522d45ba38SMiklos Szeredi struct inode *inode; 16532d45ba38SMiklos Szeredi int err; 16542d45ba38SMiklos Szeredi 16552d45ba38SMiklos Szeredi err = -EINVAL; 16562d45ba38SMiklos Szeredi if (size != sizeof(outarg)) 16572d45ba38SMiklos Szeredi goto copy_finish; 16582d45ba38SMiklos Szeredi 16592d45ba38SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 16602d45ba38SMiklos Szeredi if (err) 16612d45ba38SMiklos Szeredi goto copy_finish; 16622d45ba38SMiklos Szeredi 16632d45ba38SMiklos Szeredi fuse_copy_finish(cs); 16642d45ba38SMiklos Szeredi 16652d45ba38SMiklos Szeredi down_read(&fc->killsb); 16662d45ba38SMiklos Szeredi err = -ENOENT; 16672d45ba38SMiklos Szeredi if (fc->sb) { 16682d45ba38SMiklos Szeredi u64 nodeid = outarg.nodeid; 16692d45ba38SMiklos Szeredi 16702d45ba38SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 16712d45ba38SMiklos Szeredi if (inode) { 16722d45ba38SMiklos Szeredi err = fuse_retrieve(fc, inode, &outarg); 16732d45ba38SMiklos Szeredi iput(inode); 16742d45ba38SMiklos Szeredi } 16752d45ba38SMiklos Szeredi } 16762d45ba38SMiklos Szeredi up_read(&fc->killsb); 16772d45ba38SMiklos Szeredi 16782d45ba38SMiklos Szeredi return err; 16792d45ba38SMiklos Szeredi 16802d45ba38SMiklos Szeredi copy_finish: 16812d45ba38SMiklos Szeredi fuse_copy_finish(cs); 16822d45ba38SMiklos Szeredi return err; 16832d45ba38SMiklos Szeredi } 16842d45ba38SMiklos Szeredi 16858599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, 16868599396bSTejun Heo unsigned int size, struct fuse_copy_state *cs) 16878599396bSTejun Heo { 16888599396bSTejun Heo switch (code) { 168995668a69STejun Heo case FUSE_NOTIFY_POLL: 169095668a69STejun Heo return fuse_notify_poll(fc, size, cs); 169195668a69STejun Heo 16923b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_INODE: 16933b463ae0SJohn Muir return fuse_notify_inval_inode(fc, size, cs); 16943b463ae0SJohn Muir 16953b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_ENTRY: 16963b463ae0SJohn Muir return fuse_notify_inval_entry(fc, size, cs); 16973b463ae0SJohn Muir 1698a1d75f25SMiklos Szeredi case FUSE_NOTIFY_STORE: 1699a1d75f25SMiklos Szeredi return fuse_notify_store(fc, size, cs); 1700a1d75f25SMiklos Szeredi 17012d45ba38SMiklos Szeredi case FUSE_NOTIFY_RETRIEVE: 17022d45ba38SMiklos Szeredi return fuse_notify_retrieve(fc, size, cs); 17032d45ba38SMiklos Szeredi 1704451d0f59SJohn Muir case FUSE_NOTIFY_DELETE: 1705451d0f59SJohn Muir return fuse_notify_delete(fc, size, cs); 1706451d0f59SJohn Muir 17078599396bSTejun Heo default: 1708f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 17098599396bSTejun Heo return -EINVAL; 17108599396bSTejun Heo } 17118599396bSTejun Heo } 17128599396bSTejun Heo 1713334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */ 1714334f485dSMiklos Szeredi static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) 1715334f485dSMiklos Szeredi { 1716334f485dSMiklos Szeredi struct list_head *entry; 1717334f485dSMiklos Szeredi 1718334f485dSMiklos Szeredi list_for_each(entry, &fc->processing) { 1719334f485dSMiklos Szeredi struct fuse_req *req; 1720334f485dSMiklos Szeredi req = list_entry(entry, struct fuse_req, list); 1721a4d27e75SMiklos Szeredi if (req->in.h.unique == unique || req->intr_unique == unique) 1722334f485dSMiklos Szeredi return req; 1723334f485dSMiklos Szeredi } 1724334f485dSMiklos Szeredi return NULL; 1725334f485dSMiklos Szeredi } 1726334f485dSMiklos Szeredi 1727334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out, 1728334f485dSMiklos Szeredi unsigned nbytes) 1729334f485dSMiklos Szeredi { 1730334f485dSMiklos Szeredi unsigned reqsize = sizeof(struct fuse_out_header); 1731334f485dSMiklos Szeredi 1732334f485dSMiklos Szeredi if (out->h.error) 1733334f485dSMiklos Szeredi return nbytes != reqsize ? -EINVAL : 0; 1734334f485dSMiklos Szeredi 1735334f485dSMiklos Szeredi reqsize += len_args(out->numargs, out->args); 1736334f485dSMiklos Szeredi 1737334f485dSMiklos Szeredi if (reqsize < nbytes || (reqsize > nbytes && !out->argvar)) 1738334f485dSMiklos Szeredi return -EINVAL; 1739334f485dSMiklos Szeredi else if (reqsize > nbytes) { 1740334f485dSMiklos Szeredi struct fuse_arg *lastarg = &out->args[out->numargs-1]; 1741334f485dSMiklos Szeredi unsigned diffsize = reqsize - nbytes; 1742334f485dSMiklos Szeredi if (diffsize > lastarg->size) 1743334f485dSMiklos Szeredi return -EINVAL; 1744334f485dSMiklos Szeredi lastarg->size -= diffsize; 1745334f485dSMiklos Szeredi } 1746334f485dSMiklos Szeredi return fuse_copy_args(cs, out->numargs, out->argpages, out->args, 1747334f485dSMiklos Szeredi out->page_zeroing); 1748334f485dSMiklos Szeredi } 1749334f485dSMiklos Szeredi 1750334f485dSMiklos Szeredi /* 1751334f485dSMiklos Szeredi * Write a single reply to a request. First the header is copied from 1752334f485dSMiklos Szeredi * the write buffer. The request is then searched on the processing 1753334f485dSMiklos Szeredi * list by the unique ID found in the header. If found, then remove 1754334f485dSMiklos Szeredi * it from the list and copy the rest of the buffer to the request. 1755334f485dSMiklos Szeredi * The request is finished by calling request_end() 1756334f485dSMiklos Szeredi */ 1757dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_conn *fc, 1758dd3bb14fSMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1759334f485dSMiklos Szeredi { 1760334f485dSMiklos Szeredi int err; 1761334f485dSMiklos Szeredi struct fuse_req *req; 1762334f485dSMiklos Szeredi struct fuse_out_header oh; 1763334f485dSMiklos Szeredi 1764334f485dSMiklos Szeredi if (nbytes < sizeof(struct fuse_out_header)) 1765334f485dSMiklos Szeredi return -EINVAL; 1766334f485dSMiklos Szeredi 1767dd3bb14fSMiklos Szeredi err = fuse_copy_one(cs, &oh, sizeof(oh)); 1768334f485dSMiklos Szeredi if (err) 1769334f485dSMiklos Szeredi goto err_finish; 17708599396bSTejun Heo 1771334f485dSMiklos Szeredi err = -EINVAL; 17728599396bSTejun Heo if (oh.len != nbytes) 17738599396bSTejun Heo goto err_finish; 17748599396bSTejun Heo 17758599396bSTejun Heo /* 17768599396bSTejun Heo * Zero oh.unique indicates unsolicited notification message 17778599396bSTejun Heo * and error contains notification code. 17788599396bSTejun Heo */ 17798599396bSTejun Heo if (!oh.unique) { 1780dd3bb14fSMiklos Szeredi err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs); 17818599396bSTejun Heo return err ? err : nbytes; 17828599396bSTejun Heo } 17838599396bSTejun Heo 17848599396bSTejun Heo err = -EINVAL; 17858599396bSTejun Heo if (oh.error <= -1000 || oh.error > 0) 1786334f485dSMiklos Szeredi goto err_finish; 1787334f485dSMiklos Szeredi 1788d7133114SMiklos Szeredi spin_lock(&fc->lock); 178969a53bf2SMiklos Szeredi err = -ENOENT; 179069a53bf2SMiklos Szeredi if (!fc->connected) 179169a53bf2SMiklos Szeredi goto err_unlock; 179269a53bf2SMiklos Szeredi 1793334f485dSMiklos Szeredi req = request_find(fc, oh.unique); 1794334f485dSMiklos Szeredi if (!req) 1795334f485dSMiklos Szeredi goto err_unlock; 1796334f485dSMiklos Szeredi 1797f9a2842eSMiklos Szeredi if (req->aborted) { 1798d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1799dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1800d7133114SMiklos Szeredi spin_lock(&fc->lock); 1801222f1d69SMiklos Szeredi request_end(fc, req); 1802334f485dSMiklos Szeredi return -ENOENT; 1803334f485dSMiklos Szeredi } 1804a4d27e75SMiklos Szeredi /* Is it an interrupt reply? */ 1805a4d27e75SMiklos Szeredi if (req->intr_unique == oh.unique) { 1806a4d27e75SMiklos Szeredi err = -EINVAL; 1807a4d27e75SMiklos Szeredi if (nbytes != sizeof(struct fuse_out_header)) 1808a4d27e75SMiklos Szeredi goto err_unlock; 1809a4d27e75SMiklos Szeredi 1810a4d27e75SMiklos Szeredi if (oh.error == -ENOSYS) 1811a4d27e75SMiklos Szeredi fc->no_interrupt = 1; 1812a4d27e75SMiklos Szeredi else if (oh.error == -EAGAIN) 1813a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 1814a4d27e75SMiklos Szeredi 1815a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 1816dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1817a4d27e75SMiklos Szeredi return nbytes; 1818a4d27e75SMiklos Szeredi } 1819a4d27e75SMiklos Szeredi 1820a4d27e75SMiklos Szeredi req->state = FUSE_REQ_WRITING; 1821d77a1d5bSMiklos Szeredi list_move(&req->list, &fc->io); 1822334f485dSMiklos Szeredi req->out.h = oh; 1823334f485dSMiklos Szeredi req->locked = 1; 1824dd3bb14fSMiklos Szeredi cs->req = req; 1825ce534fb0SMiklos Szeredi if (!req->out.page_replace) 1826ce534fb0SMiklos Szeredi cs->move_pages = 0; 1827d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1828334f485dSMiklos Szeredi 1829dd3bb14fSMiklos Szeredi err = copy_out_args(cs, &req->out, nbytes); 1830dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1831334f485dSMiklos Szeredi 1832d7133114SMiklos Szeredi spin_lock(&fc->lock); 1833334f485dSMiklos Szeredi req->locked = 0; 1834334f485dSMiklos Szeredi if (!err) { 1835f9a2842eSMiklos Szeredi if (req->aborted) 1836334f485dSMiklos Szeredi err = -ENOENT; 1837f9a2842eSMiklos Szeredi } else if (!req->aborted) 1838334f485dSMiklos Szeredi req->out.h.error = -EIO; 1839334f485dSMiklos Szeredi request_end(fc, req); 1840334f485dSMiklos Szeredi 1841334f485dSMiklos Szeredi return err ? err : nbytes; 1842334f485dSMiklos Szeredi 1843334f485dSMiklos Szeredi err_unlock: 1844d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1845334f485dSMiklos Szeredi err_finish: 1846dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1847334f485dSMiklos Szeredi return err; 1848334f485dSMiklos Szeredi } 1849334f485dSMiklos Szeredi 1850dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, 1851dd3bb14fSMiklos Szeredi unsigned long nr_segs, loff_t pos) 1852dd3bb14fSMiklos Szeredi { 1853dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1854dd3bb14fSMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp); 1855dd3bb14fSMiklos Szeredi if (!fc) 1856dd3bb14fSMiklos Szeredi return -EPERM; 1857dd3bb14fSMiklos Szeredi 1858c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 0, iov, nr_segs); 1859dd3bb14fSMiklos Szeredi 1860dd3bb14fSMiklos Szeredi return fuse_dev_do_write(fc, &cs, iov_length(iov, nr_segs)); 1861dd3bb14fSMiklos Szeredi } 1862dd3bb14fSMiklos Szeredi 1863dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, 1864dd3bb14fSMiklos Szeredi struct file *out, loff_t *ppos, 1865dd3bb14fSMiklos Szeredi size_t len, unsigned int flags) 1866dd3bb14fSMiklos Szeredi { 1867dd3bb14fSMiklos Szeredi unsigned nbuf; 1868dd3bb14fSMiklos Szeredi unsigned idx; 1869dd3bb14fSMiklos Szeredi struct pipe_buffer *bufs; 1870dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1871dd3bb14fSMiklos Szeredi struct fuse_conn *fc; 1872dd3bb14fSMiklos Szeredi size_t rem; 1873dd3bb14fSMiklos Szeredi ssize_t ret; 1874dd3bb14fSMiklos Szeredi 1875dd3bb14fSMiklos Szeredi fc = fuse_get_conn(out); 1876dd3bb14fSMiklos Szeredi if (!fc) 1877dd3bb14fSMiklos Szeredi return -EPERM; 1878dd3bb14fSMiklos Szeredi 1879dd3bb14fSMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1880dd3bb14fSMiklos Szeredi if (!bufs) 1881dd3bb14fSMiklos Szeredi return -ENOMEM; 1882dd3bb14fSMiklos Szeredi 1883dd3bb14fSMiklos Szeredi pipe_lock(pipe); 1884dd3bb14fSMiklos Szeredi nbuf = 0; 1885dd3bb14fSMiklos Szeredi rem = 0; 1886dd3bb14fSMiklos Szeredi for (idx = 0; idx < pipe->nrbufs && rem < len; idx++) 1887dd3bb14fSMiklos Szeredi rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len; 1888dd3bb14fSMiklos Szeredi 1889dd3bb14fSMiklos Szeredi ret = -EINVAL; 1890dd3bb14fSMiklos Szeredi if (rem < len) { 1891dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 1892dd3bb14fSMiklos Szeredi goto out; 1893dd3bb14fSMiklos Szeredi } 1894dd3bb14fSMiklos Szeredi 1895dd3bb14fSMiklos Szeredi rem = len; 1896dd3bb14fSMiklos Szeredi while (rem) { 1897dd3bb14fSMiklos Szeredi struct pipe_buffer *ibuf; 1898dd3bb14fSMiklos Szeredi struct pipe_buffer *obuf; 1899dd3bb14fSMiklos Szeredi 1900dd3bb14fSMiklos Szeredi BUG_ON(nbuf >= pipe->buffers); 1901dd3bb14fSMiklos Szeredi BUG_ON(!pipe->nrbufs); 1902dd3bb14fSMiklos Szeredi ibuf = &pipe->bufs[pipe->curbuf]; 1903dd3bb14fSMiklos Szeredi obuf = &bufs[nbuf]; 1904dd3bb14fSMiklos Szeredi 1905dd3bb14fSMiklos Szeredi if (rem >= ibuf->len) { 1906dd3bb14fSMiklos Szeredi *obuf = *ibuf; 1907dd3bb14fSMiklos Szeredi ibuf->ops = NULL; 1908dd3bb14fSMiklos Szeredi pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); 1909dd3bb14fSMiklos Szeredi pipe->nrbufs--; 1910dd3bb14fSMiklos Szeredi } else { 1911dd3bb14fSMiklos Szeredi ibuf->ops->get(pipe, ibuf); 1912dd3bb14fSMiklos Szeredi *obuf = *ibuf; 1913dd3bb14fSMiklos Szeredi obuf->flags &= ~PIPE_BUF_FLAG_GIFT; 1914dd3bb14fSMiklos Szeredi obuf->len = rem; 1915dd3bb14fSMiklos Szeredi ibuf->offset += obuf->len; 1916dd3bb14fSMiklos Szeredi ibuf->len -= obuf->len; 1917dd3bb14fSMiklos Szeredi } 1918dd3bb14fSMiklos Szeredi nbuf++; 1919dd3bb14fSMiklos Szeredi rem -= obuf->len; 1920dd3bb14fSMiklos Szeredi } 1921dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 1922dd3bb14fSMiklos Szeredi 1923c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 0, NULL, nbuf); 1924dd3bb14fSMiklos Szeredi cs.pipebufs = bufs; 1925dd3bb14fSMiklos Szeredi cs.pipe = pipe; 1926dd3bb14fSMiklos Szeredi 1927ce534fb0SMiklos Szeredi if (flags & SPLICE_F_MOVE) 1928ce534fb0SMiklos Szeredi cs.move_pages = 1; 1929ce534fb0SMiklos Szeredi 1930dd3bb14fSMiklos Szeredi ret = fuse_dev_do_write(fc, &cs, len); 1931dd3bb14fSMiklos Szeredi 1932dd3bb14fSMiklos Szeredi for (idx = 0; idx < nbuf; idx++) { 1933dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = &bufs[idx]; 1934dd3bb14fSMiklos Szeredi buf->ops->release(pipe, buf); 1935dd3bb14fSMiklos Szeredi } 1936dd3bb14fSMiklos Szeredi out: 1937dd3bb14fSMiklos Szeredi kfree(bufs); 1938dd3bb14fSMiklos Szeredi return ret; 1939dd3bb14fSMiklos Szeredi } 1940dd3bb14fSMiklos Szeredi 1941334f485dSMiklos Szeredi static unsigned fuse_dev_poll(struct file *file, poll_table *wait) 1942334f485dSMiklos Szeredi { 1943334f485dSMiklos Szeredi unsigned mask = POLLOUT | POLLWRNORM; 19447025d9adSMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 1945334f485dSMiklos Szeredi if (!fc) 19467025d9adSMiklos Szeredi return POLLERR; 1947334f485dSMiklos Szeredi 1948334f485dSMiklos Szeredi poll_wait(file, &fc->waitq, wait); 1949334f485dSMiklos Szeredi 1950d7133114SMiklos Szeredi spin_lock(&fc->lock); 19517025d9adSMiklos Szeredi if (!fc->connected) 19527025d9adSMiklos Szeredi mask = POLLERR; 1953a4d27e75SMiklos Szeredi else if (request_pending(fc)) 1954334f485dSMiklos Szeredi mask |= POLLIN | POLLRDNORM; 1955d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1956334f485dSMiklos Szeredi 1957334f485dSMiklos Szeredi return mask; 1958334f485dSMiklos Szeredi } 1959334f485dSMiklos Szeredi 196069a53bf2SMiklos Szeredi /* 196169a53bf2SMiklos Szeredi * Abort all requests on the given list (pending or processing) 196269a53bf2SMiklos Szeredi * 1963d7133114SMiklos Szeredi * This function releases and reacquires fc->lock 196469a53bf2SMiklos Szeredi */ 1965334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head) 1966b9ca67b2SMiklos Szeredi __releases(fc->lock) 1967b9ca67b2SMiklos Szeredi __acquires(fc->lock) 1968334f485dSMiklos Szeredi { 1969334f485dSMiklos Szeredi while (!list_empty(head)) { 1970334f485dSMiklos Szeredi struct fuse_req *req; 1971334f485dSMiklos Szeredi req = list_entry(head->next, struct fuse_req, list); 1972334f485dSMiklos Szeredi req->out.h.error = -ECONNABORTED; 1973334f485dSMiklos Szeredi request_end(fc, req); 1974d7133114SMiklos Szeredi spin_lock(&fc->lock); 1975334f485dSMiklos Szeredi } 1976334f485dSMiklos Szeredi } 1977334f485dSMiklos Szeredi 197869a53bf2SMiklos Szeredi /* 197969a53bf2SMiklos Szeredi * Abort requests under I/O 198069a53bf2SMiklos Szeredi * 1981f9a2842eSMiklos Szeredi * The requests are set to aborted and finished, and the request 198269a53bf2SMiklos Szeredi * waiter is woken up. This will make request_wait_answer() wait 198369a53bf2SMiklos Szeredi * until the request is unlocked and then return. 198464c6d8edSMiklos Szeredi * 198564c6d8edSMiklos Szeredi * If the request is asynchronous, then the end function needs to be 198664c6d8edSMiklos Szeredi * called after waiting for the request to be unlocked (if it was 198764c6d8edSMiklos Szeredi * locked). 198869a53bf2SMiklos Szeredi */ 198969a53bf2SMiklos Szeredi static void end_io_requests(struct fuse_conn *fc) 1990b9ca67b2SMiklos Szeredi __releases(fc->lock) 1991b9ca67b2SMiklos Szeredi __acquires(fc->lock) 199269a53bf2SMiklos Szeredi { 199369a53bf2SMiklos Szeredi while (!list_empty(&fc->io)) { 199464c6d8edSMiklos Szeredi struct fuse_req *req = 199564c6d8edSMiklos Szeredi list_entry(fc->io.next, struct fuse_req, list); 199664c6d8edSMiklos Szeredi void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; 199764c6d8edSMiklos Szeredi 1998f9a2842eSMiklos Szeredi req->aborted = 1; 199969a53bf2SMiklos Szeredi req->out.h.error = -ECONNABORTED; 200069a53bf2SMiklos Szeredi req->state = FUSE_REQ_FINISHED; 200169a53bf2SMiklos Szeredi list_del_init(&req->list); 200269a53bf2SMiklos Szeredi wake_up(&req->waitq); 200364c6d8edSMiklos Szeredi if (end) { 200464c6d8edSMiklos Szeredi req->end = NULL; 200564c6d8edSMiklos Szeredi __fuse_get_request(req); 2006d7133114SMiklos Szeredi spin_unlock(&fc->lock); 200764c6d8edSMiklos Szeredi wait_event(req->waitq, !req->locked); 200864c6d8edSMiklos Szeredi end(fc, req); 2009e9bb09ddSTejun Heo fuse_put_request(fc, req); 2010d7133114SMiklos Szeredi spin_lock(&fc->lock); 201164c6d8edSMiklos Szeredi } 201269a53bf2SMiklos Szeredi } 201369a53bf2SMiklos Szeredi } 201469a53bf2SMiklos Szeredi 2015595afaf9SMiklos Szeredi static void end_queued_requests(struct fuse_conn *fc) 2016b9ca67b2SMiklos Szeredi __releases(fc->lock) 2017b9ca67b2SMiklos Szeredi __acquires(fc->lock) 2018595afaf9SMiklos Szeredi { 2019595afaf9SMiklos Szeredi fc->max_background = UINT_MAX; 2020595afaf9SMiklos Szeredi flush_bg_queue(fc); 2021595afaf9SMiklos Szeredi end_requests(fc, &fc->pending); 2022595afaf9SMiklos Szeredi end_requests(fc, &fc->processing); 202307e77dcaSMiklos Szeredi while (forget_pending(fc)) 202402c048b9SMiklos Szeredi kfree(dequeue_forget(fc, 1, NULL)); 2025595afaf9SMiklos Szeredi } 2026595afaf9SMiklos Szeredi 2027357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc) 2028357ccf2bSBryan Green { 2029357ccf2bSBryan Green struct rb_node *p; 2030357ccf2bSBryan Green 2031357ccf2bSBryan Green p = rb_first(&fc->polled_files); 2032357ccf2bSBryan Green 2033357ccf2bSBryan Green while (p) { 2034357ccf2bSBryan Green struct fuse_file *ff; 2035357ccf2bSBryan Green ff = rb_entry(p, struct fuse_file, polled_node); 2036357ccf2bSBryan Green wake_up_interruptible_all(&ff->poll_wait); 2037357ccf2bSBryan Green 2038357ccf2bSBryan Green p = rb_next(p); 2039357ccf2bSBryan Green } 2040357ccf2bSBryan Green } 2041357ccf2bSBryan Green 204269a53bf2SMiklos Szeredi /* 204369a53bf2SMiklos Szeredi * Abort all requests. 204469a53bf2SMiklos Szeredi * 204569a53bf2SMiklos Szeredi * Emergency exit in case of a malicious or accidental deadlock, or 204669a53bf2SMiklos Szeredi * just a hung filesystem. 204769a53bf2SMiklos Szeredi * 204869a53bf2SMiklos Szeredi * The same effect is usually achievable through killing the 204969a53bf2SMiklos Szeredi * filesystem daemon and all users of the filesystem. The exception 205069a53bf2SMiklos Szeredi * is the combination of an asynchronous request and the tricky 205169a53bf2SMiklos Szeredi * deadlock (see Documentation/filesystems/fuse.txt). 205269a53bf2SMiklos Szeredi * 205369a53bf2SMiklos Szeredi * During the aborting, progression of requests from the pending and 205469a53bf2SMiklos Szeredi * processing lists onto the io list, and progression of new requests 205569a53bf2SMiklos Szeredi * onto the pending list is prevented by req->connected being false. 205669a53bf2SMiklos Szeredi * 205769a53bf2SMiklos Szeredi * Progression of requests under I/O to the processing list is 2058f9a2842eSMiklos Szeredi * prevented by the req->aborted flag being true for these requests. 2059f9a2842eSMiklos Szeredi * For this reason requests on the io list must be aborted first. 206069a53bf2SMiklos Szeredi */ 206169a53bf2SMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc) 206269a53bf2SMiklos Szeredi { 2063d7133114SMiklos Szeredi spin_lock(&fc->lock); 206469a53bf2SMiklos Szeredi if (fc->connected) { 206569a53bf2SMiklos Szeredi fc->connected = 0; 206651eb01e7SMiklos Szeredi fc->blocked = 0; 206769a53bf2SMiklos Szeredi end_io_requests(fc); 2068595afaf9SMiklos Szeredi end_queued_requests(fc); 2069357ccf2bSBryan Green end_polls(fc); 207069a53bf2SMiklos Szeredi wake_up_all(&fc->waitq); 207151eb01e7SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 2072385a17bfSJeff Dike kill_fasync(&fc->fasync, SIGIO, POLL_IN); 207369a53bf2SMiklos Szeredi } 2074d7133114SMiklos Szeredi spin_unlock(&fc->lock); 207569a53bf2SMiklos Szeredi } 207608cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn); 207769a53bf2SMiklos Szeredi 207808cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file) 2079334f485dSMiklos Szeredi { 20800720b315SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 2081334f485dSMiklos Szeredi if (fc) { 2082d7133114SMiklos Szeredi spin_lock(&fc->lock); 20831e9a4ed9SMiklos Szeredi fc->connected = 0; 2084595afaf9SMiklos Szeredi fc->blocked = 0; 2085595afaf9SMiklos Szeredi end_queued_requests(fc); 2086357ccf2bSBryan Green end_polls(fc); 2087595afaf9SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 2088d7133114SMiklos Szeredi spin_unlock(&fc->lock); 2089bafa9654SMiklos Szeredi fuse_conn_put(fc); 2090385a17bfSJeff Dike } 2091f543f253SMiklos Szeredi 2092334f485dSMiklos Szeredi return 0; 2093334f485dSMiklos Szeredi } 209408cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release); 2095334f485dSMiklos Szeredi 2096385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on) 2097385a17bfSJeff Dike { 2098385a17bfSJeff Dike struct fuse_conn *fc = fuse_get_conn(file); 2099385a17bfSJeff Dike if (!fc) 2100a87046d8SMiklos Szeredi return -EPERM; 2101385a17bfSJeff Dike 2102385a17bfSJeff Dike /* No locking - fasync_helper does its own locking */ 2103385a17bfSJeff Dike return fasync_helper(fd, file, on, &fc->fasync); 2104385a17bfSJeff Dike } 2105385a17bfSJeff Dike 21064b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = { 2107334f485dSMiklos Szeredi .owner = THIS_MODULE, 2108334f485dSMiklos Szeredi .llseek = no_llseek, 2109ee0b3e67SBadari Pulavarty .read = do_sync_read, 2110ee0b3e67SBadari Pulavarty .aio_read = fuse_dev_read, 2111c3021629SMiklos Szeredi .splice_read = fuse_dev_splice_read, 2112ee0b3e67SBadari Pulavarty .write = do_sync_write, 2113ee0b3e67SBadari Pulavarty .aio_write = fuse_dev_write, 2114dd3bb14fSMiklos Szeredi .splice_write = fuse_dev_splice_write, 2115334f485dSMiklos Szeredi .poll = fuse_dev_poll, 2116334f485dSMiklos Szeredi .release = fuse_dev_release, 2117385a17bfSJeff Dike .fasync = fuse_dev_fasync, 2118334f485dSMiklos Szeredi }; 211908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations); 2120334f485dSMiklos Szeredi 2121334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = { 2122334f485dSMiklos Szeredi .minor = FUSE_MINOR, 2123334f485dSMiklos Szeredi .name = "fuse", 2124334f485dSMiklos Szeredi .fops = &fuse_dev_operations, 2125334f485dSMiklos Szeredi }; 2126334f485dSMiklos Szeredi 2127334f485dSMiklos Szeredi int __init fuse_dev_init(void) 2128334f485dSMiklos Szeredi { 2129334f485dSMiklos Szeredi int err = -ENOMEM; 2130334f485dSMiklos Szeredi fuse_req_cachep = kmem_cache_create("fuse_request", 2131334f485dSMiklos Szeredi sizeof(struct fuse_req), 213220c2df83SPaul Mundt 0, 0, NULL); 2133334f485dSMiklos Szeredi if (!fuse_req_cachep) 2134334f485dSMiklos Szeredi goto out; 2135334f485dSMiklos Szeredi 2136334f485dSMiklos Szeredi err = misc_register(&fuse_miscdevice); 2137334f485dSMiklos Szeredi if (err) 2138334f485dSMiklos Szeredi goto out_cache_clean; 2139334f485dSMiklos Szeredi 2140334f485dSMiklos Szeredi return 0; 2141334f485dSMiklos Szeredi 2142334f485dSMiklos Szeredi out_cache_clean: 2143334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2144334f485dSMiklos Szeredi out: 2145334f485dSMiklos Szeredi return err; 2146334f485dSMiklos Szeredi } 2147334f485dSMiklos Szeredi 2148334f485dSMiklos Szeredi void fuse_dev_cleanup(void) 2149334f485dSMiklos Szeredi { 2150334f485dSMiklos Szeredi misc_deregister(&fuse_miscdevice); 2151334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2152334f485dSMiklos Szeredi } 2153