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, 384250c066SMaxim Patlasov unsigned npages) 39334f485dSMiklos Szeredi { 40334f485dSMiklos Szeredi memset(req, 0, sizeof(*req)); 414250c066SMaxim Patlasov memset(pages, 0, sizeof(*pages) * npages); 42334f485dSMiklos Szeredi INIT_LIST_HEAD(&req->list); 43a4d27e75SMiklos Szeredi INIT_LIST_HEAD(&req->intr_entry); 44334f485dSMiklos Szeredi init_waitqueue_head(&req->waitq); 45334f485dSMiklos Szeredi atomic_set(&req->count, 1); 464250c066SMaxim Patlasov req->pages = pages; 474250c066SMaxim Patlasov req->max_pages = npages; 48334f485dSMiklos Szeredi } 49334f485dSMiklos Szeredi 504250c066SMaxim Patlasov static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) 51334f485dSMiklos Szeredi { 524250c066SMaxim Patlasov struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, flags); 534250c066SMaxim Patlasov if (req) { 544250c066SMaxim Patlasov struct page **pages; 554250c066SMaxim Patlasov 564250c066SMaxim Patlasov if (npages <= FUSE_REQ_INLINE_PAGES) 574250c066SMaxim Patlasov pages = req->inline_pages; 584250c066SMaxim Patlasov else 594250c066SMaxim Patlasov pages = kmalloc(sizeof(struct page *) * npages, flags); 604250c066SMaxim Patlasov 614250c066SMaxim Patlasov if (!pages) { 624250c066SMaxim Patlasov kmem_cache_free(fuse_req_cachep, req); 634250c066SMaxim Patlasov return NULL; 644250c066SMaxim Patlasov } 654250c066SMaxim Patlasov 664250c066SMaxim Patlasov fuse_request_init(req, pages, npages); 674250c066SMaxim Patlasov } 68334f485dSMiklos Szeredi return req; 69334f485dSMiklos Szeredi } 704250c066SMaxim Patlasov 714250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc(unsigned npages) 724250c066SMaxim Patlasov { 734250c066SMaxim Patlasov return __fuse_request_alloc(npages, GFP_KERNEL); 744250c066SMaxim Patlasov } 7508cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_alloc); 76334f485dSMiklos Szeredi 774250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc_nofs(unsigned npages) 783be5a52bSMiklos Szeredi { 794250c066SMaxim Patlasov return __fuse_request_alloc(npages, GFP_NOFS); 803be5a52bSMiklos Szeredi } 813be5a52bSMiklos Szeredi 82334f485dSMiklos Szeredi void fuse_request_free(struct fuse_req *req) 83334f485dSMiklos Szeredi { 844250c066SMaxim Patlasov if (req->pages != req->inline_pages) 854250c066SMaxim Patlasov kfree(req->pages); 86334f485dSMiklos Szeredi kmem_cache_free(fuse_req_cachep, req); 87334f485dSMiklos Szeredi } 88334f485dSMiklos Szeredi 898bfc016dSMiklos Szeredi static void block_sigs(sigset_t *oldset) 90334f485dSMiklos Szeredi { 91334f485dSMiklos Szeredi sigset_t mask; 92334f485dSMiklos Szeredi 93334f485dSMiklos Szeredi siginitsetinv(&mask, sigmask(SIGKILL)); 94334f485dSMiklos Szeredi sigprocmask(SIG_BLOCK, &mask, oldset); 95334f485dSMiklos Szeredi } 96334f485dSMiklos Szeredi 978bfc016dSMiklos Szeredi static void restore_sigs(sigset_t *oldset) 98334f485dSMiklos Szeredi { 99334f485dSMiklos Szeredi sigprocmask(SIG_SETMASK, oldset, NULL); 100334f485dSMiklos Szeredi } 101334f485dSMiklos Szeredi 102334f485dSMiklos Szeredi static void __fuse_get_request(struct fuse_req *req) 103334f485dSMiklos Szeredi { 104334f485dSMiklos Szeredi atomic_inc(&req->count); 105334f485dSMiklos Szeredi } 106334f485dSMiklos Szeredi 107334f485dSMiklos Szeredi /* Must be called with > 1 refcount */ 108334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req) 109334f485dSMiklos Szeredi { 110334f485dSMiklos Szeredi BUG_ON(atomic_read(&req->count) < 2); 111334f485dSMiklos Szeredi atomic_dec(&req->count); 112334f485dSMiklos Szeredi } 113334f485dSMiklos Szeredi 11433649c91SMiklos Szeredi static void fuse_req_init_context(struct fuse_req *req) 11533649c91SMiklos Szeredi { 116499dcf20SEric W. Biederman req->in.h.uid = from_kuid_munged(&init_user_ns, current_fsuid()); 117499dcf20SEric W. Biederman req->in.h.gid = from_kgid_munged(&init_user_ns, current_fsgid()); 11833649c91SMiklos Szeredi req->in.h.pid = current->pid; 11933649c91SMiklos Szeredi } 12033649c91SMiklos Szeredi 121b111c8c0SMaxim Patlasov struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages) 122334f485dSMiklos Szeredi { 12308a53cdcSMiklos Szeredi struct fuse_req *req; 12408a53cdcSMiklos Szeredi sigset_t oldset; 1259bc5dddaSMiklos Szeredi int intr; 12608a53cdcSMiklos Szeredi int err; 12708a53cdcSMiklos Szeredi 1289bc5dddaSMiklos Szeredi atomic_inc(&fc->num_waiting); 12908a53cdcSMiklos Szeredi block_sigs(&oldset); 1309bc5dddaSMiklos Szeredi intr = wait_event_interruptible(fc->blocked_waitq, !fc->blocked); 13108a53cdcSMiklos Szeredi restore_sigs(&oldset); 1329bc5dddaSMiklos Szeredi err = -EINTR; 1339bc5dddaSMiklos Szeredi if (intr) 1349bc5dddaSMiklos Szeredi goto out; 13508a53cdcSMiklos Szeredi 13651eb01e7SMiklos Szeredi err = -ENOTCONN; 13751eb01e7SMiklos Szeredi if (!fc->connected) 13851eb01e7SMiklos Szeredi goto out; 13951eb01e7SMiklos Szeredi 140b111c8c0SMaxim Patlasov req = fuse_request_alloc(npages); 1419bc5dddaSMiklos Szeredi err = -ENOMEM; 142ce1d5a49SMiklos Szeredi if (!req) 1439bc5dddaSMiklos Szeredi goto out; 144334f485dSMiklos Szeredi 14533649c91SMiklos Szeredi fuse_req_init_context(req); 1469bc5dddaSMiklos Szeredi req->waiting = 1; 147334f485dSMiklos Szeredi return req; 1489bc5dddaSMiklos Szeredi 1499bc5dddaSMiklos Szeredi out: 1509bc5dddaSMiklos Szeredi atomic_dec(&fc->num_waiting); 1519bc5dddaSMiklos Szeredi return ERR_PTR(err); 152334f485dSMiklos Szeredi } 15308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_get_req); 154334f485dSMiklos Szeredi 15533649c91SMiklos Szeredi /* 15633649c91SMiklos Szeredi * Return request in fuse_file->reserved_req. However that may 15733649c91SMiklos Szeredi * currently be in use. If that is the case, wait for it to become 15833649c91SMiklos Szeredi * available. 15933649c91SMiklos Szeredi */ 16033649c91SMiklos Szeredi static struct fuse_req *get_reserved_req(struct fuse_conn *fc, 16133649c91SMiklos Szeredi struct file *file) 16233649c91SMiklos Szeredi { 16333649c91SMiklos Szeredi struct fuse_req *req = NULL; 16433649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 16533649c91SMiklos Szeredi 16633649c91SMiklos Szeredi do { 167de5e3decSMiklos Szeredi wait_event(fc->reserved_req_waitq, ff->reserved_req); 16833649c91SMiklos Szeredi spin_lock(&fc->lock); 16933649c91SMiklos Szeredi if (ff->reserved_req) { 17033649c91SMiklos Szeredi req = ff->reserved_req; 17133649c91SMiklos Szeredi ff->reserved_req = NULL; 172cb0942b8SAl Viro req->stolen_file = get_file(file); 17333649c91SMiklos Szeredi } 17433649c91SMiklos Szeredi spin_unlock(&fc->lock); 17533649c91SMiklos Szeredi } while (!req); 17633649c91SMiklos Szeredi 17733649c91SMiklos Szeredi return req; 17833649c91SMiklos Szeredi } 17933649c91SMiklos Szeredi 18033649c91SMiklos Szeredi /* 18133649c91SMiklos Szeredi * Put stolen request back into fuse_file->reserved_req 18233649c91SMiklos Szeredi */ 18333649c91SMiklos Szeredi static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req) 18433649c91SMiklos Szeredi { 18533649c91SMiklos Szeredi struct file *file = req->stolen_file; 18633649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 18733649c91SMiklos Szeredi 18833649c91SMiklos Szeredi spin_lock(&fc->lock); 1894250c066SMaxim Patlasov fuse_request_init(req, req->pages, req->max_pages); 19033649c91SMiklos Szeredi BUG_ON(ff->reserved_req); 19133649c91SMiklos Szeredi ff->reserved_req = req; 192de5e3decSMiklos Szeredi wake_up_all(&fc->reserved_req_waitq); 19333649c91SMiklos Szeredi spin_unlock(&fc->lock); 19433649c91SMiklos Szeredi fput(file); 19533649c91SMiklos Szeredi } 19633649c91SMiklos Szeredi 19733649c91SMiklos Szeredi /* 19833649c91SMiklos Szeredi * Gets a requests for a file operation, always succeeds 19933649c91SMiklos Szeredi * 20033649c91SMiklos Szeredi * This is used for sending the FLUSH request, which must get to 20133649c91SMiklos Szeredi * userspace, due to POSIX locks which may need to be unlocked. 20233649c91SMiklos Szeredi * 20333649c91SMiklos Szeredi * If allocation fails due to OOM, use the reserved request in 20433649c91SMiklos Szeredi * fuse_file. 20533649c91SMiklos Szeredi * 20633649c91SMiklos Szeredi * This is very unlikely to deadlock accidentally, since the 20733649c91SMiklos Szeredi * filesystem should not have it's own file open. If deadlock is 20833649c91SMiklos Szeredi * intentional, it can still be broken by "aborting" the filesystem. 20933649c91SMiklos Szeredi */ 210b111c8c0SMaxim Patlasov struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, 211b111c8c0SMaxim Patlasov struct file *file) 21233649c91SMiklos Szeredi { 21333649c91SMiklos Szeredi struct fuse_req *req; 21433649c91SMiklos Szeredi 21533649c91SMiklos Szeredi atomic_inc(&fc->num_waiting); 21633649c91SMiklos Szeredi wait_event(fc->blocked_waitq, !fc->blocked); 217b111c8c0SMaxim Patlasov req = fuse_request_alloc(0); 21833649c91SMiklos Szeredi if (!req) 21933649c91SMiklos Szeredi req = get_reserved_req(fc, file); 22033649c91SMiklos Szeredi 22133649c91SMiklos Szeredi fuse_req_init_context(req); 22233649c91SMiklos Szeredi req->waiting = 1; 22333649c91SMiklos Szeredi return req; 22433649c91SMiklos Szeredi } 22533649c91SMiklos Szeredi 226334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) 227334f485dSMiklos Szeredi { 2287128ec2aSMiklos Szeredi if (atomic_dec_and_test(&req->count)) { 2299bc5dddaSMiklos Szeredi if (req->waiting) 230ce1d5a49SMiklos Szeredi atomic_dec(&fc->num_waiting); 23133649c91SMiklos Szeredi 23233649c91SMiklos Szeredi if (req->stolen_file) 23333649c91SMiklos Szeredi put_reserved_req(fc, req); 23433649c91SMiklos Szeredi else 235ce1d5a49SMiklos Szeredi fuse_request_free(req); 2367128ec2aSMiklos Szeredi } 2377128ec2aSMiklos Szeredi } 23808cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_put_request); 2397128ec2aSMiklos Szeredi 240d12def1bSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args) 241d12def1bSMiklos Szeredi { 242d12def1bSMiklos Szeredi unsigned nbytes = 0; 243d12def1bSMiklos Szeredi unsigned i; 244d12def1bSMiklos Szeredi 245d12def1bSMiklos Szeredi for (i = 0; i < numargs; i++) 246d12def1bSMiklos Szeredi nbytes += args[i].size; 247d12def1bSMiklos Szeredi 248d12def1bSMiklos Szeredi return nbytes; 249d12def1bSMiklos Szeredi } 250d12def1bSMiklos Szeredi 251d12def1bSMiklos Szeredi static u64 fuse_get_unique(struct fuse_conn *fc) 252d12def1bSMiklos Szeredi { 253d12def1bSMiklos Szeredi fc->reqctr++; 254d12def1bSMiklos Szeredi /* zero is special */ 255d12def1bSMiklos Szeredi if (fc->reqctr == 0) 256d12def1bSMiklos Szeredi fc->reqctr = 1; 257d12def1bSMiklos Szeredi 258d12def1bSMiklos Szeredi return fc->reqctr; 259d12def1bSMiklos Szeredi } 260d12def1bSMiklos Szeredi 261d12def1bSMiklos Szeredi static void queue_request(struct fuse_conn *fc, struct fuse_req *req) 262d12def1bSMiklos Szeredi { 263d12def1bSMiklos Szeredi req->in.h.len = sizeof(struct fuse_in_header) + 264d12def1bSMiklos Szeredi len_args(req->in.numargs, (struct fuse_arg *) req->in.args); 265d12def1bSMiklos Szeredi list_add_tail(&req->list, &fc->pending); 266d12def1bSMiklos Szeredi req->state = FUSE_REQ_PENDING; 267d12def1bSMiklos Szeredi if (!req->waiting) { 268d12def1bSMiklos Szeredi req->waiting = 1; 269d12def1bSMiklos Szeredi atomic_inc(&fc->num_waiting); 270d12def1bSMiklos Szeredi } 271d12def1bSMiklos Szeredi wake_up(&fc->waitq); 272d12def1bSMiklos Szeredi kill_fasync(&fc->fasync, SIGIO, POLL_IN); 273d12def1bSMiklos Szeredi } 274d12def1bSMiklos Szeredi 27507e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, 27607e77dcaSMiklos Szeredi u64 nodeid, u64 nlookup) 27707e77dcaSMiklos Szeredi { 27802c048b9SMiklos Szeredi forget->forget_one.nodeid = nodeid; 27902c048b9SMiklos Szeredi forget->forget_one.nlookup = nlookup; 28007e77dcaSMiklos Szeredi 28107e77dcaSMiklos Szeredi spin_lock(&fc->lock); 2825dfcc87fSMiklos Szeredi if (fc->connected) { 28307e77dcaSMiklos Szeredi fc->forget_list_tail->next = forget; 28407e77dcaSMiklos Szeredi fc->forget_list_tail = forget; 28507e77dcaSMiklos Szeredi wake_up(&fc->waitq); 28607e77dcaSMiklos Szeredi kill_fasync(&fc->fasync, SIGIO, POLL_IN); 2875dfcc87fSMiklos Szeredi } else { 2885dfcc87fSMiklos Szeredi kfree(forget); 2895dfcc87fSMiklos Szeredi } 29007e77dcaSMiklos Szeredi spin_unlock(&fc->lock); 29107e77dcaSMiklos Szeredi } 29207e77dcaSMiklos Szeredi 293d12def1bSMiklos Szeredi static void flush_bg_queue(struct fuse_conn *fc) 294d12def1bSMiklos Szeredi { 2957a6d3c8bSCsaba Henk while (fc->active_background < fc->max_background && 296d12def1bSMiklos Szeredi !list_empty(&fc->bg_queue)) { 297d12def1bSMiklos Szeredi struct fuse_req *req; 298d12def1bSMiklos Szeredi 299d12def1bSMiklos Szeredi req = list_entry(fc->bg_queue.next, struct fuse_req, list); 300d12def1bSMiklos Szeredi list_del(&req->list); 301d12def1bSMiklos Szeredi fc->active_background++; 3022d45ba38SMiklos Szeredi req->in.h.unique = fuse_get_unique(fc); 303d12def1bSMiklos Szeredi queue_request(fc, req); 304d12def1bSMiklos Szeredi } 305d12def1bSMiklos Szeredi } 306d12def1bSMiklos Szeredi 3076dbbcb12SMiklos Szeredi /* 308334f485dSMiklos Szeredi * This function is called when a request is finished. Either a reply 309f9a2842eSMiklos Szeredi * has arrived or it was aborted (and not yet sent) or some error 310f43b155aSMiklos Szeredi * occurred during communication with userspace, or the device file 31151eb01e7SMiklos Szeredi * was closed. The requester thread is woken up (if still waiting), 31251eb01e7SMiklos Szeredi * the 'end' callback is called if given, else the reference to the 31351eb01e7SMiklos Szeredi * request is released 3147128ec2aSMiklos Szeredi * 315d7133114SMiklos Szeredi * Called with fc->lock, unlocks it 316334f485dSMiklos Szeredi */ 317334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req) 318b9ca67b2SMiklos Szeredi __releases(fc->lock) 319334f485dSMiklos Szeredi { 3207128ec2aSMiklos Szeredi void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; 3217128ec2aSMiklos Szeredi req->end = NULL; 32251eb01e7SMiklos Szeredi list_del(&req->list); 323a4d27e75SMiklos Szeredi list_del(&req->intr_entry); 32451eb01e7SMiklos Szeredi req->state = FUSE_REQ_FINISHED; 32551eb01e7SMiklos Szeredi if (req->background) { 3267a6d3c8bSCsaba Henk if (fc->num_background == fc->max_background) { 32751eb01e7SMiklos Szeredi fc->blocked = 0; 32851eb01e7SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 32951eb01e7SMiklos Szeredi } 3307a6d3c8bSCsaba Henk if (fc->num_background == fc->congestion_threshold && 331a325f9b9STejun Heo fc->connected && fc->bdi_initialized) { 3328aa7e847SJens Axboe clear_bdi_congested(&fc->bdi, BLK_RW_SYNC); 3338aa7e847SJens Axboe clear_bdi_congested(&fc->bdi, BLK_RW_ASYNC); 334f92b99b9SMiklos Szeredi } 33551eb01e7SMiklos Szeredi fc->num_background--; 336d12def1bSMiklos Szeredi fc->active_background--; 337d12def1bSMiklos Szeredi flush_bg_queue(fc); 33851eb01e7SMiklos Szeredi } 339d7133114SMiklos Szeredi spin_unlock(&fc->lock); 34051eb01e7SMiklos Szeredi wake_up(&req->waitq); 34164c6d8edSMiklos Szeredi if (end) 34264c6d8edSMiklos Szeredi end(fc, req); 343f43b155aSMiklos Szeredi fuse_put_request(fc, req); 344334f485dSMiklos Szeredi } 345334f485dSMiklos Szeredi 346a4d27e75SMiklos Szeredi static void wait_answer_interruptible(struct fuse_conn *fc, 347a4d27e75SMiklos Szeredi struct fuse_req *req) 348b9ca67b2SMiklos Szeredi __releases(fc->lock) 349b9ca67b2SMiklos Szeredi __acquires(fc->lock) 350a4d27e75SMiklos Szeredi { 351a4d27e75SMiklos Szeredi if (signal_pending(current)) 352a4d27e75SMiklos Szeredi return; 353a4d27e75SMiklos Szeredi 354a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 355a4d27e75SMiklos Szeredi wait_event_interruptible(req->waitq, req->state == FUSE_REQ_FINISHED); 356a4d27e75SMiklos Szeredi spin_lock(&fc->lock); 357a4d27e75SMiklos Szeredi } 358a4d27e75SMiklos Szeredi 359a4d27e75SMiklos Szeredi static void queue_interrupt(struct fuse_conn *fc, struct fuse_req *req) 360a4d27e75SMiklos Szeredi { 361a4d27e75SMiklos Szeredi list_add_tail(&req->intr_entry, &fc->interrupts); 362a4d27e75SMiklos Szeredi wake_up(&fc->waitq); 363a4d27e75SMiklos Szeredi kill_fasync(&fc->fasync, SIGIO, POLL_IN); 364a4d27e75SMiklos Szeredi } 365a4d27e75SMiklos Szeredi 3667c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) 367b9ca67b2SMiklos Szeredi __releases(fc->lock) 368b9ca67b2SMiklos Szeredi __acquires(fc->lock) 369334f485dSMiklos Szeredi { 370a4d27e75SMiklos Szeredi if (!fc->no_interrupt) { 371a4d27e75SMiklos Szeredi /* Any signal may interrupt this */ 372a4d27e75SMiklos Szeredi wait_answer_interruptible(fc, req); 373334f485dSMiklos Szeredi 374a4d27e75SMiklos Szeredi if (req->aborted) 375a4d27e75SMiklos Szeredi goto aborted; 376a4d27e75SMiklos Szeredi if (req->state == FUSE_REQ_FINISHED) 377334f485dSMiklos Szeredi return; 378334f485dSMiklos Szeredi 379a4d27e75SMiklos Szeredi req->interrupted = 1; 380a4d27e75SMiklos Szeredi if (req->state == FUSE_REQ_SENT) 381a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 382a4d27e75SMiklos Szeredi } 383a4d27e75SMiklos Szeredi 384a131de0aSMiklos Szeredi if (!req->force) { 385a4d27e75SMiklos Szeredi sigset_t oldset; 386a4d27e75SMiklos Szeredi 387a4d27e75SMiklos Szeredi /* Only fatal signals may interrupt this */ 388a4d27e75SMiklos Szeredi block_sigs(&oldset); 389a4d27e75SMiklos Szeredi wait_answer_interruptible(fc, req); 390a4d27e75SMiklos Szeredi restore_sigs(&oldset); 391a4d27e75SMiklos Szeredi 392a4d27e75SMiklos Szeredi if (req->aborted) 393a4d27e75SMiklos Szeredi goto aborted; 394a4d27e75SMiklos Szeredi if (req->state == FUSE_REQ_FINISHED) 395a4d27e75SMiklos Szeredi return; 396a4d27e75SMiklos Szeredi 397a131de0aSMiklos Szeredi /* Request is not yet in userspace, bail out */ 398a131de0aSMiklos Szeredi if (req->state == FUSE_REQ_PENDING) { 399a131de0aSMiklos Szeredi list_del(&req->list); 400a131de0aSMiklos Szeredi __fuse_put_request(req); 401334f485dSMiklos Szeredi req->out.h.error = -EINTR; 402a131de0aSMiklos Szeredi return; 403a131de0aSMiklos Szeredi } 404a131de0aSMiklos Szeredi } 405a131de0aSMiklos Szeredi 406a131de0aSMiklos Szeredi /* 407a131de0aSMiklos Szeredi * Either request is already in userspace, or it was forced. 408a131de0aSMiklos Szeredi * Wait it out. 409a131de0aSMiklos Szeredi */ 410a131de0aSMiklos Szeredi spin_unlock(&fc->lock); 411a131de0aSMiklos Szeredi wait_event(req->waitq, req->state == FUSE_REQ_FINISHED); 412a131de0aSMiklos Szeredi spin_lock(&fc->lock); 413a131de0aSMiklos Szeredi 414a131de0aSMiklos Szeredi if (!req->aborted) 415a131de0aSMiklos Szeredi return; 416a4d27e75SMiklos Szeredi 417a4d27e75SMiklos Szeredi aborted: 418a131de0aSMiklos Szeredi BUG_ON(req->state != FUSE_REQ_FINISHED); 419334f485dSMiklos Szeredi if (req->locked) { 420334f485dSMiklos Szeredi /* This is uninterruptible sleep, because data is 421334f485dSMiklos Szeredi being copied to/from the buffers of req. During 422334f485dSMiklos Szeredi locked state, there mustn't be any filesystem 423334f485dSMiklos Szeredi operation (e.g. page fault), since that could lead 424334f485dSMiklos Szeredi to deadlock */ 425d7133114SMiklos Szeredi spin_unlock(&fc->lock); 426334f485dSMiklos Szeredi wait_event(req->waitq, !req->locked); 427d7133114SMiklos Szeredi spin_lock(&fc->lock); 428334f485dSMiklos Szeredi } 429334f485dSMiklos Szeredi } 430334f485dSMiklos Szeredi 431b93f858aSTejun Heo void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 432334f485dSMiklos Szeredi { 433334f485dSMiklos Szeredi req->isreply = 1; 434d7133114SMiklos Szeredi spin_lock(&fc->lock); 4351e9a4ed9SMiklos Szeredi if (!fc->connected) 436334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 437334f485dSMiklos Szeredi else if (fc->conn_error) 438334f485dSMiklos Szeredi req->out.h.error = -ECONNREFUSED; 439334f485dSMiklos Szeredi else { 4402d45ba38SMiklos Szeredi req->in.h.unique = fuse_get_unique(fc); 441334f485dSMiklos Szeredi queue_request(fc, req); 442334f485dSMiklos Szeredi /* acquire extra reference, since request is still needed 443334f485dSMiklos Szeredi after request_end() */ 444334f485dSMiklos Szeredi __fuse_get_request(req); 445334f485dSMiklos Szeredi 4467c352bdfSMiklos Szeredi request_wait_answer(fc, req); 447334f485dSMiklos Szeredi } 448d7133114SMiklos Szeredi spin_unlock(&fc->lock); 449334f485dSMiklos Szeredi } 45008cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send); 451334f485dSMiklos Szeredi 452b93f858aSTejun Heo static void fuse_request_send_nowait_locked(struct fuse_conn *fc, 453d12def1bSMiklos Szeredi struct fuse_req *req) 454334f485dSMiklos Szeredi { 45551eb01e7SMiklos Szeredi req->background = 1; 45651eb01e7SMiklos Szeredi fc->num_background++; 4577a6d3c8bSCsaba Henk if (fc->num_background == fc->max_background) 45851eb01e7SMiklos Szeredi fc->blocked = 1; 4597a6d3c8bSCsaba Henk if (fc->num_background == fc->congestion_threshold && 460a325f9b9STejun Heo fc->bdi_initialized) { 4618aa7e847SJens Axboe set_bdi_congested(&fc->bdi, BLK_RW_SYNC); 4628aa7e847SJens Axboe set_bdi_congested(&fc->bdi, BLK_RW_ASYNC); 463f92b99b9SMiklos Szeredi } 464d12def1bSMiklos Szeredi list_add_tail(&req->list, &fc->bg_queue); 465d12def1bSMiklos Szeredi flush_bg_queue(fc); 466d12def1bSMiklos Szeredi } 46751eb01e7SMiklos Szeredi 468b93f858aSTejun Heo static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) 469d12def1bSMiklos Szeredi { 470d12def1bSMiklos Szeredi spin_lock(&fc->lock); 471d12def1bSMiklos Szeredi if (fc->connected) { 472b93f858aSTejun Heo fuse_request_send_nowait_locked(fc, req); 473d7133114SMiklos Szeredi spin_unlock(&fc->lock); 474334f485dSMiklos Szeredi } else { 475334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 476334f485dSMiklos Szeredi request_end(fc, req); 477334f485dSMiklos Szeredi } 478334f485dSMiklos Szeredi } 479334f485dSMiklos Szeredi 480b93f858aSTejun Heo void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) 481334f485dSMiklos Szeredi { 482334f485dSMiklos Szeredi req->isreply = 1; 483b93f858aSTejun Heo fuse_request_send_nowait(fc, req); 484334f485dSMiklos Szeredi } 48508cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send_background); 486334f485dSMiklos Szeredi 4872d45ba38SMiklos Szeredi static int fuse_request_send_notify_reply(struct fuse_conn *fc, 4882d45ba38SMiklos Szeredi struct fuse_req *req, u64 unique) 4892d45ba38SMiklos Szeredi { 4902d45ba38SMiklos Szeredi int err = -ENODEV; 4912d45ba38SMiklos Szeredi 4922d45ba38SMiklos Szeredi req->isreply = 0; 4932d45ba38SMiklos Szeredi req->in.h.unique = unique; 4942d45ba38SMiklos Szeredi spin_lock(&fc->lock); 4952d45ba38SMiklos Szeredi if (fc->connected) { 4962d45ba38SMiklos Szeredi queue_request(fc, req); 4972d45ba38SMiklos Szeredi err = 0; 4982d45ba38SMiklos Szeredi } 4992d45ba38SMiklos Szeredi spin_unlock(&fc->lock); 5002d45ba38SMiklos Szeredi 5012d45ba38SMiklos Szeredi return err; 5022d45ba38SMiklos Szeredi } 5032d45ba38SMiklos Szeredi 504334f485dSMiklos Szeredi /* 5053be5a52bSMiklos Szeredi * Called under fc->lock 5063be5a52bSMiklos Szeredi * 5073be5a52bSMiklos Szeredi * fc->connected must have been checked previously 5083be5a52bSMiklos Szeredi */ 509b93f858aSTejun Heo void fuse_request_send_background_locked(struct fuse_conn *fc, 510b93f858aSTejun Heo struct fuse_req *req) 5113be5a52bSMiklos Szeredi { 5123be5a52bSMiklos Szeredi req->isreply = 1; 513b93f858aSTejun Heo fuse_request_send_nowait_locked(fc, req); 5143be5a52bSMiklos Szeredi } 5153be5a52bSMiklos Szeredi 5160b05b183SAnand V. Avati void fuse_force_forget(struct file *file, u64 nodeid) 5170b05b183SAnand V. Avati { 5180b05b183SAnand V. Avati struct inode *inode = file->f_path.dentry->d_inode; 5190b05b183SAnand V. Avati struct fuse_conn *fc = get_fuse_conn(inode); 5200b05b183SAnand V. Avati struct fuse_req *req; 5210b05b183SAnand V. Avati struct fuse_forget_in inarg; 5220b05b183SAnand V. Avati 5230b05b183SAnand V. Avati memset(&inarg, 0, sizeof(inarg)); 5240b05b183SAnand V. Avati inarg.nlookup = 1; 525b111c8c0SMaxim Patlasov req = fuse_get_req_nofail_nopages(fc, file); 5260b05b183SAnand V. Avati req->in.h.opcode = FUSE_FORGET; 5270b05b183SAnand V. Avati req->in.h.nodeid = nodeid; 5280b05b183SAnand V. Avati req->in.numargs = 1; 5290b05b183SAnand V. Avati req->in.args[0].size = sizeof(inarg); 5300b05b183SAnand V. Avati req->in.args[0].value = &inarg; 5310b05b183SAnand V. Avati req->isreply = 0; 5320b05b183SAnand V. Avati fuse_request_send_nowait(fc, req); 5330b05b183SAnand V. Avati } 5340b05b183SAnand V. Avati 5353be5a52bSMiklos Szeredi /* 536334f485dSMiklos Szeredi * Lock the request. Up to the next unlock_request() there mustn't be 537334f485dSMiklos Szeredi * anything that could cause a page-fault. If the request was already 538f9a2842eSMiklos Szeredi * aborted bail out. 539334f485dSMiklos Szeredi */ 540d7133114SMiklos Szeredi static int lock_request(struct fuse_conn *fc, struct fuse_req *req) 541334f485dSMiklos Szeredi { 542334f485dSMiklos Szeredi int err = 0; 543334f485dSMiklos Szeredi if (req) { 544d7133114SMiklos Szeredi spin_lock(&fc->lock); 545f9a2842eSMiklos Szeredi if (req->aborted) 546334f485dSMiklos Szeredi err = -ENOENT; 547334f485dSMiklos Szeredi else 548334f485dSMiklos Szeredi req->locked = 1; 549d7133114SMiklos Szeredi spin_unlock(&fc->lock); 550334f485dSMiklos Szeredi } 551334f485dSMiklos Szeredi return err; 552334f485dSMiklos Szeredi } 553334f485dSMiklos Szeredi 554334f485dSMiklos Szeredi /* 555f9a2842eSMiklos Szeredi * Unlock request. If it was aborted during being locked, the 556334f485dSMiklos Szeredi * requester thread is currently waiting for it to be unlocked, so 557334f485dSMiklos Szeredi * wake it up. 558334f485dSMiklos Szeredi */ 559d7133114SMiklos Szeredi static void unlock_request(struct fuse_conn *fc, struct fuse_req *req) 560334f485dSMiklos Szeredi { 561334f485dSMiklos Szeredi if (req) { 562d7133114SMiklos Szeredi spin_lock(&fc->lock); 563334f485dSMiklos Szeredi req->locked = 0; 564f9a2842eSMiklos Szeredi if (req->aborted) 565334f485dSMiklos Szeredi wake_up(&req->waitq); 566d7133114SMiklos Szeredi spin_unlock(&fc->lock); 567334f485dSMiklos Szeredi } 568334f485dSMiklos Szeredi } 569334f485dSMiklos Szeredi 570334f485dSMiklos Szeredi struct fuse_copy_state { 571d7133114SMiklos Szeredi struct fuse_conn *fc; 572334f485dSMiklos Szeredi int write; 573334f485dSMiklos Szeredi struct fuse_req *req; 574334f485dSMiklos Szeredi const struct iovec *iov; 575dd3bb14fSMiklos Szeredi struct pipe_buffer *pipebufs; 576dd3bb14fSMiklos Szeredi struct pipe_buffer *currbuf; 577dd3bb14fSMiklos Szeredi struct pipe_inode_info *pipe; 578334f485dSMiklos Szeredi unsigned long nr_segs; 579334f485dSMiklos Szeredi unsigned long seglen; 580334f485dSMiklos Szeredi unsigned long addr; 581334f485dSMiklos Szeredi struct page *pg; 582334f485dSMiklos Szeredi void *mapaddr; 583334f485dSMiklos Szeredi void *buf; 584334f485dSMiklos Szeredi unsigned len; 585ce534fb0SMiklos Szeredi unsigned move_pages:1; 586334f485dSMiklos Szeredi }; 587334f485dSMiklos Szeredi 588d7133114SMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc, 589c3021629SMiklos Szeredi int write, 590d7133114SMiklos Szeredi const struct iovec *iov, unsigned long nr_segs) 591334f485dSMiklos Szeredi { 592334f485dSMiklos Szeredi memset(cs, 0, sizeof(*cs)); 593d7133114SMiklos Szeredi cs->fc = fc; 594334f485dSMiklos Szeredi cs->write = write; 595334f485dSMiklos Szeredi cs->iov = iov; 596334f485dSMiklos Szeredi cs->nr_segs = nr_segs; 597334f485dSMiklos Szeredi } 598334f485dSMiklos Szeredi 599334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */ 6008bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs) 601334f485dSMiklos Szeredi { 602dd3bb14fSMiklos Szeredi if (cs->currbuf) { 603dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->currbuf; 604dd3bb14fSMiklos Szeredi 605c3021629SMiklos Szeredi if (!cs->write) { 606dd3bb14fSMiklos Szeredi buf->ops->unmap(cs->pipe, buf, cs->mapaddr); 607c3021629SMiklos Szeredi } else { 6087909b1c6SMiklos Szeredi kunmap(buf->page); 609c3021629SMiklos Szeredi buf->len = PAGE_SIZE - cs->len; 610c3021629SMiklos Szeredi } 611dd3bb14fSMiklos Szeredi cs->currbuf = NULL; 612dd3bb14fSMiklos Szeredi cs->mapaddr = NULL; 613dd3bb14fSMiklos Szeredi } else if (cs->mapaddr) { 6147909b1c6SMiklos Szeredi kunmap(cs->pg); 615334f485dSMiklos Szeredi if (cs->write) { 616334f485dSMiklos Szeredi flush_dcache_page(cs->pg); 617334f485dSMiklos Szeredi set_page_dirty_lock(cs->pg); 618334f485dSMiklos Szeredi } 619334f485dSMiklos Szeredi put_page(cs->pg); 620334f485dSMiklos Szeredi cs->mapaddr = NULL; 621334f485dSMiklos Szeredi } 622334f485dSMiklos Szeredi } 623334f485dSMiklos Szeredi 624334f485dSMiklos Szeredi /* 625334f485dSMiklos Szeredi * Get another pagefull of userspace buffer, and map it to kernel 626334f485dSMiklos Szeredi * address space, and lock request 627334f485dSMiklos Szeredi */ 628334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs) 629334f485dSMiklos Szeredi { 630334f485dSMiklos Szeredi unsigned long offset; 631334f485dSMiklos Szeredi int err; 632334f485dSMiklos Szeredi 633d7133114SMiklos Szeredi unlock_request(cs->fc, cs->req); 634334f485dSMiklos Szeredi fuse_copy_finish(cs); 635dd3bb14fSMiklos Szeredi if (cs->pipebufs) { 636dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 637dd3bb14fSMiklos Szeredi 638c3021629SMiklos Szeredi if (!cs->write) { 639dd3bb14fSMiklos Szeredi err = buf->ops->confirm(cs->pipe, buf); 640dd3bb14fSMiklos Szeredi if (err) 641dd3bb14fSMiklos Szeredi return err; 642dd3bb14fSMiklos Szeredi 643dd3bb14fSMiklos Szeredi BUG_ON(!cs->nr_segs); 644dd3bb14fSMiklos Szeredi cs->currbuf = buf; 6457909b1c6SMiklos Szeredi cs->mapaddr = buf->ops->map(cs->pipe, buf, 0); 646dd3bb14fSMiklos Szeredi cs->len = buf->len; 647dd3bb14fSMiklos Szeredi cs->buf = cs->mapaddr + buf->offset; 648dd3bb14fSMiklos Szeredi cs->pipebufs++; 649dd3bb14fSMiklos Szeredi cs->nr_segs--; 650dd3bb14fSMiklos Szeredi } else { 651c3021629SMiklos Szeredi struct page *page; 652c3021629SMiklos Szeredi 653c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 654c3021629SMiklos Szeredi return -EIO; 655c3021629SMiklos Szeredi 656c3021629SMiklos Szeredi page = alloc_page(GFP_HIGHUSER); 657c3021629SMiklos Szeredi if (!page) 658c3021629SMiklos Szeredi return -ENOMEM; 659c3021629SMiklos Szeredi 660c3021629SMiklos Szeredi buf->page = page; 661c3021629SMiklos Szeredi buf->offset = 0; 662c3021629SMiklos Szeredi buf->len = 0; 663c3021629SMiklos Szeredi 664c3021629SMiklos Szeredi cs->currbuf = buf; 6657909b1c6SMiklos Szeredi cs->mapaddr = kmap(page); 666c3021629SMiklos Szeredi cs->buf = cs->mapaddr; 667c3021629SMiklos Szeredi cs->len = PAGE_SIZE; 668c3021629SMiklos Szeredi cs->pipebufs++; 669c3021629SMiklos Szeredi cs->nr_segs++; 670c3021629SMiklos Szeredi } 671c3021629SMiklos Szeredi } else { 672334f485dSMiklos Szeredi if (!cs->seglen) { 673334f485dSMiklos Szeredi BUG_ON(!cs->nr_segs); 674334f485dSMiklos Szeredi cs->seglen = cs->iov[0].iov_len; 675334f485dSMiklos Szeredi cs->addr = (unsigned long) cs->iov[0].iov_base; 676334f485dSMiklos Szeredi cs->iov++; 677334f485dSMiklos Szeredi cs->nr_segs--; 678334f485dSMiklos Szeredi } 6791bf94ca7SMiklos Szeredi err = get_user_pages_fast(cs->addr, 1, cs->write, &cs->pg); 680334f485dSMiklos Szeredi if (err < 0) 681334f485dSMiklos Szeredi return err; 682334f485dSMiklos Szeredi BUG_ON(err != 1); 683334f485dSMiklos Szeredi offset = cs->addr % PAGE_SIZE; 6847909b1c6SMiklos Szeredi cs->mapaddr = kmap(cs->pg); 685334f485dSMiklos Szeredi cs->buf = cs->mapaddr + offset; 686334f485dSMiklos Szeredi cs->len = min(PAGE_SIZE - offset, cs->seglen); 687334f485dSMiklos Szeredi cs->seglen -= cs->len; 688334f485dSMiklos Szeredi cs->addr += cs->len; 689dd3bb14fSMiklos Szeredi } 690334f485dSMiklos Szeredi 691d7133114SMiklos Szeredi return lock_request(cs->fc, cs->req); 692334f485dSMiklos Szeredi } 693334f485dSMiklos Szeredi 694334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */ 6958bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size) 696334f485dSMiklos Szeredi { 697334f485dSMiklos Szeredi unsigned ncpy = min(*size, cs->len); 698334f485dSMiklos Szeredi if (val) { 699334f485dSMiklos Szeredi if (cs->write) 700334f485dSMiklos Szeredi memcpy(cs->buf, *val, ncpy); 701334f485dSMiklos Szeredi else 702334f485dSMiklos Szeredi memcpy(*val, cs->buf, ncpy); 703334f485dSMiklos Szeredi *val += ncpy; 704334f485dSMiklos Szeredi } 705334f485dSMiklos Szeredi *size -= ncpy; 706334f485dSMiklos Szeredi cs->len -= ncpy; 707334f485dSMiklos Szeredi cs->buf += ncpy; 708334f485dSMiklos Szeredi return ncpy; 709334f485dSMiklos Szeredi } 710334f485dSMiklos Szeredi 711ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page) 712ce534fb0SMiklos Szeredi { 713ce534fb0SMiklos Szeredi if (page_mapcount(page) || 714ce534fb0SMiklos Szeredi page->mapping != NULL || 715ce534fb0SMiklos Szeredi page_count(page) != 1 || 716ce534fb0SMiklos Szeredi (page->flags & PAGE_FLAGS_CHECK_AT_PREP & 717ce534fb0SMiklos Szeredi ~(1 << PG_locked | 718ce534fb0SMiklos Szeredi 1 << PG_referenced | 719ce534fb0SMiklos Szeredi 1 << PG_uptodate | 720ce534fb0SMiklos Szeredi 1 << PG_lru | 721ce534fb0SMiklos Szeredi 1 << PG_active | 722ce534fb0SMiklos Szeredi 1 << PG_reclaim))) { 723ce534fb0SMiklos Szeredi printk(KERN_WARNING "fuse: trying to steal weird page\n"); 724ce534fb0SMiklos 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); 725ce534fb0SMiklos Szeredi return 1; 726ce534fb0SMiklos Szeredi } 727ce534fb0SMiklos Szeredi return 0; 728ce534fb0SMiklos Szeredi } 729ce534fb0SMiklos Szeredi 730ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) 731ce534fb0SMiklos Szeredi { 732ce534fb0SMiklos Szeredi int err; 733ce534fb0SMiklos Szeredi struct page *oldpage = *pagep; 734ce534fb0SMiklos Szeredi struct page *newpage; 735ce534fb0SMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 736ce534fb0SMiklos Szeredi 737ce534fb0SMiklos Szeredi unlock_request(cs->fc, cs->req); 738ce534fb0SMiklos Szeredi fuse_copy_finish(cs); 739ce534fb0SMiklos Szeredi 740ce534fb0SMiklos Szeredi err = buf->ops->confirm(cs->pipe, buf); 741ce534fb0SMiklos Szeredi if (err) 742ce534fb0SMiklos Szeredi return err; 743ce534fb0SMiklos Szeredi 744ce534fb0SMiklos Szeredi BUG_ON(!cs->nr_segs); 745ce534fb0SMiklos Szeredi cs->currbuf = buf; 746ce534fb0SMiklos Szeredi cs->len = buf->len; 747ce534fb0SMiklos Szeredi cs->pipebufs++; 748ce534fb0SMiklos Szeredi cs->nr_segs--; 749ce534fb0SMiklos Szeredi 750ce534fb0SMiklos Szeredi if (cs->len != PAGE_SIZE) 751ce534fb0SMiklos Szeredi goto out_fallback; 752ce534fb0SMiklos Szeredi 753ce534fb0SMiklos Szeredi if (buf->ops->steal(cs->pipe, buf) != 0) 754ce534fb0SMiklos Szeredi goto out_fallback; 755ce534fb0SMiklos Szeredi 756ce534fb0SMiklos Szeredi newpage = buf->page; 757ce534fb0SMiklos Szeredi 758ce534fb0SMiklos Szeredi if (WARN_ON(!PageUptodate(newpage))) 759ce534fb0SMiklos Szeredi return -EIO; 760ce534fb0SMiklos Szeredi 761ce534fb0SMiklos Szeredi ClearPageMappedToDisk(newpage); 762ce534fb0SMiklos Szeredi 763ce534fb0SMiklos Szeredi if (fuse_check_page(newpage) != 0) 764ce534fb0SMiklos Szeredi goto out_fallback_unlock; 765ce534fb0SMiklos Szeredi 766ce534fb0SMiklos Szeredi /* 767ce534fb0SMiklos Szeredi * This is a new and locked page, it shouldn't be mapped or 768ce534fb0SMiklos Szeredi * have any special flags on it 769ce534fb0SMiklos Szeredi */ 770ce534fb0SMiklos Szeredi if (WARN_ON(page_mapped(oldpage))) 771ce534fb0SMiklos Szeredi goto out_fallback_unlock; 772ce534fb0SMiklos Szeredi if (WARN_ON(page_has_private(oldpage))) 773ce534fb0SMiklos Szeredi goto out_fallback_unlock; 774ce534fb0SMiklos Szeredi if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage))) 775ce534fb0SMiklos Szeredi goto out_fallback_unlock; 776ce534fb0SMiklos Szeredi if (WARN_ON(PageMlocked(oldpage))) 777ce534fb0SMiklos Szeredi goto out_fallback_unlock; 778ce534fb0SMiklos Szeredi 779ef6a3c63SMiklos Szeredi err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); 780ce534fb0SMiklos Szeredi if (err) { 781ef6a3c63SMiklos Szeredi unlock_page(newpage); 782ef6a3c63SMiklos Szeredi return err; 783ce534fb0SMiklos Szeredi } 784ef6a3c63SMiklos Szeredi 785ce534fb0SMiklos Szeredi page_cache_get(newpage); 786ce534fb0SMiklos Szeredi 787ce534fb0SMiklos Szeredi if (!(buf->flags & PIPE_BUF_FLAG_LRU)) 788ce534fb0SMiklos Szeredi lru_cache_add_file(newpage); 789ce534fb0SMiklos Szeredi 790ce534fb0SMiklos Szeredi err = 0; 791ce534fb0SMiklos Szeredi spin_lock(&cs->fc->lock); 792ce534fb0SMiklos Szeredi if (cs->req->aborted) 793ce534fb0SMiklos Szeredi err = -ENOENT; 794ce534fb0SMiklos Szeredi else 795ce534fb0SMiklos Szeredi *pagep = newpage; 796ce534fb0SMiklos Szeredi spin_unlock(&cs->fc->lock); 797ce534fb0SMiklos Szeredi 798ce534fb0SMiklos Szeredi if (err) { 799ce534fb0SMiklos Szeredi unlock_page(newpage); 800ce534fb0SMiklos Szeredi page_cache_release(newpage); 801ce534fb0SMiklos Szeredi return err; 802ce534fb0SMiklos Szeredi } 803ce534fb0SMiklos Szeredi 804ce534fb0SMiklos Szeredi unlock_page(oldpage); 805ce534fb0SMiklos Szeredi page_cache_release(oldpage); 806ce534fb0SMiklos Szeredi cs->len = 0; 807ce534fb0SMiklos Szeredi 808ce534fb0SMiklos Szeredi return 0; 809ce534fb0SMiklos Szeredi 810ce534fb0SMiklos Szeredi out_fallback_unlock: 811ce534fb0SMiklos Szeredi unlock_page(newpage); 812ce534fb0SMiklos Szeredi out_fallback: 813ce534fb0SMiklos Szeredi cs->mapaddr = buf->ops->map(cs->pipe, buf, 1); 814ce534fb0SMiklos Szeredi cs->buf = cs->mapaddr + buf->offset; 815ce534fb0SMiklos Szeredi 816ce534fb0SMiklos Szeredi err = lock_request(cs->fc, cs->req); 817ce534fb0SMiklos Szeredi if (err) 818ce534fb0SMiklos Szeredi return err; 819ce534fb0SMiklos Szeredi 820ce534fb0SMiklos Szeredi return 1; 821ce534fb0SMiklos Szeredi } 822ce534fb0SMiklos Szeredi 823c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page, 824c3021629SMiklos Szeredi unsigned offset, unsigned count) 825c3021629SMiklos Szeredi { 826c3021629SMiklos Szeredi struct pipe_buffer *buf; 827c3021629SMiklos Szeredi 828c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 829c3021629SMiklos Szeredi return -EIO; 830c3021629SMiklos Szeredi 831c3021629SMiklos Szeredi unlock_request(cs->fc, cs->req); 832c3021629SMiklos Szeredi fuse_copy_finish(cs); 833c3021629SMiklos Szeredi 834c3021629SMiklos Szeredi buf = cs->pipebufs; 835c3021629SMiklos Szeredi page_cache_get(page); 836c3021629SMiklos Szeredi buf->page = page; 837c3021629SMiklos Szeredi buf->offset = offset; 838c3021629SMiklos Szeredi buf->len = count; 839c3021629SMiklos Szeredi 840c3021629SMiklos Szeredi cs->pipebufs++; 841c3021629SMiklos Szeredi cs->nr_segs++; 842c3021629SMiklos Szeredi cs->len = 0; 843c3021629SMiklos Szeredi 844c3021629SMiklos Szeredi return 0; 845c3021629SMiklos Szeredi } 846c3021629SMiklos Szeredi 847334f485dSMiklos Szeredi /* 848334f485dSMiklos Szeredi * Copy a page in the request to/from the userspace buffer. Must be 849334f485dSMiklos Szeredi * done atomically 850334f485dSMiklos Szeredi */ 851ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep, 852334f485dSMiklos Szeredi unsigned offset, unsigned count, int zeroing) 853334f485dSMiklos Szeredi { 854ce534fb0SMiklos Szeredi int err; 855ce534fb0SMiklos Szeredi struct page *page = *pagep; 856ce534fb0SMiklos Szeredi 857b6777c40SMiklos Szeredi if (page && zeroing && count < PAGE_SIZE) 858b6777c40SMiklos Szeredi clear_highpage(page); 859b6777c40SMiklos Szeredi 860334f485dSMiklos Szeredi while (count) { 861c3021629SMiklos Szeredi if (cs->write && cs->pipebufs && page) { 862c3021629SMiklos Szeredi return fuse_ref_page(cs, page, offset, count); 863c3021629SMiklos Szeredi } else if (!cs->len) { 864ce534fb0SMiklos Szeredi if (cs->move_pages && page && 865ce534fb0SMiklos Szeredi offset == 0 && count == PAGE_SIZE) { 866ce534fb0SMiklos Szeredi err = fuse_try_move_page(cs, pagep); 867ce534fb0SMiklos Szeredi if (err <= 0) 868ce534fb0SMiklos Szeredi return err; 869ce534fb0SMiklos Szeredi } else { 870ce534fb0SMiklos Szeredi err = fuse_copy_fill(cs); 8711729a16cSMiklos Szeredi if (err) 872334f485dSMiklos Szeredi return err; 8731729a16cSMiklos Szeredi } 874ce534fb0SMiklos Szeredi } 875334f485dSMiklos Szeredi if (page) { 8762408f6efSCong Wang void *mapaddr = kmap_atomic(page); 877334f485dSMiklos Szeredi void *buf = mapaddr + offset; 878334f485dSMiklos Szeredi offset += fuse_copy_do(cs, &buf, &count); 8792408f6efSCong Wang kunmap_atomic(mapaddr); 880334f485dSMiklos Szeredi } else 881334f485dSMiklos Szeredi offset += fuse_copy_do(cs, NULL, &count); 882334f485dSMiklos Szeredi } 883334f485dSMiklos Szeredi if (page && !cs->write) 884334f485dSMiklos Szeredi flush_dcache_page(page); 885334f485dSMiklos Szeredi return 0; 886334f485dSMiklos Szeredi } 887334f485dSMiklos Szeredi 888334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */ 889334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes, 890334f485dSMiklos Szeredi int zeroing) 891334f485dSMiklos Szeredi { 892334f485dSMiklos Szeredi unsigned i; 893334f485dSMiklos Szeredi struct fuse_req *req = cs->req; 894334f485dSMiklos Szeredi unsigned offset = req->page_offset; 895334f485dSMiklos Szeredi unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset); 896334f485dSMiklos Szeredi 897334f485dSMiklos Szeredi for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) { 898ce534fb0SMiklos Szeredi int err; 899ce534fb0SMiklos Szeredi 900ce534fb0SMiklos Szeredi err = fuse_copy_page(cs, &req->pages[i], offset, count, 901ce534fb0SMiklos Szeredi zeroing); 902334f485dSMiklos Szeredi if (err) 903334f485dSMiklos Szeredi return err; 904334f485dSMiklos Szeredi 905334f485dSMiklos Szeredi nbytes -= count; 906334f485dSMiklos Szeredi count = min(nbytes, (unsigned) PAGE_SIZE); 907334f485dSMiklos Szeredi offset = 0; 908334f485dSMiklos Szeredi } 909334f485dSMiklos Szeredi return 0; 910334f485dSMiklos Szeredi } 911334f485dSMiklos Szeredi 912334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */ 913334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) 914334f485dSMiklos Szeredi { 915334f485dSMiklos Szeredi while (size) { 9161729a16cSMiklos Szeredi if (!cs->len) { 9171729a16cSMiklos Szeredi int err = fuse_copy_fill(cs); 9181729a16cSMiklos Szeredi if (err) 919334f485dSMiklos Szeredi return err; 9201729a16cSMiklos Szeredi } 921334f485dSMiklos Szeredi fuse_copy_do(cs, &val, &size); 922334f485dSMiklos Szeredi } 923334f485dSMiklos Szeredi return 0; 924334f485dSMiklos Szeredi } 925334f485dSMiklos Szeredi 926334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */ 927334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs, 928334f485dSMiklos Szeredi unsigned argpages, struct fuse_arg *args, 929334f485dSMiklos Szeredi int zeroing) 930334f485dSMiklos Szeredi { 931334f485dSMiklos Szeredi int err = 0; 932334f485dSMiklos Szeredi unsigned i; 933334f485dSMiklos Szeredi 934334f485dSMiklos Szeredi for (i = 0; !err && i < numargs; i++) { 935334f485dSMiklos Szeredi struct fuse_arg *arg = &args[i]; 936334f485dSMiklos Szeredi if (i == numargs - 1 && argpages) 937334f485dSMiklos Szeredi err = fuse_copy_pages(cs, arg->size, zeroing); 938334f485dSMiklos Szeredi else 939334f485dSMiklos Szeredi err = fuse_copy_one(cs, arg->value, arg->size); 940334f485dSMiklos Szeredi } 941334f485dSMiklos Szeredi return err; 942334f485dSMiklos Szeredi } 943334f485dSMiklos Szeredi 94407e77dcaSMiklos Szeredi static int forget_pending(struct fuse_conn *fc) 94507e77dcaSMiklos Szeredi { 94607e77dcaSMiklos Szeredi return fc->forget_list_head.next != NULL; 94707e77dcaSMiklos Szeredi } 94807e77dcaSMiklos Szeredi 949a4d27e75SMiklos Szeredi static int request_pending(struct fuse_conn *fc) 950a4d27e75SMiklos Szeredi { 95107e77dcaSMiklos Szeredi return !list_empty(&fc->pending) || !list_empty(&fc->interrupts) || 95207e77dcaSMiklos Szeredi forget_pending(fc); 953a4d27e75SMiklos Szeredi } 954a4d27e75SMiklos Szeredi 955334f485dSMiklos Szeredi /* Wait until a request is available on the pending list */ 956334f485dSMiklos Szeredi static void request_wait(struct fuse_conn *fc) 957b9ca67b2SMiklos Szeredi __releases(fc->lock) 958b9ca67b2SMiklos Szeredi __acquires(fc->lock) 959334f485dSMiklos Szeredi { 960334f485dSMiklos Szeredi DECLARE_WAITQUEUE(wait, current); 961334f485dSMiklos Szeredi 962334f485dSMiklos Szeredi add_wait_queue_exclusive(&fc->waitq, &wait); 963a4d27e75SMiklos Szeredi while (fc->connected && !request_pending(fc)) { 964334f485dSMiklos Szeredi set_current_state(TASK_INTERRUPTIBLE); 965334f485dSMiklos Szeredi if (signal_pending(current)) 966334f485dSMiklos Szeredi break; 967334f485dSMiklos Szeredi 968d7133114SMiklos Szeredi spin_unlock(&fc->lock); 969334f485dSMiklos Szeredi schedule(); 970d7133114SMiklos Szeredi spin_lock(&fc->lock); 971334f485dSMiklos Szeredi } 972334f485dSMiklos Szeredi set_current_state(TASK_RUNNING); 973334f485dSMiklos Szeredi remove_wait_queue(&fc->waitq, &wait); 974334f485dSMiklos Szeredi } 975334f485dSMiklos Szeredi 976334f485dSMiklos Szeredi /* 977a4d27e75SMiklos Szeredi * Transfer an interrupt request to userspace 978a4d27e75SMiklos Szeredi * 979a4d27e75SMiklos Szeredi * Unlike other requests this is assembled on demand, without a need 980a4d27e75SMiklos Szeredi * to allocate a separate fuse_req structure. 981a4d27e75SMiklos Szeredi * 982a4d27e75SMiklos Szeredi * Called with fc->lock held, releases it 983a4d27e75SMiklos Szeredi */ 984c3021629SMiklos Szeredi static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_copy_state *cs, 985c3021629SMiklos Szeredi size_t nbytes, struct fuse_req *req) 986b9ca67b2SMiklos Szeredi __releases(fc->lock) 987a4d27e75SMiklos Szeredi { 988a4d27e75SMiklos Szeredi struct fuse_in_header ih; 989a4d27e75SMiklos Szeredi struct fuse_interrupt_in arg; 990a4d27e75SMiklos Szeredi unsigned reqsize = sizeof(ih) + sizeof(arg); 991a4d27e75SMiklos Szeredi int err; 992a4d27e75SMiklos Szeredi 993a4d27e75SMiklos Szeredi list_del_init(&req->intr_entry); 994a4d27e75SMiklos Szeredi req->intr_unique = fuse_get_unique(fc); 995a4d27e75SMiklos Szeredi memset(&ih, 0, sizeof(ih)); 996a4d27e75SMiklos Szeredi memset(&arg, 0, sizeof(arg)); 997a4d27e75SMiklos Szeredi ih.len = reqsize; 998a4d27e75SMiklos Szeredi ih.opcode = FUSE_INTERRUPT; 999a4d27e75SMiklos Szeredi ih.unique = req->intr_unique; 1000a4d27e75SMiklos Szeredi arg.unique = req->in.h.unique; 1001a4d27e75SMiklos Szeredi 1002a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 1003c3021629SMiklos Szeredi if (nbytes < reqsize) 1004a4d27e75SMiklos Szeredi return -EINVAL; 1005a4d27e75SMiklos Szeredi 1006c3021629SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 1007a4d27e75SMiklos Szeredi if (!err) 1008c3021629SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 1009c3021629SMiklos Szeredi fuse_copy_finish(cs); 1010a4d27e75SMiklos Szeredi 1011a4d27e75SMiklos Szeredi return err ? err : reqsize; 1012a4d27e75SMiklos Szeredi } 1013a4d27e75SMiklos Szeredi 101402c048b9SMiklos Szeredi static struct fuse_forget_link *dequeue_forget(struct fuse_conn *fc, 101502c048b9SMiklos Szeredi unsigned max, 101602c048b9SMiklos Szeredi unsigned *countp) 101707e77dcaSMiklos Szeredi { 101802c048b9SMiklos Szeredi struct fuse_forget_link *head = fc->forget_list_head.next; 101902c048b9SMiklos Szeredi struct fuse_forget_link **newhead = &head; 102002c048b9SMiklos Szeredi unsigned count; 102107e77dcaSMiklos Szeredi 102202c048b9SMiklos Szeredi for (count = 0; *newhead != NULL && count < max; count++) 102302c048b9SMiklos Szeredi newhead = &(*newhead)->next; 102402c048b9SMiklos Szeredi 102502c048b9SMiklos Szeredi fc->forget_list_head.next = *newhead; 102602c048b9SMiklos Szeredi *newhead = NULL; 102707e77dcaSMiklos Szeredi if (fc->forget_list_head.next == NULL) 102807e77dcaSMiklos Szeredi fc->forget_list_tail = &fc->forget_list_head; 102907e77dcaSMiklos Szeredi 103002c048b9SMiklos Szeredi if (countp != NULL) 103102c048b9SMiklos Szeredi *countp = count; 103202c048b9SMiklos Szeredi 103302c048b9SMiklos Szeredi return head; 103407e77dcaSMiklos Szeredi } 103507e77dcaSMiklos Szeredi 103607e77dcaSMiklos Szeredi static int fuse_read_single_forget(struct fuse_conn *fc, 103707e77dcaSMiklos Szeredi struct fuse_copy_state *cs, 103807e77dcaSMiklos Szeredi size_t nbytes) 103907e77dcaSMiklos Szeredi __releases(fc->lock) 104007e77dcaSMiklos Szeredi { 104107e77dcaSMiklos Szeredi int err; 104202c048b9SMiklos Szeredi struct fuse_forget_link *forget = dequeue_forget(fc, 1, NULL); 104307e77dcaSMiklos Szeredi struct fuse_forget_in arg = { 104402c048b9SMiklos Szeredi .nlookup = forget->forget_one.nlookup, 104507e77dcaSMiklos Szeredi }; 104607e77dcaSMiklos Szeredi struct fuse_in_header ih = { 104707e77dcaSMiklos Szeredi .opcode = FUSE_FORGET, 104802c048b9SMiklos Szeredi .nodeid = forget->forget_one.nodeid, 104907e77dcaSMiklos Szeredi .unique = fuse_get_unique(fc), 105007e77dcaSMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 105107e77dcaSMiklos Szeredi }; 105207e77dcaSMiklos Szeredi 105307e77dcaSMiklos Szeredi spin_unlock(&fc->lock); 105407e77dcaSMiklos Szeredi kfree(forget); 105507e77dcaSMiklos Szeredi if (nbytes < ih.len) 105607e77dcaSMiklos Szeredi return -EINVAL; 105707e77dcaSMiklos Szeredi 105807e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 105907e77dcaSMiklos Szeredi if (!err) 106007e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 106107e77dcaSMiklos Szeredi fuse_copy_finish(cs); 106207e77dcaSMiklos Szeredi 106307e77dcaSMiklos Szeredi if (err) 106407e77dcaSMiklos Szeredi return err; 106507e77dcaSMiklos Szeredi 106607e77dcaSMiklos Szeredi return ih.len; 106707e77dcaSMiklos Szeredi } 106807e77dcaSMiklos Szeredi 106902c048b9SMiklos Szeredi static int fuse_read_batch_forget(struct fuse_conn *fc, 107002c048b9SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 107102c048b9SMiklos Szeredi __releases(fc->lock) 107202c048b9SMiklos Szeredi { 107302c048b9SMiklos Szeredi int err; 107402c048b9SMiklos Szeredi unsigned max_forgets; 107502c048b9SMiklos Szeredi unsigned count; 107602c048b9SMiklos Szeredi struct fuse_forget_link *head; 107702c048b9SMiklos Szeredi struct fuse_batch_forget_in arg = { .count = 0 }; 107802c048b9SMiklos Szeredi struct fuse_in_header ih = { 107902c048b9SMiklos Szeredi .opcode = FUSE_BATCH_FORGET, 108002c048b9SMiklos Szeredi .unique = fuse_get_unique(fc), 108102c048b9SMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 108202c048b9SMiklos Szeredi }; 108302c048b9SMiklos Szeredi 108402c048b9SMiklos Szeredi if (nbytes < ih.len) { 108502c048b9SMiklos Szeredi spin_unlock(&fc->lock); 108602c048b9SMiklos Szeredi return -EINVAL; 108702c048b9SMiklos Szeredi } 108802c048b9SMiklos Szeredi 108902c048b9SMiklos Szeredi max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one); 109002c048b9SMiklos Szeredi head = dequeue_forget(fc, max_forgets, &count); 109102c048b9SMiklos Szeredi spin_unlock(&fc->lock); 109202c048b9SMiklos Szeredi 109302c048b9SMiklos Szeredi arg.count = count; 109402c048b9SMiklos Szeredi ih.len += count * sizeof(struct fuse_forget_one); 109502c048b9SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 109602c048b9SMiklos Szeredi if (!err) 109702c048b9SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 109802c048b9SMiklos Szeredi 109902c048b9SMiklos Szeredi while (head) { 110002c048b9SMiklos Szeredi struct fuse_forget_link *forget = head; 110102c048b9SMiklos Szeredi 110202c048b9SMiklos Szeredi if (!err) { 110302c048b9SMiklos Szeredi err = fuse_copy_one(cs, &forget->forget_one, 110402c048b9SMiklos Szeredi sizeof(forget->forget_one)); 110502c048b9SMiklos Szeredi } 110602c048b9SMiklos Szeredi head = forget->next; 110702c048b9SMiklos Szeredi kfree(forget); 110802c048b9SMiklos Szeredi } 110902c048b9SMiklos Szeredi 111002c048b9SMiklos Szeredi fuse_copy_finish(cs); 111102c048b9SMiklos Szeredi 111202c048b9SMiklos Szeredi if (err) 111302c048b9SMiklos Szeredi return err; 111402c048b9SMiklos Szeredi 111502c048b9SMiklos Szeredi return ih.len; 111602c048b9SMiklos Szeredi } 111702c048b9SMiklos Szeredi 111802c048b9SMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_copy_state *cs, 111902c048b9SMiklos Szeredi size_t nbytes) 112002c048b9SMiklos Szeredi __releases(fc->lock) 112102c048b9SMiklos Szeredi { 112202c048b9SMiklos Szeredi if (fc->minor < 16 || fc->forget_list_head.next->next == NULL) 112302c048b9SMiklos Szeredi return fuse_read_single_forget(fc, cs, nbytes); 112402c048b9SMiklos Szeredi else 112502c048b9SMiklos Szeredi return fuse_read_batch_forget(fc, cs, nbytes); 112602c048b9SMiklos Szeredi } 112702c048b9SMiklos Szeredi 1128a4d27e75SMiklos Szeredi /* 1129334f485dSMiklos Szeredi * Read a single request into the userspace filesystem's buffer. This 1130334f485dSMiklos Szeredi * function waits until a request is available, then removes it from 1131334f485dSMiklos Szeredi * the pending list and copies request data to userspace buffer. If 1132f9a2842eSMiklos Szeredi * no reply is needed (FORGET) or request has been aborted or there 1133f9a2842eSMiklos Szeredi * was an error during the copying then it's finished by calling 1134334f485dSMiklos Szeredi * request_end(). Otherwise add it to the processing list, and set 1135334f485dSMiklos Szeredi * the 'sent' flag. 1136334f485dSMiklos Szeredi */ 1137c3021629SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file, 1138c3021629SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1139334f485dSMiklos Szeredi { 1140334f485dSMiklos Szeredi int err; 1141334f485dSMiklos Szeredi struct fuse_req *req; 1142334f485dSMiklos Szeredi struct fuse_in *in; 1143334f485dSMiklos Szeredi unsigned reqsize; 1144334f485dSMiklos Szeredi 11451d3d752bSMiklos Szeredi restart: 1146d7133114SMiklos Szeredi spin_lock(&fc->lock); 1147e5ac1d1eSJeff Dike err = -EAGAIN; 1148e5ac1d1eSJeff Dike if ((file->f_flags & O_NONBLOCK) && fc->connected && 1149a4d27e75SMiklos Szeredi !request_pending(fc)) 1150e5ac1d1eSJeff Dike goto err_unlock; 1151e5ac1d1eSJeff Dike 1152334f485dSMiklos Szeredi request_wait(fc); 1153334f485dSMiklos Szeredi err = -ENODEV; 11549ba7cbbaSMiklos Szeredi if (!fc->connected) 1155334f485dSMiklos Szeredi goto err_unlock; 1156334f485dSMiklos Szeredi err = -ERESTARTSYS; 1157a4d27e75SMiklos Szeredi if (!request_pending(fc)) 1158334f485dSMiklos Szeredi goto err_unlock; 1159334f485dSMiklos Szeredi 1160a4d27e75SMiklos Szeredi if (!list_empty(&fc->interrupts)) { 1161a4d27e75SMiklos Szeredi req = list_entry(fc->interrupts.next, struct fuse_req, 1162a4d27e75SMiklos Szeredi intr_entry); 1163c3021629SMiklos Szeredi return fuse_read_interrupt(fc, cs, nbytes, req); 1164a4d27e75SMiklos Szeredi } 1165a4d27e75SMiklos Szeredi 116607e77dcaSMiklos Szeredi if (forget_pending(fc)) { 116707e77dcaSMiklos Szeredi if (list_empty(&fc->pending) || fc->forget_batch-- > 0) 116802c048b9SMiklos Szeredi return fuse_read_forget(fc, cs, nbytes); 116907e77dcaSMiklos Szeredi 117007e77dcaSMiklos Szeredi if (fc->forget_batch <= -8) 117107e77dcaSMiklos Szeredi fc->forget_batch = 16; 117207e77dcaSMiklos Szeredi } 117307e77dcaSMiklos Szeredi 1174334f485dSMiklos Szeredi req = list_entry(fc->pending.next, struct fuse_req, list); 117583cfd493SMiklos Szeredi req->state = FUSE_REQ_READING; 1176d77a1d5bSMiklos Szeredi list_move(&req->list, &fc->io); 1177334f485dSMiklos Szeredi 1178334f485dSMiklos Szeredi in = &req->in; 11791d3d752bSMiklos Szeredi reqsize = in->h.len; 11801d3d752bSMiklos Szeredi /* If request is too large, reply with an error and restart the read */ 1181c3021629SMiklos Szeredi if (nbytes < reqsize) { 11821d3d752bSMiklos Szeredi req->out.h.error = -EIO; 11831d3d752bSMiklos Szeredi /* SETXATTR is special, since it may contain too large data */ 11841d3d752bSMiklos Szeredi if (in->h.opcode == FUSE_SETXATTR) 11851d3d752bSMiklos Szeredi req->out.h.error = -E2BIG; 11861d3d752bSMiklos Szeredi request_end(fc, req); 11871d3d752bSMiklos Szeredi goto restart; 11881d3d752bSMiklos Szeredi } 1189d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1190c3021629SMiklos Szeredi cs->req = req; 1191c3021629SMiklos Szeredi err = fuse_copy_one(cs, &in->h, sizeof(in->h)); 1192334f485dSMiklos Szeredi if (!err) 1193c3021629SMiklos Szeredi err = fuse_copy_args(cs, in->numargs, in->argpages, 1194334f485dSMiklos Szeredi (struct fuse_arg *) in->args, 0); 1195c3021629SMiklos Szeredi fuse_copy_finish(cs); 1196d7133114SMiklos Szeredi spin_lock(&fc->lock); 1197334f485dSMiklos Szeredi req->locked = 0; 1198c9c9d7dfSMiklos Szeredi if (req->aborted) { 1199c9c9d7dfSMiklos Szeredi request_end(fc, req); 1200c9c9d7dfSMiklos Szeredi return -ENODEV; 1201c9c9d7dfSMiklos Szeredi } 1202334f485dSMiklos Szeredi if (err) { 1203334f485dSMiklos Szeredi req->out.h.error = -EIO; 1204334f485dSMiklos Szeredi request_end(fc, req); 1205334f485dSMiklos Szeredi return err; 1206334f485dSMiklos Szeredi } 1207334f485dSMiklos Szeredi if (!req->isreply) 1208334f485dSMiklos Szeredi request_end(fc, req); 1209334f485dSMiklos Szeredi else { 121083cfd493SMiklos Szeredi req->state = FUSE_REQ_SENT; 1211d77a1d5bSMiklos Szeredi list_move_tail(&req->list, &fc->processing); 1212a4d27e75SMiklos Szeredi if (req->interrupted) 1213a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 1214d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1215334f485dSMiklos Szeredi } 1216334f485dSMiklos Szeredi return reqsize; 1217334f485dSMiklos Szeredi 1218334f485dSMiklos Szeredi err_unlock: 1219d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1220334f485dSMiklos Szeredi return err; 1221334f485dSMiklos Szeredi } 1222334f485dSMiklos Szeredi 1223c3021629SMiklos Szeredi static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, 1224c3021629SMiklos Szeredi unsigned long nr_segs, loff_t pos) 1225c3021629SMiklos Szeredi { 1226c3021629SMiklos Szeredi struct fuse_copy_state cs; 1227c3021629SMiklos Szeredi struct file *file = iocb->ki_filp; 1228c3021629SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 1229c3021629SMiklos Szeredi if (!fc) 1230c3021629SMiklos Szeredi return -EPERM; 1231c3021629SMiklos Szeredi 1232c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 1, iov, nr_segs); 1233c3021629SMiklos Szeredi 1234c3021629SMiklos Szeredi return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs)); 1235c3021629SMiklos Szeredi } 1236c3021629SMiklos Szeredi 1237c3021629SMiklos Szeredi static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe, 1238c3021629SMiklos Szeredi struct pipe_buffer *buf) 1239c3021629SMiklos Szeredi { 1240c3021629SMiklos Szeredi return 1; 1241c3021629SMiklos Szeredi } 1242c3021629SMiklos Szeredi 1243c3021629SMiklos Szeredi static const struct pipe_buf_operations fuse_dev_pipe_buf_ops = { 1244c3021629SMiklos Szeredi .can_merge = 0, 1245c3021629SMiklos Szeredi .map = generic_pipe_buf_map, 1246c3021629SMiklos Szeredi .unmap = generic_pipe_buf_unmap, 1247c3021629SMiklos Szeredi .confirm = generic_pipe_buf_confirm, 1248c3021629SMiklos Szeredi .release = generic_pipe_buf_release, 1249c3021629SMiklos Szeredi .steal = fuse_dev_pipe_buf_steal, 1250c3021629SMiklos Szeredi .get = generic_pipe_buf_get, 1251c3021629SMiklos Szeredi }; 1252c3021629SMiklos Szeredi 1253c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, 1254c3021629SMiklos Szeredi struct pipe_inode_info *pipe, 1255c3021629SMiklos Szeredi size_t len, unsigned int flags) 1256c3021629SMiklos Szeredi { 1257c3021629SMiklos Szeredi int ret; 1258c3021629SMiklos Szeredi int page_nr = 0; 1259c3021629SMiklos Szeredi int do_wakeup = 0; 1260c3021629SMiklos Szeredi struct pipe_buffer *bufs; 1261c3021629SMiklos Szeredi struct fuse_copy_state cs; 1262c3021629SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(in); 1263c3021629SMiklos Szeredi if (!fc) 1264c3021629SMiklos Szeredi return -EPERM; 1265c3021629SMiklos Szeredi 1266c3021629SMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1267c3021629SMiklos Szeredi if (!bufs) 1268c3021629SMiklos Szeredi return -ENOMEM; 1269c3021629SMiklos Szeredi 1270c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 1, NULL, 0); 1271c3021629SMiklos Szeredi cs.pipebufs = bufs; 1272c3021629SMiklos Szeredi cs.pipe = pipe; 1273c3021629SMiklos Szeredi ret = fuse_dev_do_read(fc, in, &cs, len); 1274c3021629SMiklos Szeredi if (ret < 0) 1275c3021629SMiklos Szeredi goto out; 1276c3021629SMiklos Szeredi 1277c3021629SMiklos Szeredi ret = 0; 1278c3021629SMiklos Szeredi pipe_lock(pipe); 1279c3021629SMiklos Szeredi 1280c3021629SMiklos Szeredi if (!pipe->readers) { 1281c3021629SMiklos Szeredi send_sig(SIGPIPE, current, 0); 1282c3021629SMiklos Szeredi if (!ret) 1283c3021629SMiklos Szeredi ret = -EPIPE; 1284c3021629SMiklos Szeredi goto out_unlock; 1285c3021629SMiklos Szeredi } 1286c3021629SMiklos Szeredi 1287c3021629SMiklos Szeredi if (pipe->nrbufs + cs.nr_segs > pipe->buffers) { 1288c3021629SMiklos Szeredi ret = -EIO; 1289c3021629SMiklos Szeredi goto out_unlock; 1290c3021629SMiklos Szeredi } 1291c3021629SMiklos Szeredi 1292c3021629SMiklos Szeredi while (page_nr < cs.nr_segs) { 1293c3021629SMiklos Szeredi int newbuf = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); 1294c3021629SMiklos Szeredi struct pipe_buffer *buf = pipe->bufs + newbuf; 1295c3021629SMiklos Szeredi 1296c3021629SMiklos Szeredi buf->page = bufs[page_nr].page; 1297c3021629SMiklos Szeredi buf->offset = bufs[page_nr].offset; 1298c3021629SMiklos Szeredi buf->len = bufs[page_nr].len; 1299c3021629SMiklos Szeredi buf->ops = &fuse_dev_pipe_buf_ops; 1300c3021629SMiklos Szeredi 1301c3021629SMiklos Szeredi pipe->nrbufs++; 1302c3021629SMiklos Szeredi page_nr++; 1303c3021629SMiklos Szeredi ret += buf->len; 1304c3021629SMiklos Szeredi 1305c3021629SMiklos Szeredi if (pipe->inode) 1306c3021629SMiklos Szeredi do_wakeup = 1; 1307c3021629SMiklos Szeredi } 1308c3021629SMiklos Szeredi 1309c3021629SMiklos Szeredi out_unlock: 1310c3021629SMiklos Szeredi pipe_unlock(pipe); 1311c3021629SMiklos Szeredi 1312c3021629SMiklos Szeredi if (do_wakeup) { 1313c3021629SMiklos Szeredi smp_mb(); 1314c3021629SMiklos Szeredi if (waitqueue_active(&pipe->wait)) 1315c3021629SMiklos Szeredi wake_up_interruptible(&pipe->wait); 1316c3021629SMiklos Szeredi kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); 1317c3021629SMiklos Szeredi } 1318c3021629SMiklos Szeredi 1319c3021629SMiklos Szeredi out: 1320c3021629SMiklos Szeredi for (; page_nr < cs.nr_segs; page_nr++) 1321c3021629SMiklos Szeredi page_cache_release(bufs[page_nr].page); 1322c3021629SMiklos Szeredi 1323c3021629SMiklos Szeredi kfree(bufs); 1324c3021629SMiklos Szeredi return ret; 1325c3021629SMiklos Szeredi } 1326c3021629SMiklos Szeredi 132795668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size, 132895668a69STejun Heo struct fuse_copy_state *cs) 132995668a69STejun Heo { 133095668a69STejun Heo struct fuse_notify_poll_wakeup_out outarg; 1331f6d47a17SMiklos Szeredi int err = -EINVAL; 133295668a69STejun Heo 133395668a69STejun Heo if (size != sizeof(outarg)) 1334f6d47a17SMiklos Szeredi goto err; 133595668a69STejun Heo 133695668a69STejun Heo err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 133795668a69STejun Heo if (err) 1338f6d47a17SMiklos Szeredi goto err; 133995668a69STejun Heo 1340f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 134195668a69STejun Heo return fuse_notify_poll_wakeup(fc, &outarg); 1342f6d47a17SMiklos Szeredi 1343f6d47a17SMiklos Szeredi err: 1344f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 1345f6d47a17SMiklos Szeredi return err; 134695668a69STejun Heo } 134795668a69STejun Heo 13483b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size, 13493b463ae0SJohn Muir struct fuse_copy_state *cs) 13503b463ae0SJohn Muir { 13513b463ae0SJohn Muir struct fuse_notify_inval_inode_out outarg; 13523b463ae0SJohn Muir int err = -EINVAL; 13533b463ae0SJohn Muir 13543b463ae0SJohn Muir if (size != sizeof(outarg)) 13553b463ae0SJohn Muir goto err; 13563b463ae0SJohn Muir 13573b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 13583b463ae0SJohn Muir if (err) 13593b463ae0SJohn Muir goto err; 13603b463ae0SJohn Muir fuse_copy_finish(cs); 13613b463ae0SJohn Muir 13623b463ae0SJohn Muir down_read(&fc->killsb); 13633b463ae0SJohn Muir err = -ENOENT; 1364b21dda43SMiklos Szeredi if (fc->sb) { 13653b463ae0SJohn Muir err = fuse_reverse_inval_inode(fc->sb, outarg.ino, 13663b463ae0SJohn Muir outarg.off, outarg.len); 1367b21dda43SMiklos Szeredi } 13683b463ae0SJohn Muir up_read(&fc->killsb); 13693b463ae0SJohn Muir return err; 13703b463ae0SJohn Muir 13713b463ae0SJohn Muir err: 13723b463ae0SJohn Muir fuse_copy_finish(cs); 13733b463ae0SJohn Muir return err; 13743b463ae0SJohn Muir } 13753b463ae0SJohn Muir 13763b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, 13773b463ae0SJohn Muir struct fuse_copy_state *cs) 13783b463ae0SJohn Muir { 13793b463ae0SJohn Muir struct fuse_notify_inval_entry_out outarg; 1380b2d82ee3SFang Wenqi int err = -ENOMEM; 1381b2d82ee3SFang Wenqi char *buf; 13823b463ae0SJohn Muir struct qstr name; 13833b463ae0SJohn Muir 1384b2d82ee3SFang Wenqi buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1385b2d82ee3SFang Wenqi if (!buf) 1386b2d82ee3SFang Wenqi goto err; 1387b2d82ee3SFang Wenqi 1388b2d82ee3SFang Wenqi err = -EINVAL; 13893b463ae0SJohn Muir if (size < sizeof(outarg)) 13903b463ae0SJohn Muir goto err; 13913b463ae0SJohn Muir 13923b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 13933b463ae0SJohn Muir if (err) 13943b463ae0SJohn Muir goto err; 13953b463ae0SJohn Muir 13963b463ae0SJohn Muir err = -ENAMETOOLONG; 13973b463ae0SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 13983b463ae0SJohn Muir goto err; 13993b463ae0SJohn Muir 1400c2183d1eSMiklos Szeredi err = -EINVAL; 1401c2183d1eSMiklos Szeredi if (size != sizeof(outarg) + outarg.namelen + 1) 1402c2183d1eSMiklos Szeredi goto err; 1403c2183d1eSMiklos Szeredi 14043b463ae0SJohn Muir name.name = buf; 14053b463ae0SJohn Muir name.len = outarg.namelen; 14063b463ae0SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 14073b463ae0SJohn Muir if (err) 14083b463ae0SJohn Muir goto err; 14093b463ae0SJohn Muir fuse_copy_finish(cs); 14103b463ae0SJohn Muir buf[outarg.namelen] = 0; 14113b463ae0SJohn Muir name.hash = full_name_hash(name.name, name.len); 14123b463ae0SJohn Muir 14133b463ae0SJohn Muir down_read(&fc->killsb); 14143b463ae0SJohn Muir err = -ENOENT; 1415b21dda43SMiklos Szeredi if (fc->sb) 1416451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 0, &name); 1417451d0f59SJohn Muir up_read(&fc->killsb); 1418451d0f59SJohn Muir kfree(buf); 1419451d0f59SJohn Muir return err; 1420451d0f59SJohn Muir 1421451d0f59SJohn Muir err: 1422451d0f59SJohn Muir kfree(buf); 1423451d0f59SJohn Muir fuse_copy_finish(cs); 1424451d0f59SJohn Muir return err; 1425451d0f59SJohn Muir } 1426451d0f59SJohn Muir 1427451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size, 1428451d0f59SJohn Muir struct fuse_copy_state *cs) 1429451d0f59SJohn Muir { 1430451d0f59SJohn Muir struct fuse_notify_delete_out outarg; 1431451d0f59SJohn Muir int err = -ENOMEM; 1432451d0f59SJohn Muir char *buf; 1433451d0f59SJohn Muir struct qstr name; 1434451d0f59SJohn Muir 1435451d0f59SJohn Muir buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1436451d0f59SJohn Muir if (!buf) 1437451d0f59SJohn Muir goto err; 1438451d0f59SJohn Muir 1439451d0f59SJohn Muir err = -EINVAL; 1440451d0f59SJohn Muir if (size < sizeof(outarg)) 1441451d0f59SJohn Muir goto err; 1442451d0f59SJohn Muir 1443451d0f59SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1444451d0f59SJohn Muir if (err) 1445451d0f59SJohn Muir goto err; 1446451d0f59SJohn Muir 1447451d0f59SJohn Muir err = -ENAMETOOLONG; 1448451d0f59SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 1449451d0f59SJohn Muir goto err; 1450451d0f59SJohn Muir 1451451d0f59SJohn Muir err = -EINVAL; 1452451d0f59SJohn Muir if (size != sizeof(outarg) + outarg.namelen + 1) 1453451d0f59SJohn Muir goto err; 1454451d0f59SJohn Muir 1455451d0f59SJohn Muir name.name = buf; 1456451d0f59SJohn Muir name.len = outarg.namelen; 1457451d0f59SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 1458451d0f59SJohn Muir if (err) 1459451d0f59SJohn Muir goto err; 1460451d0f59SJohn Muir fuse_copy_finish(cs); 1461451d0f59SJohn Muir buf[outarg.namelen] = 0; 1462451d0f59SJohn Muir name.hash = full_name_hash(name.name, name.len); 1463451d0f59SJohn Muir 1464451d0f59SJohn Muir down_read(&fc->killsb); 1465451d0f59SJohn Muir err = -ENOENT; 1466451d0f59SJohn Muir if (fc->sb) 1467451d0f59SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 1468451d0f59SJohn Muir outarg.child, &name); 14693b463ae0SJohn Muir up_read(&fc->killsb); 1470b2d82ee3SFang Wenqi kfree(buf); 14713b463ae0SJohn Muir return err; 14723b463ae0SJohn Muir 14733b463ae0SJohn Muir err: 1474b2d82ee3SFang Wenqi kfree(buf); 14753b463ae0SJohn Muir fuse_copy_finish(cs); 14763b463ae0SJohn Muir return err; 14773b463ae0SJohn Muir } 14783b463ae0SJohn Muir 1479a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, 1480a1d75f25SMiklos Szeredi struct fuse_copy_state *cs) 1481a1d75f25SMiklos Szeredi { 1482a1d75f25SMiklos Szeredi struct fuse_notify_store_out outarg; 1483a1d75f25SMiklos Szeredi struct inode *inode; 1484a1d75f25SMiklos Szeredi struct address_space *mapping; 1485a1d75f25SMiklos Szeredi u64 nodeid; 1486a1d75f25SMiklos Szeredi int err; 1487a1d75f25SMiklos Szeredi pgoff_t index; 1488a1d75f25SMiklos Szeredi unsigned int offset; 1489a1d75f25SMiklos Szeredi unsigned int num; 1490a1d75f25SMiklos Szeredi loff_t file_size; 1491a1d75f25SMiklos Szeredi loff_t end; 1492a1d75f25SMiklos Szeredi 1493a1d75f25SMiklos Szeredi err = -EINVAL; 1494a1d75f25SMiklos Szeredi if (size < sizeof(outarg)) 1495a1d75f25SMiklos Szeredi goto out_finish; 1496a1d75f25SMiklos Szeredi 1497a1d75f25SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1498a1d75f25SMiklos Szeredi if (err) 1499a1d75f25SMiklos Szeredi goto out_finish; 1500a1d75f25SMiklos Szeredi 1501a1d75f25SMiklos Szeredi err = -EINVAL; 1502a1d75f25SMiklos Szeredi if (size - sizeof(outarg) != outarg.size) 1503a1d75f25SMiklos Szeredi goto out_finish; 1504a1d75f25SMiklos Szeredi 1505a1d75f25SMiklos Szeredi nodeid = outarg.nodeid; 1506a1d75f25SMiklos Szeredi 1507a1d75f25SMiklos Szeredi down_read(&fc->killsb); 1508a1d75f25SMiklos Szeredi 1509a1d75f25SMiklos Szeredi err = -ENOENT; 1510a1d75f25SMiklos Szeredi if (!fc->sb) 1511a1d75f25SMiklos Szeredi goto out_up_killsb; 1512a1d75f25SMiklos Szeredi 1513a1d75f25SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 1514a1d75f25SMiklos Szeredi if (!inode) 1515a1d75f25SMiklos Szeredi goto out_up_killsb; 1516a1d75f25SMiklos Szeredi 1517a1d75f25SMiklos Szeredi mapping = inode->i_mapping; 1518a1d75f25SMiklos Szeredi index = outarg.offset >> PAGE_CACHE_SHIFT; 1519a1d75f25SMiklos Szeredi offset = outarg.offset & ~PAGE_CACHE_MASK; 1520a1d75f25SMiklos Szeredi file_size = i_size_read(inode); 1521a1d75f25SMiklos Szeredi end = outarg.offset + outarg.size; 1522a1d75f25SMiklos Szeredi if (end > file_size) { 1523a1d75f25SMiklos Szeredi file_size = end; 1524a1d75f25SMiklos Szeredi fuse_write_update_size(inode, file_size); 1525a1d75f25SMiklos Szeredi } 1526a1d75f25SMiklos Szeredi 1527a1d75f25SMiklos Szeredi num = outarg.size; 1528a1d75f25SMiklos Szeredi while (num) { 1529a1d75f25SMiklos Szeredi struct page *page; 1530a1d75f25SMiklos Szeredi unsigned int this_num; 1531a1d75f25SMiklos Szeredi 1532a1d75f25SMiklos Szeredi err = -ENOMEM; 1533a1d75f25SMiklos Szeredi page = find_or_create_page(mapping, index, 1534a1d75f25SMiklos Szeredi mapping_gfp_mask(mapping)); 1535a1d75f25SMiklos Szeredi if (!page) 1536a1d75f25SMiklos Szeredi goto out_iput; 1537a1d75f25SMiklos Szeredi 1538a1d75f25SMiklos Szeredi this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 1539a1d75f25SMiklos Szeredi err = fuse_copy_page(cs, &page, offset, this_num, 0); 1540a1d75f25SMiklos Szeredi if (!err && offset == 0 && (num != 0 || file_size == end)) 1541a1d75f25SMiklos Szeredi SetPageUptodate(page); 1542a1d75f25SMiklos Szeredi unlock_page(page); 1543a1d75f25SMiklos Szeredi page_cache_release(page); 1544a1d75f25SMiklos Szeredi 1545a1d75f25SMiklos Szeredi if (err) 1546a1d75f25SMiklos Szeredi goto out_iput; 1547a1d75f25SMiklos Szeredi 1548a1d75f25SMiklos Szeredi num -= this_num; 1549a1d75f25SMiklos Szeredi offset = 0; 1550a1d75f25SMiklos Szeredi index++; 1551a1d75f25SMiklos Szeredi } 1552a1d75f25SMiklos Szeredi 1553a1d75f25SMiklos Szeredi err = 0; 1554a1d75f25SMiklos Szeredi 1555a1d75f25SMiklos Szeredi out_iput: 1556a1d75f25SMiklos Szeredi iput(inode); 1557a1d75f25SMiklos Szeredi out_up_killsb: 1558a1d75f25SMiklos Szeredi up_read(&fc->killsb); 1559a1d75f25SMiklos Szeredi out_finish: 1560a1d75f25SMiklos Szeredi fuse_copy_finish(cs); 1561a1d75f25SMiklos Szeredi return err; 1562a1d75f25SMiklos Szeredi } 1563a1d75f25SMiklos Szeredi 15642d45ba38SMiklos Szeredi static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) 15652d45ba38SMiklos Szeredi { 15660be8557bSMiklos Szeredi release_pages(req->pages, req->num_pages, 0); 15672d45ba38SMiklos Szeredi } 15682d45ba38SMiklos Szeredi 15692d45ba38SMiklos Szeredi static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, 15702d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out *outarg) 15712d45ba38SMiklos Szeredi { 15722d45ba38SMiklos Szeredi int err; 15732d45ba38SMiklos Szeredi struct address_space *mapping = inode->i_mapping; 15742d45ba38SMiklos Szeredi struct fuse_req *req; 15752d45ba38SMiklos Szeredi pgoff_t index; 15762d45ba38SMiklos Szeredi loff_t file_size; 15772d45ba38SMiklos Szeredi unsigned int num; 15782d45ba38SMiklos Szeredi unsigned int offset; 15790157443cSGeert Uytterhoeven size_t total_len = 0; 15802d45ba38SMiklos Szeredi 1581b111c8c0SMaxim Patlasov req = fuse_get_req(fc, FUSE_MAX_PAGES_PER_REQ); 15822d45ba38SMiklos Szeredi if (IS_ERR(req)) 15832d45ba38SMiklos Szeredi return PTR_ERR(req); 15842d45ba38SMiklos Szeredi 15852d45ba38SMiklos Szeredi offset = outarg->offset & ~PAGE_CACHE_MASK; 15862d45ba38SMiklos Szeredi 15872d45ba38SMiklos Szeredi req->in.h.opcode = FUSE_NOTIFY_REPLY; 15882d45ba38SMiklos Szeredi req->in.h.nodeid = outarg->nodeid; 15892d45ba38SMiklos Szeredi req->in.numargs = 2; 15902d45ba38SMiklos Szeredi req->in.argpages = 1; 15912d45ba38SMiklos Szeredi req->page_offset = offset; 15922d45ba38SMiklos Szeredi req->end = fuse_retrieve_end; 15932d45ba38SMiklos Szeredi 15942d45ba38SMiklos Szeredi index = outarg->offset >> PAGE_CACHE_SHIFT; 15952d45ba38SMiklos Szeredi file_size = i_size_read(inode); 15962d45ba38SMiklos Szeredi num = outarg->size; 15972d45ba38SMiklos Szeredi if (outarg->offset > file_size) 15982d45ba38SMiklos Szeredi num = 0; 15992d45ba38SMiklos Szeredi else if (outarg->offset + num > file_size) 16002d45ba38SMiklos Szeredi num = file_size - outarg->offset; 16012d45ba38SMiklos Szeredi 160248706d0aSMiklos Szeredi while (num && req->num_pages < FUSE_MAX_PAGES_PER_REQ) { 16032d45ba38SMiklos Szeredi struct page *page; 16042d45ba38SMiklos Szeredi unsigned int this_num; 16052d45ba38SMiklos Szeredi 16062d45ba38SMiklos Szeredi page = find_get_page(mapping, index); 16072d45ba38SMiklos Szeredi if (!page) 16082d45ba38SMiklos Szeredi break; 16092d45ba38SMiklos Szeredi 16102d45ba38SMiklos Szeredi this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 16112d45ba38SMiklos Szeredi req->pages[req->num_pages] = page; 16122d45ba38SMiklos Szeredi req->num_pages++; 16132d45ba38SMiklos Szeredi 1614c9e67d48SMiklos Szeredi offset = 0; 16152d45ba38SMiklos Szeredi num -= this_num; 16162d45ba38SMiklos Szeredi total_len += this_num; 161748706d0aSMiklos Szeredi index++; 16182d45ba38SMiklos Szeredi } 16192d45ba38SMiklos Szeredi req->misc.retrieve_in.offset = outarg->offset; 16202d45ba38SMiklos Szeredi req->misc.retrieve_in.size = total_len; 16212d45ba38SMiklos Szeredi req->in.args[0].size = sizeof(req->misc.retrieve_in); 16222d45ba38SMiklos Szeredi req->in.args[0].value = &req->misc.retrieve_in; 16232d45ba38SMiklos Szeredi req->in.args[1].size = total_len; 16242d45ba38SMiklos Szeredi 16252d45ba38SMiklos Szeredi err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique); 16262d45ba38SMiklos Szeredi if (err) 16272d45ba38SMiklos Szeredi fuse_retrieve_end(fc, req); 16282d45ba38SMiklos Szeredi 16292d45ba38SMiklos Szeredi return err; 16302d45ba38SMiklos Szeredi } 16312d45ba38SMiklos Szeredi 16322d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, 16332d45ba38SMiklos Szeredi struct fuse_copy_state *cs) 16342d45ba38SMiklos Szeredi { 16352d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out outarg; 16362d45ba38SMiklos Szeredi struct inode *inode; 16372d45ba38SMiklos Szeredi int err; 16382d45ba38SMiklos Szeredi 16392d45ba38SMiklos Szeredi err = -EINVAL; 16402d45ba38SMiklos Szeredi if (size != sizeof(outarg)) 16412d45ba38SMiklos Szeredi goto copy_finish; 16422d45ba38SMiklos Szeredi 16432d45ba38SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 16442d45ba38SMiklos Szeredi if (err) 16452d45ba38SMiklos Szeredi goto copy_finish; 16462d45ba38SMiklos Szeredi 16472d45ba38SMiklos Szeredi fuse_copy_finish(cs); 16482d45ba38SMiklos Szeredi 16492d45ba38SMiklos Szeredi down_read(&fc->killsb); 16502d45ba38SMiklos Szeredi err = -ENOENT; 16512d45ba38SMiklos Szeredi if (fc->sb) { 16522d45ba38SMiklos Szeredi u64 nodeid = outarg.nodeid; 16532d45ba38SMiklos Szeredi 16542d45ba38SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 16552d45ba38SMiklos Szeredi if (inode) { 16562d45ba38SMiklos Szeredi err = fuse_retrieve(fc, inode, &outarg); 16572d45ba38SMiklos Szeredi iput(inode); 16582d45ba38SMiklos Szeredi } 16592d45ba38SMiklos Szeredi } 16602d45ba38SMiklos Szeredi up_read(&fc->killsb); 16612d45ba38SMiklos Szeredi 16622d45ba38SMiklos Szeredi return err; 16632d45ba38SMiklos Szeredi 16642d45ba38SMiklos Szeredi copy_finish: 16652d45ba38SMiklos Szeredi fuse_copy_finish(cs); 16662d45ba38SMiklos Szeredi return err; 16672d45ba38SMiklos Szeredi } 16682d45ba38SMiklos Szeredi 16698599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, 16708599396bSTejun Heo unsigned int size, struct fuse_copy_state *cs) 16718599396bSTejun Heo { 16728599396bSTejun Heo switch (code) { 167395668a69STejun Heo case FUSE_NOTIFY_POLL: 167495668a69STejun Heo return fuse_notify_poll(fc, size, cs); 167595668a69STejun Heo 16763b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_INODE: 16773b463ae0SJohn Muir return fuse_notify_inval_inode(fc, size, cs); 16783b463ae0SJohn Muir 16793b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_ENTRY: 16803b463ae0SJohn Muir return fuse_notify_inval_entry(fc, size, cs); 16813b463ae0SJohn Muir 1682a1d75f25SMiklos Szeredi case FUSE_NOTIFY_STORE: 1683a1d75f25SMiklos Szeredi return fuse_notify_store(fc, size, cs); 1684a1d75f25SMiklos Szeredi 16852d45ba38SMiklos Szeredi case FUSE_NOTIFY_RETRIEVE: 16862d45ba38SMiklos Szeredi return fuse_notify_retrieve(fc, size, cs); 16872d45ba38SMiklos Szeredi 1688451d0f59SJohn Muir case FUSE_NOTIFY_DELETE: 1689451d0f59SJohn Muir return fuse_notify_delete(fc, size, cs); 1690451d0f59SJohn Muir 16918599396bSTejun Heo default: 1692f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 16938599396bSTejun Heo return -EINVAL; 16948599396bSTejun Heo } 16958599396bSTejun Heo } 16968599396bSTejun Heo 1697334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */ 1698334f485dSMiklos Szeredi static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) 1699334f485dSMiklos Szeredi { 1700334f485dSMiklos Szeredi struct list_head *entry; 1701334f485dSMiklos Szeredi 1702334f485dSMiklos Szeredi list_for_each(entry, &fc->processing) { 1703334f485dSMiklos Szeredi struct fuse_req *req; 1704334f485dSMiklos Szeredi req = list_entry(entry, struct fuse_req, list); 1705a4d27e75SMiklos Szeredi if (req->in.h.unique == unique || req->intr_unique == unique) 1706334f485dSMiklos Szeredi return req; 1707334f485dSMiklos Szeredi } 1708334f485dSMiklos Szeredi return NULL; 1709334f485dSMiklos Szeredi } 1710334f485dSMiklos Szeredi 1711334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out, 1712334f485dSMiklos Szeredi unsigned nbytes) 1713334f485dSMiklos Szeredi { 1714334f485dSMiklos Szeredi unsigned reqsize = sizeof(struct fuse_out_header); 1715334f485dSMiklos Szeredi 1716334f485dSMiklos Szeredi if (out->h.error) 1717334f485dSMiklos Szeredi return nbytes != reqsize ? -EINVAL : 0; 1718334f485dSMiklos Szeredi 1719334f485dSMiklos Szeredi reqsize += len_args(out->numargs, out->args); 1720334f485dSMiklos Szeredi 1721334f485dSMiklos Szeredi if (reqsize < nbytes || (reqsize > nbytes && !out->argvar)) 1722334f485dSMiklos Szeredi return -EINVAL; 1723334f485dSMiklos Szeredi else if (reqsize > nbytes) { 1724334f485dSMiklos Szeredi struct fuse_arg *lastarg = &out->args[out->numargs-1]; 1725334f485dSMiklos Szeredi unsigned diffsize = reqsize - nbytes; 1726334f485dSMiklos Szeredi if (diffsize > lastarg->size) 1727334f485dSMiklos Szeredi return -EINVAL; 1728334f485dSMiklos Szeredi lastarg->size -= diffsize; 1729334f485dSMiklos Szeredi } 1730334f485dSMiklos Szeredi return fuse_copy_args(cs, out->numargs, out->argpages, out->args, 1731334f485dSMiklos Szeredi out->page_zeroing); 1732334f485dSMiklos Szeredi } 1733334f485dSMiklos Szeredi 1734334f485dSMiklos Szeredi /* 1735334f485dSMiklos Szeredi * Write a single reply to a request. First the header is copied from 1736334f485dSMiklos Szeredi * the write buffer. The request is then searched on the processing 1737334f485dSMiklos Szeredi * list by the unique ID found in the header. If found, then remove 1738334f485dSMiklos Szeredi * it from the list and copy the rest of the buffer to the request. 1739334f485dSMiklos Szeredi * The request is finished by calling request_end() 1740334f485dSMiklos Szeredi */ 1741dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_conn *fc, 1742dd3bb14fSMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1743334f485dSMiklos Szeredi { 1744334f485dSMiklos Szeredi int err; 1745334f485dSMiklos Szeredi struct fuse_req *req; 1746334f485dSMiklos Szeredi struct fuse_out_header oh; 1747334f485dSMiklos Szeredi 1748334f485dSMiklos Szeredi if (nbytes < sizeof(struct fuse_out_header)) 1749334f485dSMiklos Szeredi return -EINVAL; 1750334f485dSMiklos Szeredi 1751dd3bb14fSMiklos Szeredi err = fuse_copy_one(cs, &oh, sizeof(oh)); 1752334f485dSMiklos Szeredi if (err) 1753334f485dSMiklos Szeredi goto err_finish; 17548599396bSTejun Heo 1755334f485dSMiklos Szeredi err = -EINVAL; 17568599396bSTejun Heo if (oh.len != nbytes) 17578599396bSTejun Heo goto err_finish; 17588599396bSTejun Heo 17598599396bSTejun Heo /* 17608599396bSTejun Heo * Zero oh.unique indicates unsolicited notification message 17618599396bSTejun Heo * and error contains notification code. 17628599396bSTejun Heo */ 17638599396bSTejun Heo if (!oh.unique) { 1764dd3bb14fSMiklos Szeredi err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs); 17658599396bSTejun Heo return err ? err : nbytes; 17668599396bSTejun Heo } 17678599396bSTejun Heo 17688599396bSTejun Heo err = -EINVAL; 17698599396bSTejun Heo if (oh.error <= -1000 || oh.error > 0) 1770334f485dSMiklos Szeredi goto err_finish; 1771334f485dSMiklos Szeredi 1772d7133114SMiklos Szeredi spin_lock(&fc->lock); 177369a53bf2SMiklos Szeredi err = -ENOENT; 177469a53bf2SMiklos Szeredi if (!fc->connected) 177569a53bf2SMiklos Szeredi goto err_unlock; 177669a53bf2SMiklos Szeredi 1777334f485dSMiklos Szeredi req = request_find(fc, oh.unique); 1778334f485dSMiklos Szeredi if (!req) 1779334f485dSMiklos Szeredi goto err_unlock; 1780334f485dSMiklos Szeredi 1781f9a2842eSMiklos Szeredi if (req->aborted) { 1782d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1783dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1784d7133114SMiklos Szeredi spin_lock(&fc->lock); 1785222f1d69SMiklos Szeredi request_end(fc, req); 1786334f485dSMiklos Szeredi return -ENOENT; 1787334f485dSMiklos Szeredi } 1788a4d27e75SMiklos Szeredi /* Is it an interrupt reply? */ 1789a4d27e75SMiklos Szeredi if (req->intr_unique == oh.unique) { 1790a4d27e75SMiklos Szeredi err = -EINVAL; 1791a4d27e75SMiklos Szeredi if (nbytes != sizeof(struct fuse_out_header)) 1792a4d27e75SMiklos Szeredi goto err_unlock; 1793a4d27e75SMiklos Szeredi 1794a4d27e75SMiklos Szeredi if (oh.error == -ENOSYS) 1795a4d27e75SMiklos Szeredi fc->no_interrupt = 1; 1796a4d27e75SMiklos Szeredi else if (oh.error == -EAGAIN) 1797a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 1798a4d27e75SMiklos Szeredi 1799a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 1800dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1801a4d27e75SMiklos Szeredi return nbytes; 1802a4d27e75SMiklos Szeredi } 1803a4d27e75SMiklos Szeredi 1804a4d27e75SMiklos Szeredi req->state = FUSE_REQ_WRITING; 1805d77a1d5bSMiklos Szeredi list_move(&req->list, &fc->io); 1806334f485dSMiklos Szeredi req->out.h = oh; 1807334f485dSMiklos Szeredi req->locked = 1; 1808dd3bb14fSMiklos Szeredi cs->req = req; 1809ce534fb0SMiklos Szeredi if (!req->out.page_replace) 1810ce534fb0SMiklos Szeredi cs->move_pages = 0; 1811d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1812334f485dSMiklos Szeredi 1813dd3bb14fSMiklos Szeredi err = copy_out_args(cs, &req->out, nbytes); 1814dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1815334f485dSMiklos Szeredi 1816d7133114SMiklos Szeredi spin_lock(&fc->lock); 1817334f485dSMiklos Szeredi req->locked = 0; 1818334f485dSMiklos Szeredi if (!err) { 1819f9a2842eSMiklos Szeredi if (req->aborted) 1820334f485dSMiklos Szeredi err = -ENOENT; 1821f9a2842eSMiklos Szeredi } else if (!req->aborted) 1822334f485dSMiklos Szeredi req->out.h.error = -EIO; 1823334f485dSMiklos Szeredi request_end(fc, req); 1824334f485dSMiklos Szeredi 1825334f485dSMiklos Szeredi return err ? err : nbytes; 1826334f485dSMiklos Szeredi 1827334f485dSMiklos Szeredi err_unlock: 1828d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1829334f485dSMiklos Szeredi err_finish: 1830dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1831334f485dSMiklos Szeredi return err; 1832334f485dSMiklos Szeredi } 1833334f485dSMiklos Szeredi 1834dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, 1835dd3bb14fSMiklos Szeredi unsigned long nr_segs, loff_t pos) 1836dd3bb14fSMiklos Szeredi { 1837dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1838dd3bb14fSMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp); 1839dd3bb14fSMiklos Szeredi if (!fc) 1840dd3bb14fSMiklos Szeredi return -EPERM; 1841dd3bb14fSMiklos Szeredi 1842c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 0, iov, nr_segs); 1843dd3bb14fSMiklos Szeredi 1844dd3bb14fSMiklos Szeredi return fuse_dev_do_write(fc, &cs, iov_length(iov, nr_segs)); 1845dd3bb14fSMiklos Szeredi } 1846dd3bb14fSMiklos Szeredi 1847dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, 1848dd3bb14fSMiklos Szeredi struct file *out, loff_t *ppos, 1849dd3bb14fSMiklos Szeredi size_t len, unsigned int flags) 1850dd3bb14fSMiklos Szeredi { 1851dd3bb14fSMiklos Szeredi unsigned nbuf; 1852dd3bb14fSMiklos Szeredi unsigned idx; 1853dd3bb14fSMiklos Szeredi struct pipe_buffer *bufs; 1854dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1855dd3bb14fSMiklos Szeredi struct fuse_conn *fc; 1856dd3bb14fSMiklos Szeredi size_t rem; 1857dd3bb14fSMiklos Szeredi ssize_t ret; 1858dd3bb14fSMiklos Szeredi 1859dd3bb14fSMiklos Szeredi fc = fuse_get_conn(out); 1860dd3bb14fSMiklos Szeredi if (!fc) 1861dd3bb14fSMiklos Szeredi return -EPERM; 1862dd3bb14fSMiklos Szeredi 1863dd3bb14fSMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1864dd3bb14fSMiklos Szeredi if (!bufs) 1865dd3bb14fSMiklos Szeredi return -ENOMEM; 1866dd3bb14fSMiklos Szeredi 1867dd3bb14fSMiklos Szeredi pipe_lock(pipe); 1868dd3bb14fSMiklos Szeredi nbuf = 0; 1869dd3bb14fSMiklos Szeredi rem = 0; 1870dd3bb14fSMiklos Szeredi for (idx = 0; idx < pipe->nrbufs && rem < len; idx++) 1871dd3bb14fSMiklos Szeredi rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len; 1872dd3bb14fSMiklos Szeredi 1873dd3bb14fSMiklos Szeredi ret = -EINVAL; 1874dd3bb14fSMiklos Szeredi if (rem < len) { 1875dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 1876dd3bb14fSMiklos Szeredi goto out; 1877dd3bb14fSMiklos Szeredi } 1878dd3bb14fSMiklos Szeredi 1879dd3bb14fSMiklos Szeredi rem = len; 1880dd3bb14fSMiklos Szeredi while (rem) { 1881dd3bb14fSMiklos Szeredi struct pipe_buffer *ibuf; 1882dd3bb14fSMiklos Szeredi struct pipe_buffer *obuf; 1883dd3bb14fSMiklos Szeredi 1884dd3bb14fSMiklos Szeredi BUG_ON(nbuf >= pipe->buffers); 1885dd3bb14fSMiklos Szeredi BUG_ON(!pipe->nrbufs); 1886dd3bb14fSMiklos Szeredi ibuf = &pipe->bufs[pipe->curbuf]; 1887dd3bb14fSMiklos Szeredi obuf = &bufs[nbuf]; 1888dd3bb14fSMiklos Szeredi 1889dd3bb14fSMiklos Szeredi if (rem >= ibuf->len) { 1890dd3bb14fSMiklos Szeredi *obuf = *ibuf; 1891dd3bb14fSMiklos Szeredi ibuf->ops = NULL; 1892dd3bb14fSMiklos Szeredi pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); 1893dd3bb14fSMiklos Szeredi pipe->nrbufs--; 1894dd3bb14fSMiklos Szeredi } else { 1895dd3bb14fSMiklos Szeredi ibuf->ops->get(pipe, ibuf); 1896dd3bb14fSMiklos Szeredi *obuf = *ibuf; 1897dd3bb14fSMiklos Szeredi obuf->flags &= ~PIPE_BUF_FLAG_GIFT; 1898dd3bb14fSMiklos Szeredi obuf->len = rem; 1899dd3bb14fSMiklos Szeredi ibuf->offset += obuf->len; 1900dd3bb14fSMiklos Szeredi ibuf->len -= obuf->len; 1901dd3bb14fSMiklos Szeredi } 1902dd3bb14fSMiklos Szeredi nbuf++; 1903dd3bb14fSMiklos Szeredi rem -= obuf->len; 1904dd3bb14fSMiklos Szeredi } 1905dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 1906dd3bb14fSMiklos Szeredi 1907c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 0, NULL, nbuf); 1908dd3bb14fSMiklos Szeredi cs.pipebufs = bufs; 1909dd3bb14fSMiklos Szeredi cs.pipe = pipe; 1910dd3bb14fSMiklos Szeredi 1911ce534fb0SMiklos Szeredi if (flags & SPLICE_F_MOVE) 1912ce534fb0SMiklos Szeredi cs.move_pages = 1; 1913ce534fb0SMiklos Szeredi 1914dd3bb14fSMiklos Szeredi ret = fuse_dev_do_write(fc, &cs, len); 1915dd3bb14fSMiklos Szeredi 1916dd3bb14fSMiklos Szeredi for (idx = 0; idx < nbuf; idx++) { 1917dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = &bufs[idx]; 1918dd3bb14fSMiklos Szeredi buf->ops->release(pipe, buf); 1919dd3bb14fSMiklos Szeredi } 1920dd3bb14fSMiklos Szeredi out: 1921dd3bb14fSMiklos Szeredi kfree(bufs); 1922dd3bb14fSMiklos Szeredi return ret; 1923dd3bb14fSMiklos Szeredi } 1924dd3bb14fSMiklos Szeredi 1925334f485dSMiklos Szeredi static unsigned fuse_dev_poll(struct file *file, poll_table *wait) 1926334f485dSMiklos Szeredi { 1927334f485dSMiklos Szeredi unsigned mask = POLLOUT | POLLWRNORM; 19287025d9adSMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 1929334f485dSMiklos Szeredi if (!fc) 19307025d9adSMiklos Szeredi return POLLERR; 1931334f485dSMiklos Szeredi 1932334f485dSMiklos Szeredi poll_wait(file, &fc->waitq, wait); 1933334f485dSMiklos Szeredi 1934d7133114SMiklos Szeredi spin_lock(&fc->lock); 19357025d9adSMiklos Szeredi if (!fc->connected) 19367025d9adSMiklos Szeredi mask = POLLERR; 1937a4d27e75SMiklos Szeredi else if (request_pending(fc)) 1938334f485dSMiklos Szeredi mask |= POLLIN | POLLRDNORM; 1939d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1940334f485dSMiklos Szeredi 1941334f485dSMiklos Szeredi return mask; 1942334f485dSMiklos Szeredi } 1943334f485dSMiklos Szeredi 194469a53bf2SMiklos Szeredi /* 194569a53bf2SMiklos Szeredi * Abort all requests on the given list (pending or processing) 194669a53bf2SMiklos Szeredi * 1947d7133114SMiklos Szeredi * This function releases and reacquires fc->lock 194869a53bf2SMiklos Szeredi */ 1949334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head) 1950b9ca67b2SMiklos Szeredi __releases(fc->lock) 1951b9ca67b2SMiklos Szeredi __acquires(fc->lock) 1952334f485dSMiklos Szeredi { 1953334f485dSMiklos Szeredi while (!list_empty(head)) { 1954334f485dSMiklos Szeredi struct fuse_req *req; 1955334f485dSMiklos Szeredi req = list_entry(head->next, struct fuse_req, list); 1956334f485dSMiklos Szeredi req->out.h.error = -ECONNABORTED; 1957334f485dSMiklos Szeredi request_end(fc, req); 1958d7133114SMiklos Szeredi spin_lock(&fc->lock); 1959334f485dSMiklos Szeredi } 1960334f485dSMiklos Szeredi } 1961334f485dSMiklos Szeredi 196269a53bf2SMiklos Szeredi /* 196369a53bf2SMiklos Szeredi * Abort requests under I/O 196469a53bf2SMiklos Szeredi * 1965f9a2842eSMiklos Szeredi * The requests are set to aborted and finished, and the request 196669a53bf2SMiklos Szeredi * waiter is woken up. This will make request_wait_answer() wait 196769a53bf2SMiklos Szeredi * until the request is unlocked and then return. 196864c6d8edSMiklos Szeredi * 196964c6d8edSMiklos Szeredi * If the request is asynchronous, then the end function needs to be 197064c6d8edSMiklos Szeredi * called after waiting for the request to be unlocked (if it was 197164c6d8edSMiklos Szeredi * locked). 197269a53bf2SMiklos Szeredi */ 197369a53bf2SMiklos Szeredi static void end_io_requests(struct fuse_conn *fc) 1974b9ca67b2SMiklos Szeredi __releases(fc->lock) 1975b9ca67b2SMiklos Szeredi __acquires(fc->lock) 197669a53bf2SMiklos Szeredi { 197769a53bf2SMiklos Szeredi while (!list_empty(&fc->io)) { 197864c6d8edSMiklos Szeredi struct fuse_req *req = 197964c6d8edSMiklos Szeredi list_entry(fc->io.next, struct fuse_req, list); 198064c6d8edSMiklos Szeredi void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; 198164c6d8edSMiklos Szeredi 1982f9a2842eSMiklos Szeredi req->aborted = 1; 198369a53bf2SMiklos Szeredi req->out.h.error = -ECONNABORTED; 198469a53bf2SMiklos Szeredi req->state = FUSE_REQ_FINISHED; 198569a53bf2SMiklos Szeredi list_del_init(&req->list); 198669a53bf2SMiklos Szeredi wake_up(&req->waitq); 198764c6d8edSMiklos Szeredi if (end) { 198864c6d8edSMiklos Szeredi req->end = NULL; 198964c6d8edSMiklos Szeredi __fuse_get_request(req); 1990d7133114SMiklos Szeredi spin_unlock(&fc->lock); 199164c6d8edSMiklos Szeredi wait_event(req->waitq, !req->locked); 199264c6d8edSMiklos Szeredi end(fc, req); 1993e9bb09ddSTejun Heo fuse_put_request(fc, req); 1994d7133114SMiklos Szeredi spin_lock(&fc->lock); 199564c6d8edSMiklos Szeredi } 199669a53bf2SMiklos Szeredi } 199769a53bf2SMiklos Szeredi } 199869a53bf2SMiklos Szeredi 1999595afaf9SMiklos Szeredi static void end_queued_requests(struct fuse_conn *fc) 2000b9ca67b2SMiklos Szeredi __releases(fc->lock) 2001b9ca67b2SMiklos Szeredi __acquires(fc->lock) 2002595afaf9SMiklos Szeredi { 2003595afaf9SMiklos Szeredi fc->max_background = UINT_MAX; 2004595afaf9SMiklos Szeredi flush_bg_queue(fc); 2005595afaf9SMiklos Szeredi end_requests(fc, &fc->pending); 2006595afaf9SMiklos Szeredi end_requests(fc, &fc->processing); 200707e77dcaSMiklos Szeredi while (forget_pending(fc)) 200802c048b9SMiklos Szeredi kfree(dequeue_forget(fc, 1, NULL)); 2009595afaf9SMiklos Szeredi } 2010595afaf9SMiklos Szeredi 2011357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc) 2012357ccf2bSBryan Green { 2013357ccf2bSBryan Green struct rb_node *p; 2014357ccf2bSBryan Green 2015357ccf2bSBryan Green p = rb_first(&fc->polled_files); 2016357ccf2bSBryan Green 2017357ccf2bSBryan Green while (p) { 2018357ccf2bSBryan Green struct fuse_file *ff; 2019357ccf2bSBryan Green ff = rb_entry(p, struct fuse_file, polled_node); 2020357ccf2bSBryan Green wake_up_interruptible_all(&ff->poll_wait); 2021357ccf2bSBryan Green 2022357ccf2bSBryan Green p = rb_next(p); 2023357ccf2bSBryan Green } 2024357ccf2bSBryan Green } 2025357ccf2bSBryan Green 202669a53bf2SMiklos Szeredi /* 202769a53bf2SMiklos Szeredi * Abort all requests. 202869a53bf2SMiklos Szeredi * 202969a53bf2SMiklos Szeredi * Emergency exit in case of a malicious or accidental deadlock, or 203069a53bf2SMiklos Szeredi * just a hung filesystem. 203169a53bf2SMiklos Szeredi * 203269a53bf2SMiklos Szeredi * The same effect is usually achievable through killing the 203369a53bf2SMiklos Szeredi * filesystem daemon and all users of the filesystem. The exception 203469a53bf2SMiklos Szeredi * is the combination of an asynchronous request and the tricky 203569a53bf2SMiklos Szeredi * deadlock (see Documentation/filesystems/fuse.txt). 203669a53bf2SMiklos Szeredi * 203769a53bf2SMiklos Szeredi * During the aborting, progression of requests from the pending and 203869a53bf2SMiklos Szeredi * processing lists onto the io list, and progression of new requests 203969a53bf2SMiklos Szeredi * onto the pending list is prevented by req->connected being false. 204069a53bf2SMiklos Szeredi * 204169a53bf2SMiklos Szeredi * Progression of requests under I/O to the processing list is 2042f9a2842eSMiklos Szeredi * prevented by the req->aborted flag being true for these requests. 2043f9a2842eSMiklos Szeredi * For this reason requests on the io list must be aborted first. 204469a53bf2SMiklos Szeredi */ 204569a53bf2SMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc) 204669a53bf2SMiklos Szeredi { 2047d7133114SMiklos Szeredi spin_lock(&fc->lock); 204869a53bf2SMiklos Szeredi if (fc->connected) { 204969a53bf2SMiklos Szeredi fc->connected = 0; 205051eb01e7SMiklos Szeredi fc->blocked = 0; 205169a53bf2SMiklos Szeredi end_io_requests(fc); 2052595afaf9SMiklos Szeredi end_queued_requests(fc); 2053357ccf2bSBryan Green end_polls(fc); 205469a53bf2SMiklos Szeredi wake_up_all(&fc->waitq); 205551eb01e7SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 2056385a17bfSJeff Dike kill_fasync(&fc->fasync, SIGIO, POLL_IN); 205769a53bf2SMiklos Szeredi } 2058d7133114SMiklos Szeredi spin_unlock(&fc->lock); 205969a53bf2SMiklos Szeredi } 206008cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn); 206169a53bf2SMiklos Szeredi 206208cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file) 2063334f485dSMiklos Szeredi { 20640720b315SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 2065334f485dSMiklos Szeredi if (fc) { 2066d7133114SMiklos Szeredi spin_lock(&fc->lock); 20671e9a4ed9SMiklos Szeredi fc->connected = 0; 2068595afaf9SMiklos Szeredi fc->blocked = 0; 2069595afaf9SMiklos Szeredi end_queued_requests(fc); 2070357ccf2bSBryan Green end_polls(fc); 2071595afaf9SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 2072d7133114SMiklos Szeredi spin_unlock(&fc->lock); 2073bafa9654SMiklos Szeredi fuse_conn_put(fc); 2074385a17bfSJeff Dike } 2075f543f253SMiklos Szeredi 2076334f485dSMiklos Szeredi return 0; 2077334f485dSMiklos Szeredi } 207808cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release); 2079334f485dSMiklos Szeredi 2080385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on) 2081385a17bfSJeff Dike { 2082385a17bfSJeff Dike struct fuse_conn *fc = fuse_get_conn(file); 2083385a17bfSJeff Dike if (!fc) 2084a87046d8SMiklos Szeredi return -EPERM; 2085385a17bfSJeff Dike 2086385a17bfSJeff Dike /* No locking - fasync_helper does its own locking */ 2087385a17bfSJeff Dike return fasync_helper(fd, file, on, &fc->fasync); 2088385a17bfSJeff Dike } 2089385a17bfSJeff Dike 20904b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = { 2091334f485dSMiklos Szeredi .owner = THIS_MODULE, 2092334f485dSMiklos Szeredi .llseek = no_llseek, 2093ee0b3e67SBadari Pulavarty .read = do_sync_read, 2094ee0b3e67SBadari Pulavarty .aio_read = fuse_dev_read, 2095c3021629SMiklos Szeredi .splice_read = fuse_dev_splice_read, 2096ee0b3e67SBadari Pulavarty .write = do_sync_write, 2097ee0b3e67SBadari Pulavarty .aio_write = fuse_dev_write, 2098dd3bb14fSMiklos Szeredi .splice_write = fuse_dev_splice_write, 2099334f485dSMiklos Szeredi .poll = fuse_dev_poll, 2100334f485dSMiklos Szeredi .release = fuse_dev_release, 2101385a17bfSJeff Dike .fasync = fuse_dev_fasync, 2102334f485dSMiklos Szeredi }; 210308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations); 2104334f485dSMiklos Szeredi 2105334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = { 2106334f485dSMiklos Szeredi .minor = FUSE_MINOR, 2107334f485dSMiklos Szeredi .name = "fuse", 2108334f485dSMiklos Szeredi .fops = &fuse_dev_operations, 2109334f485dSMiklos Szeredi }; 2110334f485dSMiklos Szeredi 2111334f485dSMiklos Szeredi int __init fuse_dev_init(void) 2112334f485dSMiklos Szeredi { 2113334f485dSMiklos Szeredi int err = -ENOMEM; 2114334f485dSMiklos Szeredi fuse_req_cachep = kmem_cache_create("fuse_request", 2115334f485dSMiklos Szeredi sizeof(struct fuse_req), 211620c2df83SPaul Mundt 0, 0, NULL); 2117334f485dSMiklos Szeredi if (!fuse_req_cachep) 2118334f485dSMiklos Szeredi goto out; 2119334f485dSMiklos Szeredi 2120334f485dSMiklos Szeredi err = misc_register(&fuse_miscdevice); 2121334f485dSMiklos Szeredi if (err) 2122334f485dSMiklos Szeredi goto out_cache_clean; 2123334f485dSMiklos Szeredi 2124334f485dSMiklos Szeredi return 0; 2125334f485dSMiklos Szeredi 2126334f485dSMiklos Szeredi out_cache_clean: 2127334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2128334f485dSMiklos Szeredi out: 2129334f485dSMiklos Szeredi return err; 2130334f485dSMiklos Szeredi } 2131334f485dSMiklos Szeredi 2132334f485dSMiklos Szeredi void fuse_dev_cleanup(void) 2133334f485dSMiklos Szeredi { 2134334f485dSMiklos Szeredi misc_deregister(&fuse_miscdevice); 2135334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2136334f485dSMiklos Szeredi } 2137