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 4436a4e922cSEric Wong static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 444334f485dSMiklos Szeredi { 445d7133114SMiklos Szeredi spin_lock(&fc->lock); 4461e9a4ed9SMiklos Szeredi if (!fc->connected) 447334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 448334f485dSMiklos Szeredi else if (fc->conn_error) 449334f485dSMiklos Szeredi req->out.h.error = -ECONNREFUSED; 450334f485dSMiklos Szeredi else { 4512d45ba38SMiklos Szeredi req->in.h.unique = fuse_get_unique(fc); 452334f485dSMiklos Szeredi queue_request(fc, req); 453334f485dSMiklos Szeredi /* acquire extra reference, since request is still needed 454334f485dSMiklos Szeredi after request_end() */ 455334f485dSMiklos Szeredi __fuse_get_request(req); 456334f485dSMiklos Szeredi 4577c352bdfSMiklos Szeredi request_wait_answer(fc, req); 458334f485dSMiklos Szeredi } 459d7133114SMiklos Szeredi spin_unlock(&fc->lock); 460334f485dSMiklos Szeredi } 4616a4e922cSEric Wong 4626a4e922cSEric Wong void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 4636a4e922cSEric Wong { 4646a4e922cSEric Wong req->isreply = 1; 4656a4e922cSEric Wong __fuse_request_send(fc, req); 4666a4e922cSEric Wong } 46708cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send); 468334f485dSMiklos Szeredi 469b93f858aSTejun Heo static void fuse_request_send_nowait_locked(struct fuse_conn *fc, 470d12def1bSMiklos Szeredi struct fuse_req *req) 471334f485dSMiklos Szeredi { 47251eb01e7SMiklos Szeredi req->background = 1; 47351eb01e7SMiklos Szeredi fc->num_background++; 4747a6d3c8bSCsaba Henk if (fc->num_background == fc->max_background) 47551eb01e7SMiklos Szeredi fc->blocked = 1; 4767a6d3c8bSCsaba Henk if (fc->num_background == fc->congestion_threshold && 477a325f9b9STejun Heo fc->bdi_initialized) { 4788aa7e847SJens Axboe set_bdi_congested(&fc->bdi, BLK_RW_SYNC); 4798aa7e847SJens Axboe set_bdi_congested(&fc->bdi, BLK_RW_ASYNC); 480f92b99b9SMiklos Szeredi } 481d12def1bSMiklos Szeredi list_add_tail(&req->list, &fc->bg_queue); 482d12def1bSMiklos Szeredi flush_bg_queue(fc); 483d12def1bSMiklos Szeredi } 48451eb01e7SMiklos Szeredi 485b93f858aSTejun Heo static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) 486d12def1bSMiklos Szeredi { 487d12def1bSMiklos Szeredi spin_lock(&fc->lock); 488d12def1bSMiklos Szeredi if (fc->connected) { 489b93f858aSTejun Heo fuse_request_send_nowait_locked(fc, req); 490d7133114SMiklos Szeredi spin_unlock(&fc->lock); 491334f485dSMiklos Szeredi } else { 492334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 493334f485dSMiklos Szeredi request_end(fc, req); 494334f485dSMiklos Szeredi } 495334f485dSMiklos Szeredi } 496334f485dSMiklos Szeredi 497b93f858aSTejun Heo void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) 498334f485dSMiklos Szeredi { 499334f485dSMiklos Szeredi req->isreply = 1; 500b93f858aSTejun Heo fuse_request_send_nowait(fc, req); 501334f485dSMiklos Szeredi } 50208cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send_background); 503334f485dSMiklos Szeredi 5042d45ba38SMiklos Szeredi static int fuse_request_send_notify_reply(struct fuse_conn *fc, 5052d45ba38SMiklos Szeredi struct fuse_req *req, u64 unique) 5062d45ba38SMiklos Szeredi { 5072d45ba38SMiklos Szeredi int err = -ENODEV; 5082d45ba38SMiklos Szeredi 5092d45ba38SMiklos Szeredi req->isreply = 0; 5102d45ba38SMiklos Szeredi req->in.h.unique = unique; 5112d45ba38SMiklos Szeredi spin_lock(&fc->lock); 5122d45ba38SMiklos Szeredi if (fc->connected) { 5132d45ba38SMiklos Szeredi queue_request(fc, req); 5142d45ba38SMiklos Szeredi err = 0; 5152d45ba38SMiklos Szeredi } 5162d45ba38SMiklos Szeredi spin_unlock(&fc->lock); 5172d45ba38SMiklos Szeredi 5182d45ba38SMiklos Szeredi return err; 5192d45ba38SMiklos Szeredi } 5202d45ba38SMiklos Szeredi 521334f485dSMiklos Szeredi /* 5223be5a52bSMiklos Szeredi * Called under fc->lock 5233be5a52bSMiklos Szeredi * 5243be5a52bSMiklos Szeredi * fc->connected must have been checked previously 5253be5a52bSMiklos Szeredi */ 526b93f858aSTejun Heo void fuse_request_send_background_locked(struct fuse_conn *fc, 527b93f858aSTejun Heo struct fuse_req *req) 5283be5a52bSMiklos Szeredi { 5293be5a52bSMiklos Szeredi req->isreply = 1; 530b93f858aSTejun Heo fuse_request_send_nowait_locked(fc, req); 5313be5a52bSMiklos Szeredi } 5323be5a52bSMiklos Szeredi 5330b05b183SAnand V. Avati void fuse_force_forget(struct file *file, u64 nodeid) 5340b05b183SAnand V. Avati { 5356131ffaaSAl Viro struct inode *inode = file_inode(file); 5360b05b183SAnand V. Avati struct fuse_conn *fc = get_fuse_conn(inode); 5370b05b183SAnand V. Avati struct fuse_req *req; 5380b05b183SAnand V. Avati struct fuse_forget_in inarg; 5390b05b183SAnand V. Avati 5400b05b183SAnand V. Avati memset(&inarg, 0, sizeof(inarg)); 5410b05b183SAnand V. Avati inarg.nlookup = 1; 542b111c8c0SMaxim Patlasov req = fuse_get_req_nofail_nopages(fc, file); 5430b05b183SAnand V. Avati req->in.h.opcode = FUSE_FORGET; 5440b05b183SAnand V. Avati req->in.h.nodeid = nodeid; 5450b05b183SAnand V. Avati req->in.numargs = 1; 5460b05b183SAnand V. Avati req->in.args[0].size = sizeof(inarg); 5470b05b183SAnand V. Avati req->in.args[0].value = &inarg; 5480b05b183SAnand V. Avati req->isreply = 0; 5496a4e922cSEric Wong __fuse_request_send(fc, req); 5506a4e922cSEric Wong /* ignore errors */ 5516a4e922cSEric Wong fuse_put_request(fc, req); 5520b05b183SAnand V. Avati } 5530b05b183SAnand V. Avati 5543be5a52bSMiklos Szeredi /* 555334f485dSMiklos Szeredi * Lock the request. Up to the next unlock_request() there mustn't be 556334f485dSMiklos Szeredi * anything that could cause a page-fault. If the request was already 557f9a2842eSMiklos Szeredi * aborted bail out. 558334f485dSMiklos Szeredi */ 559d7133114SMiklos Szeredi static int lock_request(struct fuse_conn *fc, struct fuse_req *req) 560334f485dSMiklos Szeredi { 561334f485dSMiklos Szeredi int err = 0; 562334f485dSMiklos Szeredi if (req) { 563d7133114SMiklos Szeredi spin_lock(&fc->lock); 564f9a2842eSMiklos Szeredi if (req->aborted) 565334f485dSMiklos Szeredi err = -ENOENT; 566334f485dSMiklos Szeredi else 567334f485dSMiklos Szeredi req->locked = 1; 568d7133114SMiklos Szeredi spin_unlock(&fc->lock); 569334f485dSMiklos Szeredi } 570334f485dSMiklos Szeredi return err; 571334f485dSMiklos Szeredi } 572334f485dSMiklos Szeredi 573334f485dSMiklos Szeredi /* 574f9a2842eSMiklos Szeredi * Unlock request. If it was aborted during being locked, the 575334f485dSMiklos Szeredi * requester thread is currently waiting for it to be unlocked, so 576334f485dSMiklos Szeredi * wake it up. 577334f485dSMiklos Szeredi */ 578d7133114SMiklos Szeredi static void unlock_request(struct fuse_conn *fc, struct fuse_req *req) 579334f485dSMiklos Szeredi { 580334f485dSMiklos Szeredi if (req) { 581d7133114SMiklos Szeredi spin_lock(&fc->lock); 582334f485dSMiklos Szeredi req->locked = 0; 583f9a2842eSMiklos Szeredi if (req->aborted) 584334f485dSMiklos Szeredi wake_up(&req->waitq); 585d7133114SMiklos Szeredi spin_unlock(&fc->lock); 586334f485dSMiklos Szeredi } 587334f485dSMiklos Szeredi } 588334f485dSMiklos Szeredi 589334f485dSMiklos Szeredi struct fuse_copy_state { 590d7133114SMiklos Szeredi struct fuse_conn *fc; 591334f485dSMiklos Szeredi int write; 592334f485dSMiklos Szeredi struct fuse_req *req; 593334f485dSMiklos Szeredi const struct iovec *iov; 594dd3bb14fSMiklos Szeredi struct pipe_buffer *pipebufs; 595dd3bb14fSMiklos Szeredi struct pipe_buffer *currbuf; 596dd3bb14fSMiklos Szeredi struct pipe_inode_info *pipe; 597334f485dSMiklos Szeredi unsigned long nr_segs; 598334f485dSMiklos Szeredi unsigned long seglen; 599334f485dSMiklos Szeredi unsigned long addr; 600334f485dSMiklos Szeredi struct page *pg; 601334f485dSMiklos Szeredi void *mapaddr; 602334f485dSMiklos Szeredi void *buf; 603334f485dSMiklos Szeredi unsigned len; 604ce534fb0SMiklos Szeredi unsigned move_pages:1; 605334f485dSMiklos Szeredi }; 606334f485dSMiklos Szeredi 607d7133114SMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc, 608c3021629SMiklos Szeredi int write, 609d7133114SMiklos Szeredi const struct iovec *iov, unsigned long nr_segs) 610334f485dSMiklos Szeredi { 611334f485dSMiklos Szeredi memset(cs, 0, sizeof(*cs)); 612d7133114SMiklos Szeredi cs->fc = fc; 613334f485dSMiklos Szeredi cs->write = write; 614334f485dSMiklos Szeredi cs->iov = iov; 615334f485dSMiklos Szeredi cs->nr_segs = nr_segs; 616334f485dSMiklos Szeredi } 617334f485dSMiklos Szeredi 618334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */ 6198bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs) 620334f485dSMiklos Szeredi { 621dd3bb14fSMiklos Szeredi if (cs->currbuf) { 622dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->currbuf; 623dd3bb14fSMiklos Szeredi 624c3021629SMiklos Szeredi if (!cs->write) { 625dd3bb14fSMiklos Szeredi buf->ops->unmap(cs->pipe, buf, cs->mapaddr); 626c3021629SMiklos Szeredi } else { 6277909b1c6SMiklos Szeredi kunmap(buf->page); 628c3021629SMiklos Szeredi buf->len = PAGE_SIZE - cs->len; 629c3021629SMiklos Szeredi } 630dd3bb14fSMiklos Szeredi cs->currbuf = NULL; 631dd3bb14fSMiklos Szeredi cs->mapaddr = NULL; 632dd3bb14fSMiklos Szeredi } else if (cs->mapaddr) { 6337909b1c6SMiklos Szeredi kunmap(cs->pg); 634334f485dSMiklos Szeredi if (cs->write) { 635334f485dSMiklos Szeredi flush_dcache_page(cs->pg); 636334f485dSMiklos Szeredi set_page_dirty_lock(cs->pg); 637334f485dSMiklos Szeredi } 638334f485dSMiklos Szeredi put_page(cs->pg); 639334f485dSMiklos Szeredi cs->mapaddr = NULL; 640334f485dSMiklos Szeredi } 641334f485dSMiklos Szeredi } 642334f485dSMiklos Szeredi 643334f485dSMiklos Szeredi /* 644334f485dSMiklos Szeredi * Get another pagefull of userspace buffer, and map it to kernel 645334f485dSMiklos Szeredi * address space, and lock request 646334f485dSMiklos Szeredi */ 647334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs) 648334f485dSMiklos Szeredi { 649334f485dSMiklos Szeredi unsigned long offset; 650334f485dSMiklos Szeredi int err; 651334f485dSMiklos Szeredi 652d7133114SMiklos Szeredi unlock_request(cs->fc, cs->req); 653334f485dSMiklos Szeredi fuse_copy_finish(cs); 654dd3bb14fSMiklos Szeredi if (cs->pipebufs) { 655dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 656dd3bb14fSMiklos Szeredi 657c3021629SMiklos Szeredi if (!cs->write) { 658dd3bb14fSMiklos Szeredi err = buf->ops->confirm(cs->pipe, buf); 659dd3bb14fSMiklos Szeredi if (err) 660dd3bb14fSMiklos Szeredi return err; 661dd3bb14fSMiklos Szeredi 662dd3bb14fSMiklos Szeredi BUG_ON(!cs->nr_segs); 663dd3bb14fSMiklos Szeredi cs->currbuf = buf; 6647909b1c6SMiklos Szeredi cs->mapaddr = buf->ops->map(cs->pipe, buf, 0); 665dd3bb14fSMiklos Szeredi cs->len = buf->len; 666dd3bb14fSMiklos Szeredi cs->buf = cs->mapaddr + buf->offset; 667dd3bb14fSMiklos Szeredi cs->pipebufs++; 668dd3bb14fSMiklos Szeredi cs->nr_segs--; 669dd3bb14fSMiklos Szeredi } else { 670c3021629SMiklos Szeredi struct page *page; 671c3021629SMiklos Szeredi 672c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 673c3021629SMiklos Szeredi return -EIO; 674c3021629SMiklos Szeredi 675c3021629SMiklos Szeredi page = alloc_page(GFP_HIGHUSER); 676c3021629SMiklos Szeredi if (!page) 677c3021629SMiklos Szeredi return -ENOMEM; 678c3021629SMiklos Szeredi 679c3021629SMiklos Szeredi buf->page = page; 680c3021629SMiklos Szeredi buf->offset = 0; 681c3021629SMiklos Szeredi buf->len = 0; 682c3021629SMiklos Szeredi 683c3021629SMiklos Szeredi cs->currbuf = buf; 6847909b1c6SMiklos Szeredi cs->mapaddr = kmap(page); 685c3021629SMiklos Szeredi cs->buf = cs->mapaddr; 686c3021629SMiklos Szeredi cs->len = PAGE_SIZE; 687c3021629SMiklos Szeredi cs->pipebufs++; 688c3021629SMiklos Szeredi cs->nr_segs++; 689c3021629SMiklos Szeredi } 690c3021629SMiklos Szeredi } else { 691334f485dSMiklos Szeredi if (!cs->seglen) { 692334f485dSMiklos Szeredi BUG_ON(!cs->nr_segs); 693334f485dSMiklos Szeredi cs->seglen = cs->iov[0].iov_len; 694334f485dSMiklos Szeredi cs->addr = (unsigned long) cs->iov[0].iov_base; 695334f485dSMiklos Szeredi cs->iov++; 696334f485dSMiklos Szeredi cs->nr_segs--; 697334f485dSMiklos Szeredi } 6981bf94ca7SMiklos Szeredi err = get_user_pages_fast(cs->addr, 1, cs->write, &cs->pg); 699334f485dSMiklos Szeredi if (err < 0) 700334f485dSMiklos Szeredi return err; 701334f485dSMiklos Szeredi BUG_ON(err != 1); 702334f485dSMiklos Szeredi offset = cs->addr % PAGE_SIZE; 7037909b1c6SMiklos Szeredi cs->mapaddr = kmap(cs->pg); 704334f485dSMiklos Szeredi cs->buf = cs->mapaddr + offset; 705334f485dSMiklos Szeredi cs->len = min(PAGE_SIZE - offset, cs->seglen); 706334f485dSMiklos Szeredi cs->seglen -= cs->len; 707334f485dSMiklos Szeredi cs->addr += cs->len; 708dd3bb14fSMiklos Szeredi } 709334f485dSMiklos Szeredi 710d7133114SMiklos Szeredi return lock_request(cs->fc, cs->req); 711334f485dSMiklos Szeredi } 712334f485dSMiklos Szeredi 713334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */ 7148bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size) 715334f485dSMiklos Szeredi { 716334f485dSMiklos Szeredi unsigned ncpy = min(*size, cs->len); 717334f485dSMiklos Szeredi if (val) { 718334f485dSMiklos Szeredi if (cs->write) 719334f485dSMiklos Szeredi memcpy(cs->buf, *val, ncpy); 720334f485dSMiklos Szeredi else 721334f485dSMiklos Szeredi memcpy(*val, cs->buf, ncpy); 722334f485dSMiklos Szeredi *val += ncpy; 723334f485dSMiklos Szeredi } 724334f485dSMiklos Szeredi *size -= ncpy; 725334f485dSMiklos Szeredi cs->len -= ncpy; 726334f485dSMiklos Szeredi cs->buf += ncpy; 727334f485dSMiklos Szeredi return ncpy; 728334f485dSMiklos Szeredi } 729334f485dSMiklos Szeredi 730ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page) 731ce534fb0SMiklos Szeredi { 732ce534fb0SMiklos Szeredi if (page_mapcount(page) || 733ce534fb0SMiklos Szeredi page->mapping != NULL || 734ce534fb0SMiklos Szeredi page_count(page) != 1 || 735ce534fb0SMiklos Szeredi (page->flags & PAGE_FLAGS_CHECK_AT_PREP & 736ce534fb0SMiklos Szeredi ~(1 << PG_locked | 737ce534fb0SMiklos Szeredi 1 << PG_referenced | 738ce534fb0SMiklos Szeredi 1 << PG_uptodate | 739ce534fb0SMiklos Szeredi 1 << PG_lru | 740ce534fb0SMiklos Szeredi 1 << PG_active | 741ce534fb0SMiklos Szeredi 1 << PG_reclaim))) { 742ce534fb0SMiklos Szeredi printk(KERN_WARNING "fuse: trying to steal weird page\n"); 743ce534fb0SMiklos 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); 744ce534fb0SMiklos Szeredi return 1; 745ce534fb0SMiklos Szeredi } 746ce534fb0SMiklos Szeredi return 0; 747ce534fb0SMiklos Szeredi } 748ce534fb0SMiklos Szeredi 749ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) 750ce534fb0SMiklos Szeredi { 751ce534fb0SMiklos Szeredi int err; 752ce534fb0SMiklos Szeredi struct page *oldpage = *pagep; 753ce534fb0SMiklos Szeredi struct page *newpage; 754ce534fb0SMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 755ce534fb0SMiklos Szeredi 756ce534fb0SMiklos Szeredi unlock_request(cs->fc, cs->req); 757ce534fb0SMiklos Szeredi fuse_copy_finish(cs); 758ce534fb0SMiklos Szeredi 759ce534fb0SMiklos Szeredi err = buf->ops->confirm(cs->pipe, buf); 760ce534fb0SMiklos Szeredi if (err) 761ce534fb0SMiklos Szeredi return err; 762ce534fb0SMiklos Szeredi 763ce534fb0SMiklos Szeredi BUG_ON(!cs->nr_segs); 764ce534fb0SMiklos Szeredi cs->currbuf = buf; 765ce534fb0SMiklos Szeredi cs->len = buf->len; 766ce534fb0SMiklos Szeredi cs->pipebufs++; 767ce534fb0SMiklos Szeredi cs->nr_segs--; 768ce534fb0SMiklos Szeredi 769ce534fb0SMiklos Szeredi if (cs->len != PAGE_SIZE) 770ce534fb0SMiklos Szeredi goto out_fallback; 771ce534fb0SMiklos Szeredi 772ce534fb0SMiklos Szeredi if (buf->ops->steal(cs->pipe, buf) != 0) 773ce534fb0SMiklos Szeredi goto out_fallback; 774ce534fb0SMiklos Szeredi 775ce534fb0SMiklos Szeredi newpage = buf->page; 776ce534fb0SMiklos Szeredi 777ce534fb0SMiklos Szeredi if (WARN_ON(!PageUptodate(newpage))) 778ce534fb0SMiklos Szeredi return -EIO; 779ce534fb0SMiklos Szeredi 780ce534fb0SMiklos Szeredi ClearPageMappedToDisk(newpage); 781ce534fb0SMiklos Szeredi 782ce534fb0SMiklos Szeredi if (fuse_check_page(newpage) != 0) 783ce534fb0SMiklos Szeredi goto out_fallback_unlock; 784ce534fb0SMiklos Szeredi 785ce534fb0SMiklos Szeredi /* 786ce534fb0SMiklos Szeredi * This is a new and locked page, it shouldn't be mapped or 787ce534fb0SMiklos Szeredi * have any special flags on it 788ce534fb0SMiklos Szeredi */ 789ce534fb0SMiklos Szeredi if (WARN_ON(page_mapped(oldpage))) 790ce534fb0SMiklos Szeredi goto out_fallback_unlock; 791ce534fb0SMiklos Szeredi if (WARN_ON(page_has_private(oldpage))) 792ce534fb0SMiklos Szeredi goto out_fallback_unlock; 793ce534fb0SMiklos Szeredi if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage))) 794ce534fb0SMiklos Szeredi goto out_fallback_unlock; 795ce534fb0SMiklos Szeredi if (WARN_ON(PageMlocked(oldpage))) 796ce534fb0SMiklos Szeredi goto out_fallback_unlock; 797ce534fb0SMiklos Szeredi 798ef6a3c63SMiklos Szeredi err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); 799ce534fb0SMiklos Szeredi if (err) { 800ef6a3c63SMiklos Szeredi unlock_page(newpage); 801ef6a3c63SMiklos Szeredi return err; 802ce534fb0SMiklos Szeredi } 803ef6a3c63SMiklos Szeredi 804ce534fb0SMiklos Szeredi page_cache_get(newpage); 805ce534fb0SMiklos Szeredi 806ce534fb0SMiklos Szeredi if (!(buf->flags & PIPE_BUF_FLAG_LRU)) 807ce534fb0SMiklos Szeredi lru_cache_add_file(newpage); 808ce534fb0SMiklos Szeredi 809ce534fb0SMiklos Szeredi err = 0; 810ce534fb0SMiklos Szeredi spin_lock(&cs->fc->lock); 811ce534fb0SMiklos Szeredi if (cs->req->aborted) 812ce534fb0SMiklos Szeredi err = -ENOENT; 813ce534fb0SMiklos Szeredi else 814ce534fb0SMiklos Szeredi *pagep = newpage; 815ce534fb0SMiklos Szeredi spin_unlock(&cs->fc->lock); 816ce534fb0SMiklos Szeredi 817ce534fb0SMiklos Szeredi if (err) { 818ce534fb0SMiklos Szeredi unlock_page(newpage); 819ce534fb0SMiklos Szeredi page_cache_release(newpage); 820ce534fb0SMiklos Szeredi return err; 821ce534fb0SMiklos Szeredi } 822ce534fb0SMiklos Szeredi 823ce534fb0SMiklos Szeredi unlock_page(oldpage); 824ce534fb0SMiklos Szeredi page_cache_release(oldpage); 825ce534fb0SMiklos Szeredi cs->len = 0; 826ce534fb0SMiklos Szeredi 827ce534fb0SMiklos Szeredi return 0; 828ce534fb0SMiklos Szeredi 829ce534fb0SMiklos Szeredi out_fallback_unlock: 830ce534fb0SMiklos Szeredi unlock_page(newpage); 831ce534fb0SMiklos Szeredi out_fallback: 832ce534fb0SMiklos Szeredi cs->mapaddr = buf->ops->map(cs->pipe, buf, 1); 833ce534fb0SMiklos Szeredi cs->buf = cs->mapaddr + buf->offset; 834ce534fb0SMiklos Szeredi 835ce534fb0SMiklos Szeredi err = lock_request(cs->fc, cs->req); 836ce534fb0SMiklos Szeredi if (err) 837ce534fb0SMiklos Szeredi return err; 838ce534fb0SMiklos Szeredi 839ce534fb0SMiklos Szeredi return 1; 840ce534fb0SMiklos Szeredi } 841ce534fb0SMiklos Szeredi 842c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page, 843c3021629SMiklos Szeredi unsigned offset, unsigned count) 844c3021629SMiklos Szeredi { 845c3021629SMiklos Szeredi struct pipe_buffer *buf; 846c3021629SMiklos Szeredi 847c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 848c3021629SMiklos Szeredi return -EIO; 849c3021629SMiklos Szeredi 850c3021629SMiklos Szeredi unlock_request(cs->fc, cs->req); 851c3021629SMiklos Szeredi fuse_copy_finish(cs); 852c3021629SMiklos Szeredi 853c3021629SMiklos Szeredi buf = cs->pipebufs; 854c3021629SMiklos Szeredi page_cache_get(page); 855c3021629SMiklos Szeredi buf->page = page; 856c3021629SMiklos Szeredi buf->offset = offset; 857c3021629SMiklos Szeredi buf->len = count; 858c3021629SMiklos Szeredi 859c3021629SMiklos Szeredi cs->pipebufs++; 860c3021629SMiklos Szeredi cs->nr_segs++; 861c3021629SMiklos Szeredi cs->len = 0; 862c3021629SMiklos Szeredi 863c3021629SMiklos Szeredi return 0; 864c3021629SMiklos Szeredi } 865c3021629SMiklos Szeredi 866334f485dSMiklos Szeredi /* 867334f485dSMiklos Szeredi * Copy a page in the request to/from the userspace buffer. Must be 868334f485dSMiklos Szeredi * done atomically 869334f485dSMiklos Szeredi */ 870ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep, 871334f485dSMiklos Szeredi unsigned offset, unsigned count, int zeroing) 872334f485dSMiklos Szeredi { 873ce534fb0SMiklos Szeredi int err; 874ce534fb0SMiklos Szeredi struct page *page = *pagep; 875ce534fb0SMiklos Szeredi 876b6777c40SMiklos Szeredi if (page && zeroing && count < PAGE_SIZE) 877b6777c40SMiklos Szeredi clear_highpage(page); 878b6777c40SMiklos Szeredi 879334f485dSMiklos Szeredi while (count) { 880c3021629SMiklos Szeredi if (cs->write && cs->pipebufs && page) { 881c3021629SMiklos Szeredi return fuse_ref_page(cs, page, offset, count); 882c3021629SMiklos Szeredi } else if (!cs->len) { 883ce534fb0SMiklos Szeredi if (cs->move_pages && page && 884ce534fb0SMiklos Szeredi offset == 0 && count == PAGE_SIZE) { 885ce534fb0SMiklos Szeredi err = fuse_try_move_page(cs, pagep); 886ce534fb0SMiklos Szeredi if (err <= 0) 887ce534fb0SMiklos Szeredi return err; 888ce534fb0SMiklos Szeredi } else { 889ce534fb0SMiklos Szeredi err = fuse_copy_fill(cs); 8901729a16cSMiklos Szeredi if (err) 891334f485dSMiklos Szeredi return err; 8921729a16cSMiklos Szeredi } 893ce534fb0SMiklos Szeredi } 894334f485dSMiklos Szeredi if (page) { 8952408f6efSCong Wang void *mapaddr = kmap_atomic(page); 896334f485dSMiklos Szeredi void *buf = mapaddr + offset; 897334f485dSMiklos Szeredi offset += fuse_copy_do(cs, &buf, &count); 8982408f6efSCong Wang kunmap_atomic(mapaddr); 899334f485dSMiklos Szeredi } else 900334f485dSMiklos Szeredi offset += fuse_copy_do(cs, NULL, &count); 901334f485dSMiklos Szeredi } 902334f485dSMiklos Szeredi if (page && !cs->write) 903334f485dSMiklos Szeredi flush_dcache_page(page); 904334f485dSMiklos Szeredi return 0; 905334f485dSMiklos Szeredi } 906334f485dSMiklos Szeredi 907334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */ 908334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes, 909334f485dSMiklos Szeredi int zeroing) 910334f485dSMiklos Szeredi { 911334f485dSMiklos Szeredi unsigned i; 912334f485dSMiklos Szeredi struct fuse_req *req = cs->req; 913334f485dSMiklos Szeredi 914334f485dSMiklos Szeredi for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) { 915ce534fb0SMiklos Szeredi int err; 91685f40aecSMaxim Patlasov unsigned offset = req->page_descs[i].offset; 91785f40aecSMaxim Patlasov unsigned count = min(nbytes, req->page_descs[i].length); 918ce534fb0SMiklos Szeredi 919ce534fb0SMiklos Szeredi err = fuse_copy_page(cs, &req->pages[i], offset, count, 920ce534fb0SMiklos Szeredi zeroing); 921334f485dSMiklos Szeredi if (err) 922334f485dSMiklos Szeredi return err; 923334f485dSMiklos Szeredi 924334f485dSMiklos Szeredi nbytes -= count; 925334f485dSMiklos Szeredi } 926334f485dSMiklos Szeredi return 0; 927334f485dSMiklos Szeredi } 928334f485dSMiklos Szeredi 929334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */ 930334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) 931334f485dSMiklos Szeredi { 932334f485dSMiklos Szeredi while (size) { 9331729a16cSMiklos Szeredi if (!cs->len) { 9341729a16cSMiklos Szeredi int err = fuse_copy_fill(cs); 9351729a16cSMiklos Szeredi if (err) 936334f485dSMiklos Szeredi return err; 9371729a16cSMiklos Szeredi } 938334f485dSMiklos Szeredi fuse_copy_do(cs, &val, &size); 939334f485dSMiklos Szeredi } 940334f485dSMiklos Szeredi return 0; 941334f485dSMiklos Szeredi } 942334f485dSMiklos Szeredi 943334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */ 944334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs, 945334f485dSMiklos Szeredi unsigned argpages, struct fuse_arg *args, 946334f485dSMiklos Szeredi int zeroing) 947334f485dSMiklos Szeredi { 948334f485dSMiklos Szeredi int err = 0; 949334f485dSMiklos Szeredi unsigned i; 950334f485dSMiklos Szeredi 951334f485dSMiklos Szeredi for (i = 0; !err && i < numargs; i++) { 952334f485dSMiklos Szeredi struct fuse_arg *arg = &args[i]; 953334f485dSMiklos Szeredi if (i == numargs - 1 && argpages) 954334f485dSMiklos Szeredi err = fuse_copy_pages(cs, arg->size, zeroing); 955334f485dSMiklos Szeredi else 956334f485dSMiklos Szeredi err = fuse_copy_one(cs, arg->value, arg->size); 957334f485dSMiklos Szeredi } 958334f485dSMiklos Szeredi return err; 959334f485dSMiklos Szeredi } 960334f485dSMiklos Szeredi 96107e77dcaSMiklos Szeredi static int forget_pending(struct fuse_conn *fc) 96207e77dcaSMiklos Szeredi { 96307e77dcaSMiklos Szeredi return fc->forget_list_head.next != NULL; 96407e77dcaSMiklos Szeredi } 96507e77dcaSMiklos Szeredi 966a4d27e75SMiklos Szeredi static int request_pending(struct fuse_conn *fc) 967a4d27e75SMiklos Szeredi { 96807e77dcaSMiklos Szeredi return !list_empty(&fc->pending) || !list_empty(&fc->interrupts) || 96907e77dcaSMiklos Szeredi forget_pending(fc); 970a4d27e75SMiklos Szeredi } 971a4d27e75SMiklos Szeredi 972334f485dSMiklos Szeredi /* Wait until a request is available on the pending list */ 973334f485dSMiklos Szeredi static void request_wait(struct fuse_conn *fc) 974b9ca67b2SMiklos Szeredi __releases(fc->lock) 975b9ca67b2SMiklos Szeredi __acquires(fc->lock) 976334f485dSMiklos Szeredi { 977334f485dSMiklos Szeredi DECLARE_WAITQUEUE(wait, current); 978334f485dSMiklos Szeredi 979334f485dSMiklos Szeredi add_wait_queue_exclusive(&fc->waitq, &wait); 980a4d27e75SMiklos Szeredi while (fc->connected && !request_pending(fc)) { 981334f485dSMiklos Szeredi set_current_state(TASK_INTERRUPTIBLE); 982334f485dSMiklos Szeredi if (signal_pending(current)) 983334f485dSMiklos Szeredi break; 984334f485dSMiklos Szeredi 985d7133114SMiklos Szeredi spin_unlock(&fc->lock); 986334f485dSMiklos Szeredi schedule(); 987d7133114SMiklos Szeredi spin_lock(&fc->lock); 988334f485dSMiklos Szeredi } 989334f485dSMiklos Szeredi set_current_state(TASK_RUNNING); 990334f485dSMiklos Szeredi remove_wait_queue(&fc->waitq, &wait); 991334f485dSMiklos Szeredi } 992334f485dSMiklos Szeredi 993334f485dSMiklos Szeredi /* 994a4d27e75SMiklos Szeredi * Transfer an interrupt request to userspace 995a4d27e75SMiklos Szeredi * 996a4d27e75SMiklos Szeredi * Unlike other requests this is assembled on demand, without a need 997a4d27e75SMiklos Szeredi * to allocate a separate fuse_req structure. 998a4d27e75SMiklos Szeredi * 999a4d27e75SMiklos Szeredi * Called with fc->lock held, releases it 1000a4d27e75SMiklos Szeredi */ 1001c3021629SMiklos Szeredi static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_copy_state *cs, 1002c3021629SMiklos Szeredi size_t nbytes, struct fuse_req *req) 1003b9ca67b2SMiklos Szeredi __releases(fc->lock) 1004a4d27e75SMiklos Szeredi { 1005a4d27e75SMiklos Szeredi struct fuse_in_header ih; 1006a4d27e75SMiklos Szeredi struct fuse_interrupt_in arg; 1007a4d27e75SMiklos Szeredi unsigned reqsize = sizeof(ih) + sizeof(arg); 1008a4d27e75SMiklos Szeredi int err; 1009a4d27e75SMiklos Szeredi 1010a4d27e75SMiklos Szeredi list_del_init(&req->intr_entry); 1011a4d27e75SMiklos Szeredi req->intr_unique = fuse_get_unique(fc); 1012a4d27e75SMiklos Szeredi memset(&ih, 0, sizeof(ih)); 1013a4d27e75SMiklos Szeredi memset(&arg, 0, sizeof(arg)); 1014a4d27e75SMiklos Szeredi ih.len = reqsize; 1015a4d27e75SMiklos Szeredi ih.opcode = FUSE_INTERRUPT; 1016a4d27e75SMiklos Szeredi ih.unique = req->intr_unique; 1017a4d27e75SMiklos Szeredi arg.unique = req->in.h.unique; 1018a4d27e75SMiklos Szeredi 1019a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 1020c3021629SMiklos Szeredi if (nbytes < reqsize) 1021a4d27e75SMiklos Szeredi return -EINVAL; 1022a4d27e75SMiklos Szeredi 1023c3021629SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 1024a4d27e75SMiklos Szeredi if (!err) 1025c3021629SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 1026c3021629SMiklos Szeredi fuse_copy_finish(cs); 1027a4d27e75SMiklos Szeredi 1028a4d27e75SMiklos Szeredi return err ? err : reqsize; 1029a4d27e75SMiklos Szeredi } 1030a4d27e75SMiklos Szeredi 103102c048b9SMiklos Szeredi static struct fuse_forget_link *dequeue_forget(struct fuse_conn *fc, 103202c048b9SMiklos Szeredi unsigned max, 103302c048b9SMiklos Szeredi unsigned *countp) 103407e77dcaSMiklos Szeredi { 103502c048b9SMiklos Szeredi struct fuse_forget_link *head = fc->forget_list_head.next; 103602c048b9SMiklos Szeredi struct fuse_forget_link **newhead = &head; 103702c048b9SMiklos Szeredi unsigned count; 103807e77dcaSMiklos Szeredi 103902c048b9SMiklos Szeredi for (count = 0; *newhead != NULL && count < max; count++) 104002c048b9SMiklos Szeredi newhead = &(*newhead)->next; 104102c048b9SMiklos Szeredi 104202c048b9SMiklos Szeredi fc->forget_list_head.next = *newhead; 104302c048b9SMiklos Szeredi *newhead = NULL; 104407e77dcaSMiklos Szeredi if (fc->forget_list_head.next == NULL) 104507e77dcaSMiklos Szeredi fc->forget_list_tail = &fc->forget_list_head; 104607e77dcaSMiklos Szeredi 104702c048b9SMiklos Szeredi if (countp != NULL) 104802c048b9SMiklos Szeredi *countp = count; 104902c048b9SMiklos Szeredi 105002c048b9SMiklos Szeredi return head; 105107e77dcaSMiklos Szeredi } 105207e77dcaSMiklos Szeredi 105307e77dcaSMiklos Szeredi static int fuse_read_single_forget(struct fuse_conn *fc, 105407e77dcaSMiklos Szeredi struct fuse_copy_state *cs, 105507e77dcaSMiklos Szeredi size_t nbytes) 105607e77dcaSMiklos Szeredi __releases(fc->lock) 105707e77dcaSMiklos Szeredi { 105807e77dcaSMiklos Szeredi int err; 105902c048b9SMiklos Szeredi struct fuse_forget_link *forget = dequeue_forget(fc, 1, NULL); 106007e77dcaSMiklos Szeredi struct fuse_forget_in arg = { 106102c048b9SMiklos Szeredi .nlookup = forget->forget_one.nlookup, 106207e77dcaSMiklos Szeredi }; 106307e77dcaSMiklos Szeredi struct fuse_in_header ih = { 106407e77dcaSMiklos Szeredi .opcode = FUSE_FORGET, 106502c048b9SMiklos Szeredi .nodeid = forget->forget_one.nodeid, 106607e77dcaSMiklos Szeredi .unique = fuse_get_unique(fc), 106707e77dcaSMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 106807e77dcaSMiklos Szeredi }; 106907e77dcaSMiklos Szeredi 107007e77dcaSMiklos Szeredi spin_unlock(&fc->lock); 107107e77dcaSMiklos Szeredi kfree(forget); 107207e77dcaSMiklos Szeredi if (nbytes < ih.len) 107307e77dcaSMiklos Szeredi return -EINVAL; 107407e77dcaSMiklos Szeredi 107507e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 107607e77dcaSMiklos Szeredi if (!err) 107707e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 107807e77dcaSMiklos Szeredi fuse_copy_finish(cs); 107907e77dcaSMiklos Szeredi 108007e77dcaSMiklos Szeredi if (err) 108107e77dcaSMiklos Szeredi return err; 108207e77dcaSMiklos Szeredi 108307e77dcaSMiklos Szeredi return ih.len; 108407e77dcaSMiklos Szeredi } 108507e77dcaSMiklos Szeredi 108602c048b9SMiklos Szeredi static int fuse_read_batch_forget(struct fuse_conn *fc, 108702c048b9SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 108802c048b9SMiklos Szeredi __releases(fc->lock) 108902c048b9SMiklos Szeredi { 109002c048b9SMiklos Szeredi int err; 109102c048b9SMiklos Szeredi unsigned max_forgets; 109202c048b9SMiklos Szeredi unsigned count; 109302c048b9SMiklos Szeredi struct fuse_forget_link *head; 109402c048b9SMiklos Szeredi struct fuse_batch_forget_in arg = { .count = 0 }; 109502c048b9SMiklos Szeredi struct fuse_in_header ih = { 109602c048b9SMiklos Szeredi .opcode = FUSE_BATCH_FORGET, 109702c048b9SMiklos Szeredi .unique = fuse_get_unique(fc), 109802c048b9SMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 109902c048b9SMiklos Szeredi }; 110002c048b9SMiklos Szeredi 110102c048b9SMiklos Szeredi if (nbytes < ih.len) { 110202c048b9SMiklos Szeredi spin_unlock(&fc->lock); 110302c048b9SMiklos Szeredi return -EINVAL; 110402c048b9SMiklos Szeredi } 110502c048b9SMiklos Szeredi 110602c048b9SMiklos Szeredi max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one); 110702c048b9SMiklos Szeredi head = dequeue_forget(fc, max_forgets, &count); 110802c048b9SMiklos Szeredi spin_unlock(&fc->lock); 110902c048b9SMiklos Szeredi 111002c048b9SMiklos Szeredi arg.count = count; 111102c048b9SMiklos Szeredi ih.len += count * sizeof(struct fuse_forget_one); 111202c048b9SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 111302c048b9SMiklos Szeredi if (!err) 111402c048b9SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 111502c048b9SMiklos Szeredi 111602c048b9SMiklos Szeredi while (head) { 111702c048b9SMiklos Szeredi struct fuse_forget_link *forget = head; 111802c048b9SMiklos Szeredi 111902c048b9SMiklos Szeredi if (!err) { 112002c048b9SMiklos Szeredi err = fuse_copy_one(cs, &forget->forget_one, 112102c048b9SMiklos Szeredi sizeof(forget->forget_one)); 112202c048b9SMiklos Szeredi } 112302c048b9SMiklos Szeredi head = forget->next; 112402c048b9SMiklos Szeredi kfree(forget); 112502c048b9SMiklos Szeredi } 112602c048b9SMiklos Szeredi 112702c048b9SMiklos Szeredi fuse_copy_finish(cs); 112802c048b9SMiklos Szeredi 112902c048b9SMiklos Szeredi if (err) 113002c048b9SMiklos Szeredi return err; 113102c048b9SMiklos Szeredi 113202c048b9SMiklos Szeredi return ih.len; 113302c048b9SMiklos Szeredi } 113402c048b9SMiklos Szeredi 113502c048b9SMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_copy_state *cs, 113602c048b9SMiklos Szeredi size_t nbytes) 113702c048b9SMiklos Szeredi __releases(fc->lock) 113802c048b9SMiklos Szeredi { 113902c048b9SMiklos Szeredi if (fc->minor < 16 || fc->forget_list_head.next->next == NULL) 114002c048b9SMiklos Szeredi return fuse_read_single_forget(fc, cs, nbytes); 114102c048b9SMiklos Szeredi else 114202c048b9SMiklos Szeredi return fuse_read_batch_forget(fc, cs, nbytes); 114302c048b9SMiklos Szeredi } 114402c048b9SMiklos Szeredi 1145a4d27e75SMiklos Szeredi /* 1146334f485dSMiklos Szeredi * Read a single request into the userspace filesystem's buffer. This 1147334f485dSMiklos Szeredi * function waits until a request is available, then removes it from 1148334f485dSMiklos Szeredi * the pending list and copies request data to userspace buffer. If 1149f9a2842eSMiklos Szeredi * no reply is needed (FORGET) or request has been aborted or there 1150f9a2842eSMiklos Szeredi * was an error during the copying then it's finished by calling 1151334f485dSMiklos Szeredi * request_end(). Otherwise add it to the processing list, and set 1152334f485dSMiklos Szeredi * the 'sent' flag. 1153334f485dSMiklos Szeredi */ 1154c3021629SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file, 1155c3021629SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1156334f485dSMiklos Szeredi { 1157334f485dSMiklos Szeredi int err; 1158334f485dSMiklos Szeredi struct fuse_req *req; 1159334f485dSMiklos Szeredi struct fuse_in *in; 1160334f485dSMiklos Szeredi unsigned reqsize; 1161334f485dSMiklos Szeredi 11621d3d752bSMiklos Szeredi restart: 1163d7133114SMiklos Szeredi spin_lock(&fc->lock); 1164e5ac1d1eSJeff Dike err = -EAGAIN; 1165e5ac1d1eSJeff Dike if ((file->f_flags & O_NONBLOCK) && fc->connected && 1166a4d27e75SMiklos Szeredi !request_pending(fc)) 1167e5ac1d1eSJeff Dike goto err_unlock; 1168e5ac1d1eSJeff Dike 1169334f485dSMiklos Szeredi request_wait(fc); 1170334f485dSMiklos Szeredi err = -ENODEV; 11719ba7cbbaSMiklos Szeredi if (!fc->connected) 1172334f485dSMiklos Szeredi goto err_unlock; 1173334f485dSMiklos Szeredi err = -ERESTARTSYS; 1174a4d27e75SMiklos Szeredi if (!request_pending(fc)) 1175334f485dSMiklos Szeredi goto err_unlock; 1176334f485dSMiklos Szeredi 1177a4d27e75SMiklos Szeredi if (!list_empty(&fc->interrupts)) { 1178a4d27e75SMiklos Szeredi req = list_entry(fc->interrupts.next, struct fuse_req, 1179a4d27e75SMiklos Szeredi intr_entry); 1180c3021629SMiklos Szeredi return fuse_read_interrupt(fc, cs, nbytes, req); 1181a4d27e75SMiklos Szeredi } 1182a4d27e75SMiklos Szeredi 118307e77dcaSMiklos Szeredi if (forget_pending(fc)) { 118407e77dcaSMiklos Szeredi if (list_empty(&fc->pending) || fc->forget_batch-- > 0) 118502c048b9SMiklos Szeredi return fuse_read_forget(fc, cs, nbytes); 118607e77dcaSMiklos Szeredi 118707e77dcaSMiklos Szeredi if (fc->forget_batch <= -8) 118807e77dcaSMiklos Szeredi fc->forget_batch = 16; 118907e77dcaSMiklos Szeredi } 119007e77dcaSMiklos Szeredi 1191334f485dSMiklos Szeredi req = list_entry(fc->pending.next, struct fuse_req, list); 119283cfd493SMiklos Szeredi req->state = FUSE_REQ_READING; 1193d77a1d5bSMiklos Szeredi list_move(&req->list, &fc->io); 1194334f485dSMiklos Szeredi 1195334f485dSMiklos Szeredi in = &req->in; 11961d3d752bSMiklos Szeredi reqsize = in->h.len; 11971d3d752bSMiklos Szeredi /* If request is too large, reply with an error and restart the read */ 1198c3021629SMiklos Szeredi if (nbytes < reqsize) { 11991d3d752bSMiklos Szeredi req->out.h.error = -EIO; 12001d3d752bSMiklos Szeredi /* SETXATTR is special, since it may contain too large data */ 12011d3d752bSMiklos Szeredi if (in->h.opcode == FUSE_SETXATTR) 12021d3d752bSMiklos Szeredi req->out.h.error = -E2BIG; 12031d3d752bSMiklos Szeredi request_end(fc, req); 12041d3d752bSMiklos Szeredi goto restart; 12051d3d752bSMiklos Szeredi } 1206d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1207c3021629SMiklos Szeredi cs->req = req; 1208c3021629SMiklos Szeredi err = fuse_copy_one(cs, &in->h, sizeof(in->h)); 1209334f485dSMiklos Szeredi if (!err) 1210c3021629SMiklos Szeredi err = fuse_copy_args(cs, in->numargs, in->argpages, 1211334f485dSMiklos Szeredi (struct fuse_arg *) in->args, 0); 1212c3021629SMiklos Szeredi fuse_copy_finish(cs); 1213d7133114SMiklos Szeredi spin_lock(&fc->lock); 1214334f485dSMiklos Szeredi req->locked = 0; 1215c9c9d7dfSMiklos Szeredi if (req->aborted) { 1216c9c9d7dfSMiklos Szeredi request_end(fc, req); 1217c9c9d7dfSMiklos Szeredi return -ENODEV; 1218c9c9d7dfSMiklos Szeredi } 1219334f485dSMiklos Szeredi if (err) { 1220334f485dSMiklos Szeredi req->out.h.error = -EIO; 1221334f485dSMiklos Szeredi request_end(fc, req); 1222334f485dSMiklos Szeredi return err; 1223334f485dSMiklos Szeredi } 1224334f485dSMiklos Szeredi if (!req->isreply) 1225334f485dSMiklos Szeredi request_end(fc, req); 1226334f485dSMiklos Szeredi else { 122783cfd493SMiklos Szeredi req->state = FUSE_REQ_SENT; 1228d77a1d5bSMiklos Szeredi list_move_tail(&req->list, &fc->processing); 1229a4d27e75SMiklos Szeredi if (req->interrupted) 1230a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 1231d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1232334f485dSMiklos Szeredi } 1233334f485dSMiklos Szeredi return reqsize; 1234334f485dSMiklos Szeredi 1235334f485dSMiklos Szeredi err_unlock: 1236d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1237334f485dSMiklos Szeredi return err; 1238334f485dSMiklos Szeredi } 1239334f485dSMiklos Szeredi 1240c3021629SMiklos Szeredi static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, 1241c3021629SMiklos Szeredi unsigned long nr_segs, loff_t pos) 1242c3021629SMiklos Szeredi { 1243c3021629SMiklos Szeredi struct fuse_copy_state cs; 1244c3021629SMiklos Szeredi struct file *file = iocb->ki_filp; 1245c3021629SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 1246c3021629SMiklos Szeredi if (!fc) 1247c3021629SMiklos Szeredi return -EPERM; 1248c3021629SMiklos Szeredi 1249c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 1, iov, nr_segs); 1250c3021629SMiklos Szeredi 1251c3021629SMiklos Szeredi return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs)); 1252c3021629SMiklos Szeredi } 1253c3021629SMiklos Szeredi 1254c3021629SMiklos Szeredi static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe, 1255c3021629SMiklos Szeredi struct pipe_buffer *buf) 1256c3021629SMiklos Szeredi { 1257c3021629SMiklos Szeredi return 1; 1258c3021629SMiklos Szeredi } 1259c3021629SMiklos Szeredi 1260c3021629SMiklos Szeredi static const struct pipe_buf_operations fuse_dev_pipe_buf_ops = { 1261c3021629SMiklos Szeredi .can_merge = 0, 1262c3021629SMiklos Szeredi .map = generic_pipe_buf_map, 1263c3021629SMiklos Szeredi .unmap = generic_pipe_buf_unmap, 1264c3021629SMiklos Szeredi .confirm = generic_pipe_buf_confirm, 1265c3021629SMiklos Szeredi .release = generic_pipe_buf_release, 1266c3021629SMiklos Szeredi .steal = fuse_dev_pipe_buf_steal, 1267c3021629SMiklos Szeredi .get = generic_pipe_buf_get, 1268c3021629SMiklos Szeredi }; 1269c3021629SMiklos Szeredi 1270c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, 1271c3021629SMiklos Szeredi struct pipe_inode_info *pipe, 1272c3021629SMiklos Szeredi size_t len, unsigned int flags) 1273c3021629SMiklos Szeredi { 1274c3021629SMiklos Szeredi int ret; 1275c3021629SMiklos Szeredi int page_nr = 0; 1276c3021629SMiklos Szeredi int do_wakeup = 0; 1277c3021629SMiklos Szeredi struct pipe_buffer *bufs; 1278c3021629SMiklos Szeredi struct fuse_copy_state cs; 1279c3021629SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(in); 1280c3021629SMiklos Szeredi if (!fc) 1281c3021629SMiklos Szeredi return -EPERM; 1282c3021629SMiklos Szeredi 1283c3021629SMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1284c3021629SMiklos Szeredi if (!bufs) 1285c3021629SMiklos Szeredi return -ENOMEM; 1286c3021629SMiklos Szeredi 1287c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 1, NULL, 0); 1288c3021629SMiklos Szeredi cs.pipebufs = bufs; 1289c3021629SMiklos Szeredi cs.pipe = pipe; 1290c3021629SMiklos Szeredi ret = fuse_dev_do_read(fc, in, &cs, len); 1291c3021629SMiklos Szeredi if (ret < 0) 1292c3021629SMiklos Szeredi goto out; 1293c3021629SMiklos Szeredi 1294c3021629SMiklos Szeredi ret = 0; 1295c3021629SMiklos Szeredi pipe_lock(pipe); 1296c3021629SMiklos Szeredi 1297c3021629SMiklos Szeredi if (!pipe->readers) { 1298c3021629SMiklos Szeredi send_sig(SIGPIPE, current, 0); 1299c3021629SMiklos Szeredi if (!ret) 1300c3021629SMiklos Szeredi ret = -EPIPE; 1301c3021629SMiklos Szeredi goto out_unlock; 1302c3021629SMiklos Szeredi } 1303c3021629SMiklos Szeredi 1304c3021629SMiklos Szeredi if (pipe->nrbufs + cs.nr_segs > pipe->buffers) { 1305c3021629SMiklos Szeredi ret = -EIO; 1306c3021629SMiklos Szeredi goto out_unlock; 1307c3021629SMiklos Szeredi } 1308c3021629SMiklos Szeredi 1309c3021629SMiklos Szeredi while (page_nr < cs.nr_segs) { 1310c3021629SMiklos Szeredi int newbuf = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); 1311c3021629SMiklos Szeredi struct pipe_buffer *buf = pipe->bufs + newbuf; 1312c3021629SMiklos Szeredi 1313c3021629SMiklos Szeredi buf->page = bufs[page_nr].page; 1314c3021629SMiklos Szeredi buf->offset = bufs[page_nr].offset; 1315c3021629SMiklos Szeredi buf->len = bufs[page_nr].len; 1316c3021629SMiklos Szeredi buf->ops = &fuse_dev_pipe_buf_ops; 1317c3021629SMiklos Szeredi 1318c3021629SMiklos Szeredi pipe->nrbufs++; 1319c3021629SMiklos Szeredi page_nr++; 1320c3021629SMiklos Szeredi ret += buf->len; 1321c3021629SMiklos Szeredi 1322*6447a3cfSAl Viro if (pipe->files) 1323c3021629SMiklos Szeredi do_wakeup = 1; 1324c3021629SMiklos Szeredi } 1325c3021629SMiklos Szeredi 1326c3021629SMiklos Szeredi out_unlock: 1327c3021629SMiklos Szeredi pipe_unlock(pipe); 1328c3021629SMiklos Szeredi 1329c3021629SMiklos Szeredi if (do_wakeup) { 1330c3021629SMiklos Szeredi smp_mb(); 1331c3021629SMiklos Szeredi if (waitqueue_active(&pipe->wait)) 1332c3021629SMiklos Szeredi wake_up_interruptible(&pipe->wait); 1333c3021629SMiklos Szeredi kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); 1334c3021629SMiklos Szeredi } 1335c3021629SMiklos Szeredi 1336c3021629SMiklos Szeredi out: 1337c3021629SMiklos Szeredi for (; page_nr < cs.nr_segs; page_nr++) 1338c3021629SMiklos Szeredi page_cache_release(bufs[page_nr].page); 1339c3021629SMiklos Szeredi 1340c3021629SMiklos Szeredi kfree(bufs); 1341c3021629SMiklos Szeredi return ret; 1342c3021629SMiklos Szeredi } 1343c3021629SMiklos Szeredi 134495668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size, 134595668a69STejun Heo struct fuse_copy_state *cs) 134695668a69STejun Heo { 134795668a69STejun Heo struct fuse_notify_poll_wakeup_out outarg; 1348f6d47a17SMiklos Szeredi int err = -EINVAL; 134995668a69STejun Heo 135095668a69STejun Heo if (size != sizeof(outarg)) 1351f6d47a17SMiklos Szeredi goto err; 135295668a69STejun Heo 135395668a69STejun Heo err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 135495668a69STejun Heo if (err) 1355f6d47a17SMiklos Szeredi goto err; 135695668a69STejun Heo 1357f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 135895668a69STejun Heo return fuse_notify_poll_wakeup(fc, &outarg); 1359f6d47a17SMiklos Szeredi 1360f6d47a17SMiklos Szeredi err: 1361f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 1362f6d47a17SMiklos Szeredi return err; 136395668a69STejun Heo } 136495668a69STejun Heo 13653b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size, 13663b463ae0SJohn Muir struct fuse_copy_state *cs) 13673b463ae0SJohn Muir { 13683b463ae0SJohn Muir struct fuse_notify_inval_inode_out outarg; 13693b463ae0SJohn Muir int err = -EINVAL; 13703b463ae0SJohn Muir 13713b463ae0SJohn Muir if (size != sizeof(outarg)) 13723b463ae0SJohn Muir goto err; 13733b463ae0SJohn Muir 13743b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 13753b463ae0SJohn Muir if (err) 13763b463ae0SJohn Muir goto err; 13773b463ae0SJohn Muir fuse_copy_finish(cs); 13783b463ae0SJohn Muir 13793b463ae0SJohn Muir down_read(&fc->killsb); 13803b463ae0SJohn Muir err = -ENOENT; 1381b21dda43SMiklos Szeredi if (fc->sb) { 13823b463ae0SJohn Muir err = fuse_reverse_inval_inode(fc->sb, outarg.ino, 13833b463ae0SJohn Muir outarg.off, outarg.len); 1384b21dda43SMiklos Szeredi } 13853b463ae0SJohn Muir up_read(&fc->killsb); 13863b463ae0SJohn Muir return err; 13873b463ae0SJohn Muir 13883b463ae0SJohn Muir err: 13893b463ae0SJohn Muir fuse_copy_finish(cs); 13903b463ae0SJohn Muir return err; 13913b463ae0SJohn Muir } 13923b463ae0SJohn Muir 13933b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, 13943b463ae0SJohn Muir struct fuse_copy_state *cs) 13953b463ae0SJohn Muir { 13963b463ae0SJohn Muir struct fuse_notify_inval_entry_out outarg; 1397b2d82ee3SFang Wenqi int err = -ENOMEM; 1398b2d82ee3SFang Wenqi char *buf; 13993b463ae0SJohn Muir struct qstr name; 14003b463ae0SJohn Muir 1401b2d82ee3SFang Wenqi buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1402b2d82ee3SFang Wenqi if (!buf) 1403b2d82ee3SFang Wenqi goto err; 1404b2d82ee3SFang Wenqi 1405b2d82ee3SFang Wenqi err = -EINVAL; 14063b463ae0SJohn Muir if (size < sizeof(outarg)) 14073b463ae0SJohn Muir goto err; 14083b463ae0SJohn Muir 14093b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 14103b463ae0SJohn Muir if (err) 14113b463ae0SJohn Muir goto err; 14123b463ae0SJohn Muir 14133b463ae0SJohn Muir err = -ENAMETOOLONG; 14143b463ae0SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 14153b463ae0SJohn Muir goto err; 14163b463ae0SJohn Muir 1417c2183d1eSMiklos Szeredi err = -EINVAL; 1418c2183d1eSMiklos Szeredi if (size != sizeof(outarg) + outarg.namelen + 1) 1419c2183d1eSMiklos Szeredi goto err; 1420c2183d1eSMiklos Szeredi 14213b463ae0SJohn Muir name.name = buf; 14223b463ae0SJohn Muir name.len = outarg.namelen; 14233b463ae0SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 14243b463ae0SJohn Muir if (err) 14253b463ae0SJohn Muir goto err; 14263b463ae0SJohn Muir fuse_copy_finish(cs); 14273b463ae0SJohn Muir buf[outarg.namelen] = 0; 14283b463ae0SJohn Muir name.hash = full_name_hash(name.name, name.len); 14293b463ae0SJohn Muir 14303b463ae0SJohn Muir down_read(&fc->killsb); 14313b463ae0SJohn Muir err = -ENOENT; 1432b21dda43SMiklos Szeredi if (fc->sb) 1433451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 0, &name); 1434451d0f59SJohn Muir up_read(&fc->killsb); 1435451d0f59SJohn Muir kfree(buf); 1436451d0f59SJohn Muir return err; 1437451d0f59SJohn Muir 1438451d0f59SJohn Muir err: 1439451d0f59SJohn Muir kfree(buf); 1440451d0f59SJohn Muir fuse_copy_finish(cs); 1441451d0f59SJohn Muir return err; 1442451d0f59SJohn Muir } 1443451d0f59SJohn Muir 1444451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size, 1445451d0f59SJohn Muir struct fuse_copy_state *cs) 1446451d0f59SJohn Muir { 1447451d0f59SJohn Muir struct fuse_notify_delete_out outarg; 1448451d0f59SJohn Muir int err = -ENOMEM; 1449451d0f59SJohn Muir char *buf; 1450451d0f59SJohn Muir struct qstr name; 1451451d0f59SJohn Muir 1452451d0f59SJohn Muir buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1453451d0f59SJohn Muir if (!buf) 1454451d0f59SJohn Muir goto err; 1455451d0f59SJohn Muir 1456451d0f59SJohn Muir err = -EINVAL; 1457451d0f59SJohn Muir if (size < sizeof(outarg)) 1458451d0f59SJohn Muir goto err; 1459451d0f59SJohn Muir 1460451d0f59SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1461451d0f59SJohn Muir if (err) 1462451d0f59SJohn Muir goto err; 1463451d0f59SJohn Muir 1464451d0f59SJohn Muir err = -ENAMETOOLONG; 1465451d0f59SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 1466451d0f59SJohn Muir goto err; 1467451d0f59SJohn Muir 1468451d0f59SJohn Muir err = -EINVAL; 1469451d0f59SJohn Muir if (size != sizeof(outarg) + outarg.namelen + 1) 1470451d0f59SJohn Muir goto err; 1471451d0f59SJohn Muir 1472451d0f59SJohn Muir name.name = buf; 1473451d0f59SJohn Muir name.len = outarg.namelen; 1474451d0f59SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 1475451d0f59SJohn Muir if (err) 1476451d0f59SJohn Muir goto err; 1477451d0f59SJohn Muir fuse_copy_finish(cs); 1478451d0f59SJohn Muir buf[outarg.namelen] = 0; 1479451d0f59SJohn Muir name.hash = full_name_hash(name.name, name.len); 1480451d0f59SJohn Muir 1481451d0f59SJohn Muir down_read(&fc->killsb); 1482451d0f59SJohn Muir err = -ENOENT; 1483451d0f59SJohn Muir if (fc->sb) 1484451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 1485451d0f59SJohn Muir outarg.child, &name); 14863b463ae0SJohn Muir up_read(&fc->killsb); 1487b2d82ee3SFang Wenqi kfree(buf); 14883b463ae0SJohn Muir return err; 14893b463ae0SJohn Muir 14903b463ae0SJohn Muir err: 1491b2d82ee3SFang Wenqi kfree(buf); 14923b463ae0SJohn Muir fuse_copy_finish(cs); 14933b463ae0SJohn Muir return err; 14943b463ae0SJohn Muir } 14953b463ae0SJohn Muir 1496a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, 1497a1d75f25SMiklos Szeredi struct fuse_copy_state *cs) 1498a1d75f25SMiklos Szeredi { 1499a1d75f25SMiklos Szeredi struct fuse_notify_store_out outarg; 1500a1d75f25SMiklos Szeredi struct inode *inode; 1501a1d75f25SMiklos Szeredi struct address_space *mapping; 1502a1d75f25SMiklos Szeredi u64 nodeid; 1503a1d75f25SMiklos Szeredi int err; 1504a1d75f25SMiklos Szeredi pgoff_t index; 1505a1d75f25SMiklos Szeredi unsigned int offset; 1506a1d75f25SMiklos Szeredi unsigned int num; 1507a1d75f25SMiklos Szeredi loff_t file_size; 1508a1d75f25SMiklos Szeredi loff_t end; 1509a1d75f25SMiklos Szeredi 1510a1d75f25SMiklos Szeredi err = -EINVAL; 1511a1d75f25SMiklos Szeredi if (size < sizeof(outarg)) 1512a1d75f25SMiklos Szeredi goto out_finish; 1513a1d75f25SMiklos Szeredi 1514a1d75f25SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1515a1d75f25SMiklos Szeredi if (err) 1516a1d75f25SMiklos Szeredi goto out_finish; 1517a1d75f25SMiklos Szeredi 1518a1d75f25SMiklos Szeredi err = -EINVAL; 1519a1d75f25SMiklos Szeredi if (size - sizeof(outarg) != outarg.size) 1520a1d75f25SMiklos Szeredi goto out_finish; 1521a1d75f25SMiklos Szeredi 1522a1d75f25SMiklos Szeredi nodeid = outarg.nodeid; 1523a1d75f25SMiklos Szeredi 1524a1d75f25SMiklos Szeredi down_read(&fc->killsb); 1525a1d75f25SMiklos Szeredi 1526a1d75f25SMiklos Szeredi err = -ENOENT; 1527a1d75f25SMiklos Szeredi if (!fc->sb) 1528a1d75f25SMiklos Szeredi goto out_up_killsb; 1529a1d75f25SMiklos Szeredi 1530a1d75f25SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 1531a1d75f25SMiklos Szeredi if (!inode) 1532a1d75f25SMiklos Szeredi goto out_up_killsb; 1533a1d75f25SMiklos Szeredi 1534a1d75f25SMiklos Szeredi mapping = inode->i_mapping; 1535a1d75f25SMiklos Szeredi index = outarg.offset >> PAGE_CACHE_SHIFT; 1536a1d75f25SMiklos Szeredi offset = outarg.offset & ~PAGE_CACHE_MASK; 1537a1d75f25SMiklos Szeredi file_size = i_size_read(inode); 1538a1d75f25SMiklos Szeredi end = outarg.offset + outarg.size; 1539a1d75f25SMiklos Szeredi if (end > file_size) { 1540a1d75f25SMiklos Szeredi file_size = end; 1541a1d75f25SMiklos Szeredi fuse_write_update_size(inode, file_size); 1542a1d75f25SMiklos Szeredi } 1543a1d75f25SMiklos Szeredi 1544a1d75f25SMiklos Szeredi num = outarg.size; 1545a1d75f25SMiklos Szeredi while (num) { 1546a1d75f25SMiklos Szeredi struct page *page; 1547a1d75f25SMiklos Szeredi unsigned int this_num; 1548a1d75f25SMiklos Szeredi 1549a1d75f25SMiklos Szeredi err = -ENOMEM; 1550a1d75f25SMiklos Szeredi page = find_or_create_page(mapping, index, 1551a1d75f25SMiklos Szeredi mapping_gfp_mask(mapping)); 1552a1d75f25SMiklos Szeredi if (!page) 1553a1d75f25SMiklos Szeredi goto out_iput; 1554a1d75f25SMiklos Szeredi 1555a1d75f25SMiklos Szeredi this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 1556a1d75f25SMiklos Szeredi err = fuse_copy_page(cs, &page, offset, this_num, 0); 1557a1d75f25SMiklos Szeredi if (!err && offset == 0 && (num != 0 || file_size == end)) 1558a1d75f25SMiklos Szeredi SetPageUptodate(page); 1559a1d75f25SMiklos Szeredi unlock_page(page); 1560a1d75f25SMiklos Szeredi page_cache_release(page); 1561a1d75f25SMiklos Szeredi 1562a1d75f25SMiklos Szeredi if (err) 1563a1d75f25SMiklos Szeredi goto out_iput; 1564a1d75f25SMiklos Szeredi 1565a1d75f25SMiklos Szeredi num -= this_num; 1566a1d75f25SMiklos Szeredi offset = 0; 1567a1d75f25SMiklos Szeredi index++; 1568a1d75f25SMiklos Szeredi } 1569a1d75f25SMiklos Szeredi 1570a1d75f25SMiklos Szeredi err = 0; 1571a1d75f25SMiklos Szeredi 1572a1d75f25SMiklos Szeredi out_iput: 1573a1d75f25SMiklos Szeredi iput(inode); 1574a1d75f25SMiklos Szeredi out_up_killsb: 1575a1d75f25SMiklos Szeredi up_read(&fc->killsb); 1576a1d75f25SMiklos Szeredi out_finish: 1577a1d75f25SMiklos Szeredi fuse_copy_finish(cs); 1578a1d75f25SMiklos Szeredi return err; 1579a1d75f25SMiklos Szeredi } 1580a1d75f25SMiklos Szeredi 15812d45ba38SMiklos Szeredi static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) 15822d45ba38SMiklos Szeredi { 15830be8557bSMiklos Szeredi release_pages(req->pages, req->num_pages, 0); 15842d45ba38SMiklos Szeredi } 15852d45ba38SMiklos Szeredi 15862d45ba38SMiklos Szeredi static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, 15872d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out *outarg) 15882d45ba38SMiklos Szeredi { 15892d45ba38SMiklos Szeredi int err; 15902d45ba38SMiklos Szeredi struct address_space *mapping = inode->i_mapping; 15912d45ba38SMiklos Szeredi struct fuse_req *req; 15922d45ba38SMiklos Szeredi pgoff_t index; 15932d45ba38SMiklos Szeredi loff_t file_size; 15942d45ba38SMiklos Szeredi unsigned int num; 15952d45ba38SMiklos Szeredi unsigned int offset; 15960157443cSGeert Uytterhoeven size_t total_len = 0; 15974d53dc99SMaxim Patlasov int num_pages; 15982d45ba38SMiklos Szeredi 15992d45ba38SMiklos Szeredi offset = outarg->offset & ~PAGE_CACHE_MASK; 16004d53dc99SMaxim Patlasov file_size = i_size_read(inode); 16014d53dc99SMaxim Patlasov 16024d53dc99SMaxim Patlasov num = outarg->size; 16034d53dc99SMaxim Patlasov if (outarg->offset > file_size) 16044d53dc99SMaxim Patlasov num = 0; 16054d53dc99SMaxim Patlasov else if (outarg->offset + num > file_size) 16064d53dc99SMaxim Patlasov num = file_size - outarg->offset; 16074d53dc99SMaxim Patlasov 16084d53dc99SMaxim Patlasov num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; 16094d53dc99SMaxim Patlasov num_pages = min(num_pages, FUSE_MAX_PAGES_PER_REQ); 16104d53dc99SMaxim Patlasov 16114d53dc99SMaxim Patlasov req = fuse_get_req(fc, num_pages); 16124d53dc99SMaxim Patlasov if (IS_ERR(req)) 16134d53dc99SMaxim Patlasov return PTR_ERR(req); 16142d45ba38SMiklos Szeredi 16152d45ba38SMiklos Szeredi req->in.h.opcode = FUSE_NOTIFY_REPLY; 16162d45ba38SMiklos Szeredi req->in.h.nodeid = outarg->nodeid; 16172d45ba38SMiklos Szeredi req->in.numargs = 2; 16182d45ba38SMiklos Szeredi req->in.argpages = 1; 1619b2430d75SMaxim Patlasov req->page_descs[0].offset = offset; 16202d45ba38SMiklos Szeredi req->end = fuse_retrieve_end; 16212d45ba38SMiklos Szeredi 16222d45ba38SMiklos Szeredi index = outarg->offset >> PAGE_CACHE_SHIFT; 16232d45ba38SMiklos Szeredi 16244d53dc99SMaxim Patlasov while (num && req->num_pages < num_pages) { 16252d45ba38SMiklos Szeredi struct page *page; 16262d45ba38SMiklos Szeredi unsigned int this_num; 16272d45ba38SMiklos Szeredi 16282d45ba38SMiklos Szeredi page = find_get_page(mapping, index); 16292d45ba38SMiklos Szeredi if (!page) 16302d45ba38SMiklos Szeredi break; 16312d45ba38SMiklos Szeredi 16322d45ba38SMiklos Szeredi this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 16332d45ba38SMiklos Szeredi req->pages[req->num_pages] = page; 163485f40aecSMaxim Patlasov req->page_descs[req->num_pages].length = this_num; 16352d45ba38SMiklos Szeredi req->num_pages++; 16362d45ba38SMiklos Szeredi 1637c9e67d48SMiklos Szeredi offset = 0; 16382d45ba38SMiklos Szeredi num -= this_num; 16392d45ba38SMiklos Szeredi total_len += this_num; 164048706d0aSMiklos Szeredi index++; 16412d45ba38SMiklos Szeredi } 16422d45ba38SMiklos Szeredi req->misc.retrieve_in.offset = outarg->offset; 16432d45ba38SMiklos Szeredi req->misc.retrieve_in.size = total_len; 16442d45ba38SMiklos Szeredi req->in.args[0].size = sizeof(req->misc.retrieve_in); 16452d45ba38SMiklos Szeredi req->in.args[0].value = &req->misc.retrieve_in; 16462d45ba38SMiklos Szeredi req->in.args[1].size = total_len; 16472d45ba38SMiklos Szeredi 16482d45ba38SMiklos Szeredi err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique); 16492d45ba38SMiklos Szeredi if (err) 16502d45ba38SMiklos Szeredi fuse_retrieve_end(fc, req); 16512d45ba38SMiklos Szeredi 16522d45ba38SMiklos Szeredi return err; 16532d45ba38SMiklos Szeredi } 16542d45ba38SMiklos Szeredi 16552d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, 16562d45ba38SMiklos Szeredi struct fuse_copy_state *cs) 16572d45ba38SMiklos Szeredi { 16582d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out outarg; 16592d45ba38SMiklos Szeredi struct inode *inode; 16602d45ba38SMiklos Szeredi int err; 16612d45ba38SMiklos Szeredi 16622d45ba38SMiklos Szeredi err = -EINVAL; 16632d45ba38SMiklos Szeredi if (size != sizeof(outarg)) 16642d45ba38SMiklos Szeredi goto copy_finish; 16652d45ba38SMiklos Szeredi 16662d45ba38SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 16672d45ba38SMiklos Szeredi if (err) 16682d45ba38SMiklos Szeredi goto copy_finish; 16692d45ba38SMiklos Szeredi 16702d45ba38SMiklos Szeredi fuse_copy_finish(cs); 16712d45ba38SMiklos Szeredi 16722d45ba38SMiklos Szeredi down_read(&fc->killsb); 16732d45ba38SMiklos Szeredi err = -ENOENT; 16742d45ba38SMiklos Szeredi if (fc->sb) { 16752d45ba38SMiklos Szeredi u64 nodeid = outarg.nodeid; 16762d45ba38SMiklos Szeredi 16772d45ba38SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 16782d45ba38SMiklos Szeredi if (inode) { 16792d45ba38SMiklos Szeredi err = fuse_retrieve(fc, inode, &outarg); 16802d45ba38SMiklos Szeredi iput(inode); 16812d45ba38SMiklos Szeredi } 16822d45ba38SMiklos Szeredi } 16832d45ba38SMiklos Szeredi up_read(&fc->killsb); 16842d45ba38SMiklos Szeredi 16852d45ba38SMiklos Szeredi return err; 16862d45ba38SMiklos Szeredi 16872d45ba38SMiklos Szeredi copy_finish: 16882d45ba38SMiklos Szeredi fuse_copy_finish(cs); 16892d45ba38SMiklos Szeredi return err; 16902d45ba38SMiklos Szeredi } 16912d45ba38SMiklos Szeredi 16928599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, 16938599396bSTejun Heo unsigned int size, struct fuse_copy_state *cs) 16948599396bSTejun Heo { 16958599396bSTejun Heo switch (code) { 169695668a69STejun Heo case FUSE_NOTIFY_POLL: 169795668a69STejun Heo return fuse_notify_poll(fc, size, cs); 169895668a69STejun Heo 16993b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_INODE: 17003b463ae0SJohn Muir return fuse_notify_inval_inode(fc, size, cs); 17013b463ae0SJohn Muir 17023b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_ENTRY: 17033b463ae0SJohn Muir return fuse_notify_inval_entry(fc, size, cs); 17043b463ae0SJohn Muir 1705a1d75f25SMiklos Szeredi case FUSE_NOTIFY_STORE: 1706a1d75f25SMiklos Szeredi return fuse_notify_store(fc, size, cs); 1707a1d75f25SMiklos Szeredi 17082d45ba38SMiklos Szeredi case FUSE_NOTIFY_RETRIEVE: 17092d45ba38SMiklos Szeredi return fuse_notify_retrieve(fc, size, cs); 17102d45ba38SMiklos Szeredi 1711451d0f59SJohn Muir case FUSE_NOTIFY_DELETE: 1712451d0f59SJohn Muir return fuse_notify_delete(fc, size, cs); 1713451d0f59SJohn Muir 17148599396bSTejun Heo default: 1715f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 17168599396bSTejun Heo return -EINVAL; 17178599396bSTejun Heo } 17188599396bSTejun Heo } 17198599396bSTejun Heo 1720334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */ 1721334f485dSMiklos Szeredi static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) 1722334f485dSMiklos Szeredi { 1723334f485dSMiklos Szeredi struct list_head *entry; 1724334f485dSMiklos Szeredi 1725334f485dSMiklos Szeredi list_for_each(entry, &fc->processing) { 1726334f485dSMiklos Szeredi struct fuse_req *req; 1727334f485dSMiklos Szeredi req = list_entry(entry, struct fuse_req, list); 1728a4d27e75SMiklos Szeredi if (req->in.h.unique == unique || req->intr_unique == unique) 1729334f485dSMiklos Szeredi return req; 1730334f485dSMiklos Szeredi } 1731334f485dSMiklos Szeredi return NULL; 1732334f485dSMiklos Szeredi } 1733334f485dSMiklos Szeredi 1734334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out, 1735334f485dSMiklos Szeredi unsigned nbytes) 1736334f485dSMiklos Szeredi { 1737334f485dSMiklos Szeredi unsigned reqsize = sizeof(struct fuse_out_header); 1738334f485dSMiklos Szeredi 1739334f485dSMiklos Szeredi if (out->h.error) 1740334f485dSMiklos Szeredi return nbytes != reqsize ? -EINVAL : 0; 1741334f485dSMiklos Szeredi 1742334f485dSMiklos Szeredi reqsize += len_args(out->numargs, out->args); 1743334f485dSMiklos Szeredi 1744334f485dSMiklos Szeredi if (reqsize < nbytes || (reqsize > nbytes && !out->argvar)) 1745334f485dSMiklos Szeredi return -EINVAL; 1746334f485dSMiklos Szeredi else if (reqsize > nbytes) { 1747334f485dSMiklos Szeredi struct fuse_arg *lastarg = &out->args[out->numargs-1]; 1748334f485dSMiklos Szeredi unsigned diffsize = reqsize - nbytes; 1749334f485dSMiklos Szeredi if (diffsize > lastarg->size) 1750334f485dSMiklos Szeredi return -EINVAL; 1751334f485dSMiklos Szeredi lastarg->size -= diffsize; 1752334f485dSMiklos Szeredi } 1753334f485dSMiklos Szeredi return fuse_copy_args(cs, out->numargs, out->argpages, out->args, 1754334f485dSMiklos Szeredi out->page_zeroing); 1755334f485dSMiklos Szeredi } 1756334f485dSMiklos Szeredi 1757334f485dSMiklos Szeredi /* 1758334f485dSMiklos Szeredi * Write a single reply to a request. First the header is copied from 1759334f485dSMiklos Szeredi * the write buffer. The request is then searched on the processing 1760334f485dSMiklos Szeredi * list by the unique ID found in the header. If found, then remove 1761334f485dSMiklos Szeredi * it from the list and copy the rest of the buffer to the request. 1762334f485dSMiklos Szeredi * The request is finished by calling request_end() 1763334f485dSMiklos Szeredi */ 1764dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_conn *fc, 1765dd3bb14fSMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1766334f485dSMiklos Szeredi { 1767334f485dSMiklos Szeredi int err; 1768334f485dSMiklos Szeredi struct fuse_req *req; 1769334f485dSMiklos Szeredi struct fuse_out_header oh; 1770334f485dSMiklos Szeredi 1771334f485dSMiklos Szeredi if (nbytes < sizeof(struct fuse_out_header)) 1772334f485dSMiklos Szeredi return -EINVAL; 1773334f485dSMiklos Szeredi 1774dd3bb14fSMiklos Szeredi err = fuse_copy_one(cs, &oh, sizeof(oh)); 1775334f485dSMiklos Szeredi if (err) 1776334f485dSMiklos Szeredi goto err_finish; 17778599396bSTejun Heo 1778334f485dSMiklos Szeredi err = -EINVAL; 17798599396bSTejun Heo if (oh.len != nbytes) 17808599396bSTejun Heo goto err_finish; 17818599396bSTejun Heo 17828599396bSTejun Heo /* 17838599396bSTejun Heo * Zero oh.unique indicates unsolicited notification message 17848599396bSTejun Heo * and error contains notification code. 17858599396bSTejun Heo */ 17868599396bSTejun Heo if (!oh.unique) { 1787dd3bb14fSMiklos Szeredi err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs); 17888599396bSTejun Heo return err ? err : nbytes; 17898599396bSTejun Heo } 17908599396bSTejun Heo 17918599396bSTejun Heo err = -EINVAL; 17928599396bSTejun Heo if (oh.error <= -1000 || oh.error > 0) 1793334f485dSMiklos Szeredi goto err_finish; 1794334f485dSMiklos Szeredi 1795d7133114SMiklos Szeredi spin_lock(&fc->lock); 179669a53bf2SMiklos Szeredi err = -ENOENT; 179769a53bf2SMiklos Szeredi if (!fc->connected) 179869a53bf2SMiklos Szeredi goto err_unlock; 179969a53bf2SMiklos Szeredi 1800334f485dSMiklos Szeredi req = request_find(fc, oh.unique); 1801334f485dSMiklos Szeredi if (!req) 1802334f485dSMiklos Szeredi goto err_unlock; 1803334f485dSMiklos Szeredi 1804f9a2842eSMiklos Szeredi if (req->aborted) { 1805d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1806dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1807d7133114SMiklos Szeredi spin_lock(&fc->lock); 1808222f1d69SMiklos Szeredi request_end(fc, req); 1809334f485dSMiklos Szeredi return -ENOENT; 1810334f485dSMiklos Szeredi } 1811a4d27e75SMiklos Szeredi /* Is it an interrupt reply? */ 1812a4d27e75SMiklos Szeredi if (req->intr_unique == oh.unique) { 1813a4d27e75SMiklos Szeredi err = -EINVAL; 1814a4d27e75SMiklos Szeredi if (nbytes != sizeof(struct fuse_out_header)) 1815a4d27e75SMiklos Szeredi goto err_unlock; 1816a4d27e75SMiklos Szeredi 1817a4d27e75SMiklos Szeredi if (oh.error == -ENOSYS) 1818a4d27e75SMiklos Szeredi fc->no_interrupt = 1; 1819a4d27e75SMiklos Szeredi else if (oh.error == -EAGAIN) 1820a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 1821a4d27e75SMiklos Szeredi 1822a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 1823dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1824a4d27e75SMiklos Szeredi return nbytes; 1825a4d27e75SMiklos Szeredi } 1826a4d27e75SMiklos Szeredi 1827a4d27e75SMiklos Szeredi req->state = FUSE_REQ_WRITING; 1828d77a1d5bSMiklos Szeredi list_move(&req->list, &fc->io); 1829334f485dSMiklos Szeredi req->out.h = oh; 1830334f485dSMiklos Szeredi req->locked = 1; 1831dd3bb14fSMiklos Szeredi cs->req = req; 1832ce534fb0SMiklos Szeredi if (!req->out.page_replace) 1833ce534fb0SMiklos Szeredi cs->move_pages = 0; 1834d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1835334f485dSMiklos Szeredi 1836dd3bb14fSMiklos Szeredi err = copy_out_args(cs, &req->out, nbytes); 1837dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1838334f485dSMiklos Szeredi 1839d7133114SMiklos Szeredi spin_lock(&fc->lock); 1840334f485dSMiklos Szeredi req->locked = 0; 1841334f485dSMiklos Szeredi if (!err) { 1842f9a2842eSMiklos Szeredi if (req->aborted) 1843334f485dSMiklos Szeredi err = -ENOENT; 1844f9a2842eSMiklos Szeredi } else if (!req->aborted) 1845334f485dSMiklos Szeredi req->out.h.error = -EIO; 1846334f485dSMiklos Szeredi request_end(fc, req); 1847334f485dSMiklos Szeredi 1848334f485dSMiklos Szeredi return err ? err : nbytes; 1849334f485dSMiklos Szeredi 1850334f485dSMiklos Szeredi err_unlock: 1851d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1852334f485dSMiklos Szeredi err_finish: 1853dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1854334f485dSMiklos Szeredi return err; 1855334f485dSMiklos Szeredi } 1856334f485dSMiklos Szeredi 1857dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, 1858dd3bb14fSMiklos Szeredi unsigned long nr_segs, loff_t pos) 1859dd3bb14fSMiklos Szeredi { 1860dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1861dd3bb14fSMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp); 1862dd3bb14fSMiklos Szeredi if (!fc) 1863dd3bb14fSMiklos Szeredi return -EPERM; 1864dd3bb14fSMiklos Szeredi 1865c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 0, iov, nr_segs); 1866dd3bb14fSMiklos Szeredi 1867dd3bb14fSMiklos Szeredi return fuse_dev_do_write(fc, &cs, iov_length(iov, nr_segs)); 1868dd3bb14fSMiklos Szeredi } 1869dd3bb14fSMiklos Szeredi 1870dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, 1871dd3bb14fSMiklos Szeredi struct file *out, loff_t *ppos, 1872dd3bb14fSMiklos Szeredi size_t len, unsigned int flags) 1873dd3bb14fSMiklos Szeredi { 1874dd3bb14fSMiklos Szeredi unsigned nbuf; 1875dd3bb14fSMiklos Szeredi unsigned idx; 1876dd3bb14fSMiklos Szeredi struct pipe_buffer *bufs; 1877dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1878dd3bb14fSMiklos Szeredi struct fuse_conn *fc; 1879dd3bb14fSMiklos Szeredi size_t rem; 1880dd3bb14fSMiklos Szeredi ssize_t ret; 1881dd3bb14fSMiklos Szeredi 1882dd3bb14fSMiklos Szeredi fc = fuse_get_conn(out); 1883dd3bb14fSMiklos Szeredi if (!fc) 1884dd3bb14fSMiklos Szeredi return -EPERM; 1885dd3bb14fSMiklos Szeredi 1886dd3bb14fSMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1887dd3bb14fSMiklos Szeredi if (!bufs) 1888dd3bb14fSMiklos Szeredi return -ENOMEM; 1889dd3bb14fSMiklos Szeredi 1890dd3bb14fSMiklos Szeredi pipe_lock(pipe); 1891dd3bb14fSMiklos Szeredi nbuf = 0; 1892dd3bb14fSMiklos Szeredi rem = 0; 1893dd3bb14fSMiklos Szeredi for (idx = 0; idx < pipe->nrbufs && rem < len; idx++) 1894dd3bb14fSMiklos Szeredi rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len; 1895dd3bb14fSMiklos Szeredi 1896dd3bb14fSMiklos Szeredi ret = -EINVAL; 1897dd3bb14fSMiklos Szeredi if (rem < len) { 1898dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 1899dd3bb14fSMiklos Szeredi goto out; 1900dd3bb14fSMiklos Szeredi } 1901dd3bb14fSMiklos Szeredi 1902dd3bb14fSMiklos Szeredi rem = len; 1903dd3bb14fSMiklos Szeredi while (rem) { 1904dd3bb14fSMiklos Szeredi struct pipe_buffer *ibuf; 1905dd3bb14fSMiklos Szeredi struct pipe_buffer *obuf; 1906dd3bb14fSMiklos Szeredi 1907dd3bb14fSMiklos Szeredi BUG_ON(nbuf >= pipe->buffers); 1908dd3bb14fSMiklos Szeredi BUG_ON(!pipe->nrbufs); 1909dd3bb14fSMiklos Szeredi ibuf = &pipe->bufs[pipe->curbuf]; 1910dd3bb14fSMiklos Szeredi obuf = &bufs[nbuf]; 1911dd3bb14fSMiklos Szeredi 1912dd3bb14fSMiklos Szeredi if (rem >= ibuf->len) { 1913dd3bb14fSMiklos Szeredi *obuf = *ibuf; 1914dd3bb14fSMiklos Szeredi ibuf->ops = NULL; 1915dd3bb14fSMiklos Szeredi pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); 1916dd3bb14fSMiklos Szeredi pipe->nrbufs--; 1917dd3bb14fSMiklos Szeredi } else { 1918dd3bb14fSMiklos Szeredi ibuf->ops->get(pipe, ibuf); 1919dd3bb14fSMiklos Szeredi *obuf = *ibuf; 1920dd3bb14fSMiklos Szeredi obuf->flags &= ~PIPE_BUF_FLAG_GIFT; 1921dd3bb14fSMiklos Szeredi obuf->len = rem; 1922dd3bb14fSMiklos Szeredi ibuf->offset += obuf->len; 1923dd3bb14fSMiklos Szeredi ibuf->len -= obuf->len; 1924dd3bb14fSMiklos Szeredi } 1925dd3bb14fSMiklos Szeredi nbuf++; 1926dd3bb14fSMiklos Szeredi rem -= obuf->len; 1927dd3bb14fSMiklos Szeredi } 1928dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 1929dd3bb14fSMiklos Szeredi 1930c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 0, NULL, nbuf); 1931dd3bb14fSMiklos Szeredi cs.pipebufs = bufs; 1932dd3bb14fSMiklos Szeredi cs.pipe = pipe; 1933dd3bb14fSMiklos Szeredi 1934ce534fb0SMiklos Szeredi if (flags & SPLICE_F_MOVE) 1935ce534fb0SMiklos Szeredi cs.move_pages = 1; 1936ce534fb0SMiklos Szeredi 1937dd3bb14fSMiklos Szeredi ret = fuse_dev_do_write(fc, &cs, len); 1938dd3bb14fSMiklos Szeredi 1939dd3bb14fSMiklos Szeredi for (idx = 0; idx < nbuf; idx++) { 1940dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = &bufs[idx]; 1941dd3bb14fSMiklos Szeredi buf->ops->release(pipe, buf); 1942dd3bb14fSMiklos Szeredi } 1943dd3bb14fSMiklos Szeredi out: 1944dd3bb14fSMiklos Szeredi kfree(bufs); 1945dd3bb14fSMiklos Szeredi return ret; 1946dd3bb14fSMiklos Szeredi } 1947dd3bb14fSMiklos Szeredi 1948334f485dSMiklos Szeredi static unsigned fuse_dev_poll(struct file *file, poll_table *wait) 1949334f485dSMiklos Szeredi { 1950334f485dSMiklos Szeredi unsigned mask = POLLOUT | POLLWRNORM; 19517025d9adSMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 1952334f485dSMiklos Szeredi if (!fc) 19537025d9adSMiklos Szeredi return POLLERR; 1954334f485dSMiklos Szeredi 1955334f485dSMiklos Szeredi poll_wait(file, &fc->waitq, wait); 1956334f485dSMiklos Szeredi 1957d7133114SMiklos Szeredi spin_lock(&fc->lock); 19587025d9adSMiklos Szeredi if (!fc->connected) 19597025d9adSMiklos Szeredi mask = POLLERR; 1960a4d27e75SMiklos Szeredi else if (request_pending(fc)) 1961334f485dSMiklos Szeredi mask |= POLLIN | POLLRDNORM; 1962d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1963334f485dSMiklos Szeredi 1964334f485dSMiklos Szeredi return mask; 1965334f485dSMiklos Szeredi } 1966334f485dSMiklos Szeredi 196769a53bf2SMiklos Szeredi /* 196869a53bf2SMiklos Szeredi * Abort all requests on the given list (pending or processing) 196969a53bf2SMiklos Szeredi * 1970d7133114SMiklos Szeredi * This function releases and reacquires fc->lock 197169a53bf2SMiklos Szeredi */ 1972334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head) 1973b9ca67b2SMiklos Szeredi __releases(fc->lock) 1974b9ca67b2SMiklos Szeredi __acquires(fc->lock) 1975334f485dSMiklos Szeredi { 1976334f485dSMiklos Szeredi while (!list_empty(head)) { 1977334f485dSMiklos Szeredi struct fuse_req *req; 1978334f485dSMiklos Szeredi req = list_entry(head->next, struct fuse_req, list); 1979334f485dSMiklos Szeredi req->out.h.error = -ECONNABORTED; 1980334f485dSMiklos Szeredi request_end(fc, req); 1981d7133114SMiklos Szeredi spin_lock(&fc->lock); 1982334f485dSMiklos Szeredi } 1983334f485dSMiklos Szeredi } 1984334f485dSMiklos Szeredi 198569a53bf2SMiklos Szeredi /* 198669a53bf2SMiklos Szeredi * Abort requests under I/O 198769a53bf2SMiklos Szeredi * 1988f9a2842eSMiklos Szeredi * The requests are set to aborted and finished, and the request 198969a53bf2SMiklos Szeredi * waiter is woken up. This will make request_wait_answer() wait 199069a53bf2SMiklos Szeredi * until the request is unlocked and then return. 199164c6d8edSMiklos Szeredi * 199264c6d8edSMiklos Szeredi * If the request is asynchronous, then the end function needs to be 199364c6d8edSMiklos Szeredi * called after waiting for the request to be unlocked (if it was 199464c6d8edSMiklos Szeredi * locked). 199569a53bf2SMiklos Szeredi */ 199669a53bf2SMiklos Szeredi static void end_io_requests(struct fuse_conn *fc) 1997b9ca67b2SMiklos Szeredi __releases(fc->lock) 1998b9ca67b2SMiklos Szeredi __acquires(fc->lock) 199969a53bf2SMiklos Szeredi { 200069a53bf2SMiklos Szeredi while (!list_empty(&fc->io)) { 200164c6d8edSMiklos Szeredi struct fuse_req *req = 200264c6d8edSMiklos Szeredi list_entry(fc->io.next, struct fuse_req, list); 200364c6d8edSMiklos Szeredi void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; 200464c6d8edSMiklos Szeredi 2005f9a2842eSMiklos Szeredi req->aborted = 1; 200669a53bf2SMiklos Szeredi req->out.h.error = -ECONNABORTED; 200769a53bf2SMiklos Szeredi req->state = FUSE_REQ_FINISHED; 200869a53bf2SMiklos Szeredi list_del_init(&req->list); 200969a53bf2SMiklos Szeredi wake_up(&req->waitq); 201064c6d8edSMiklos Szeredi if (end) { 201164c6d8edSMiklos Szeredi req->end = NULL; 201264c6d8edSMiklos Szeredi __fuse_get_request(req); 2013d7133114SMiklos Szeredi spin_unlock(&fc->lock); 201464c6d8edSMiklos Szeredi wait_event(req->waitq, !req->locked); 201564c6d8edSMiklos Szeredi end(fc, req); 2016e9bb09ddSTejun Heo fuse_put_request(fc, req); 2017d7133114SMiklos Szeredi spin_lock(&fc->lock); 201864c6d8edSMiklos Szeredi } 201969a53bf2SMiklos Szeredi } 202069a53bf2SMiklos Szeredi } 202169a53bf2SMiklos Szeredi 2022595afaf9SMiklos Szeredi static void end_queued_requests(struct fuse_conn *fc) 2023b9ca67b2SMiklos Szeredi __releases(fc->lock) 2024b9ca67b2SMiklos Szeredi __acquires(fc->lock) 2025595afaf9SMiklos Szeredi { 2026595afaf9SMiklos Szeredi fc->max_background = UINT_MAX; 2027595afaf9SMiklos Szeredi flush_bg_queue(fc); 2028595afaf9SMiklos Szeredi end_requests(fc, &fc->pending); 2029595afaf9SMiklos Szeredi end_requests(fc, &fc->processing); 203007e77dcaSMiklos Szeredi while (forget_pending(fc)) 203102c048b9SMiklos Szeredi kfree(dequeue_forget(fc, 1, NULL)); 2032595afaf9SMiklos Szeredi } 2033595afaf9SMiklos Szeredi 2034357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc) 2035357ccf2bSBryan Green { 2036357ccf2bSBryan Green struct rb_node *p; 2037357ccf2bSBryan Green 2038357ccf2bSBryan Green p = rb_first(&fc->polled_files); 2039357ccf2bSBryan Green 2040357ccf2bSBryan Green while (p) { 2041357ccf2bSBryan Green struct fuse_file *ff; 2042357ccf2bSBryan Green ff = rb_entry(p, struct fuse_file, polled_node); 2043357ccf2bSBryan Green wake_up_interruptible_all(&ff->poll_wait); 2044357ccf2bSBryan Green 2045357ccf2bSBryan Green p = rb_next(p); 2046357ccf2bSBryan Green } 2047357ccf2bSBryan Green } 2048357ccf2bSBryan Green 204969a53bf2SMiklos Szeredi /* 205069a53bf2SMiklos Szeredi * Abort all requests. 205169a53bf2SMiklos Szeredi * 205269a53bf2SMiklos Szeredi * Emergency exit in case of a malicious or accidental deadlock, or 205369a53bf2SMiklos Szeredi * just a hung filesystem. 205469a53bf2SMiklos Szeredi * 205569a53bf2SMiklos Szeredi * The same effect is usually achievable through killing the 205669a53bf2SMiklos Szeredi * filesystem daemon and all users of the filesystem. The exception 205769a53bf2SMiklos Szeredi * is the combination of an asynchronous request and the tricky 205869a53bf2SMiklos Szeredi * deadlock (see Documentation/filesystems/fuse.txt). 205969a53bf2SMiklos Szeredi * 206069a53bf2SMiklos Szeredi * During the aborting, progression of requests from the pending and 206169a53bf2SMiklos Szeredi * processing lists onto the io list, and progression of new requests 206269a53bf2SMiklos Szeredi * onto the pending list is prevented by req->connected being false. 206369a53bf2SMiklos Szeredi * 206469a53bf2SMiklos Szeredi * Progression of requests under I/O to the processing list is 2065f9a2842eSMiklos Szeredi * prevented by the req->aborted flag being true for these requests. 2066f9a2842eSMiklos Szeredi * For this reason requests on the io list must be aborted first. 206769a53bf2SMiklos Szeredi */ 206869a53bf2SMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc) 206969a53bf2SMiklos Szeredi { 2070d7133114SMiklos Szeredi spin_lock(&fc->lock); 207169a53bf2SMiklos Szeredi if (fc->connected) { 207269a53bf2SMiklos Szeredi fc->connected = 0; 207351eb01e7SMiklos Szeredi fc->blocked = 0; 207469a53bf2SMiklos Szeredi end_io_requests(fc); 2075595afaf9SMiklos Szeredi end_queued_requests(fc); 2076357ccf2bSBryan Green end_polls(fc); 207769a53bf2SMiklos Szeredi wake_up_all(&fc->waitq); 207851eb01e7SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 2079385a17bfSJeff Dike kill_fasync(&fc->fasync, SIGIO, POLL_IN); 208069a53bf2SMiklos Szeredi } 2081d7133114SMiklos Szeredi spin_unlock(&fc->lock); 208269a53bf2SMiklos Szeredi } 208308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn); 208469a53bf2SMiklos Szeredi 208508cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file) 2086334f485dSMiklos Szeredi { 20870720b315SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 2088334f485dSMiklos Szeredi if (fc) { 2089d7133114SMiklos Szeredi spin_lock(&fc->lock); 20901e9a4ed9SMiklos Szeredi fc->connected = 0; 2091595afaf9SMiklos Szeredi fc->blocked = 0; 2092595afaf9SMiklos Szeredi end_queued_requests(fc); 2093357ccf2bSBryan Green end_polls(fc); 2094595afaf9SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 2095d7133114SMiklos Szeredi spin_unlock(&fc->lock); 2096bafa9654SMiklos Szeredi fuse_conn_put(fc); 2097385a17bfSJeff Dike } 2098f543f253SMiklos Szeredi 2099334f485dSMiklos Szeredi return 0; 2100334f485dSMiklos Szeredi } 210108cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release); 2102334f485dSMiklos Szeredi 2103385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on) 2104385a17bfSJeff Dike { 2105385a17bfSJeff Dike struct fuse_conn *fc = fuse_get_conn(file); 2106385a17bfSJeff Dike if (!fc) 2107a87046d8SMiklos Szeredi return -EPERM; 2108385a17bfSJeff Dike 2109385a17bfSJeff Dike /* No locking - fasync_helper does its own locking */ 2110385a17bfSJeff Dike return fasync_helper(fd, file, on, &fc->fasync); 2111385a17bfSJeff Dike } 2112385a17bfSJeff Dike 21134b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = { 2114334f485dSMiklos Szeredi .owner = THIS_MODULE, 2115334f485dSMiklos Szeredi .llseek = no_llseek, 2116ee0b3e67SBadari Pulavarty .read = do_sync_read, 2117ee0b3e67SBadari Pulavarty .aio_read = fuse_dev_read, 2118c3021629SMiklos Szeredi .splice_read = fuse_dev_splice_read, 2119ee0b3e67SBadari Pulavarty .write = do_sync_write, 2120ee0b3e67SBadari Pulavarty .aio_write = fuse_dev_write, 2121dd3bb14fSMiklos Szeredi .splice_write = fuse_dev_splice_write, 2122334f485dSMiklos Szeredi .poll = fuse_dev_poll, 2123334f485dSMiklos Szeredi .release = fuse_dev_release, 2124385a17bfSJeff Dike .fasync = fuse_dev_fasync, 2125334f485dSMiklos Szeredi }; 212608cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations); 2127334f485dSMiklos Szeredi 2128334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = { 2129334f485dSMiklos Szeredi .minor = FUSE_MINOR, 2130334f485dSMiklos Szeredi .name = "fuse", 2131334f485dSMiklos Szeredi .fops = &fuse_dev_operations, 2132334f485dSMiklos Szeredi }; 2133334f485dSMiklos Szeredi 2134334f485dSMiklos Szeredi int __init fuse_dev_init(void) 2135334f485dSMiklos Szeredi { 2136334f485dSMiklos Szeredi int err = -ENOMEM; 2137334f485dSMiklos Szeredi fuse_req_cachep = kmem_cache_create("fuse_request", 2138334f485dSMiklos Szeredi sizeof(struct fuse_req), 213920c2df83SPaul Mundt 0, 0, NULL); 2140334f485dSMiklos Szeredi if (!fuse_req_cachep) 2141334f485dSMiklos Szeredi goto out; 2142334f485dSMiklos Szeredi 2143334f485dSMiklos Szeredi err = misc_register(&fuse_miscdevice); 2144334f485dSMiklos Szeredi if (err) 2145334f485dSMiklos Szeredi goto out_cache_clean; 2146334f485dSMiklos Szeredi 2147334f485dSMiklos Szeredi return 0; 2148334f485dSMiklos Szeredi 2149334f485dSMiklos Szeredi out_cache_clean: 2150334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2151334f485dSMiklos Szeredi out: 2152334f485dSMiklos Szeredi return err; 2153334f485dSMiklos Szeredi } 2154334f485dSMiklos Szeredi 2155334f485dSMiklos Szeredi void fuse_dev_cleanup(void) 2156334f485dSMiklos Szeredi { 2157334f485dSMiklos Szeredi misc_deregister(&fuse_miscdevice); 2158334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2159334f485dSMiklos Szeredi } 2160