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 378bfc016dSMiklos Szeredi static void fuse_request_init(struct fuse_req *req) 38334f485dSMiklos Szeredi { 39334f485dSMiklos Szeredi memset(req, 0, sizeof(*req)); 40334f485dSMiklos Szeredi INIT_LIST_HEAD(&req->list); 41a4d27e75SMiklos Szeredi INIT_LIST_HEAD(&req->intr_entry); 42334f485dSMiklos Szeredi init_waitqueue_head(&req->waitq); 43334f485dSMiklos Szeredi atomic_set(&req->count, 1); 44334f485dSMiklos Szeredi } 45334f485dSMiklos Szeredi 46334f485dSMiklos Szeredi struct fuse_req *fuse_request_alloc(void) 47334f485dSMiklos Szeredi { 48e94b1766SChristoph Lameter struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_KERNEL); 49334f485dSMiklos Szeredi if (req) 50334f485dSMiklos Szeredi fuse_request_init(req); 51334f485dSMiklos Szeredi return req; 52334f485dSMiklos Szeredi } 5308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_alloc); 54334f485dSMiklos Szeredi 553be5a52bSMiklos Szeredi struct fuse_req *fuse_request_alloc_nofs(void) 563be5a52bSMiklos Szeredi { 573be5a52bSMiklos Szeredi struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_NOFS); 583be5a52bSMiklos Szeredi if (req) 593be5a52bSMiklos Szeredi fuse_request_init(req); 603be5a52bSMiklos Szeredi return req; 613be5a52bSMiklos Szeredi } 623be5a52bSMiklos Szeredi 63334f485dSMiklos Szeredi void fuse_request_free(struct fuse_req *req) 64334f485dSMiklos Szeredi { 65334f485dSMiklos Szeredi kmem_cache_free(fuse_req_cachep, req); 66334f485dSMiklos Szeredi } 67334f485dSMiklos Szeredi 688bfc016dSMiklos Szeredi static void block_sigs(sigset_t *oldset) 69334f485dSMiklos Szeredi { 70334f485dSMiklos Szeredi sigset_t mask; 71334f485dSMiklos Szeredi 72334f485dSMiklos Szeredi siginitsetinv(&mask, sigmask(SIGKILL)); 73334f485dSMiklos Szeredi sigprocmask(SIG_BLOCK, &mask, oldset); 74334f485dSMiklos Szeredi } 75334f485dSMiklos Szeredi 768bfc016dSMiklos Szeredi static void restore_sigs(sigset_t *oldset) 77334f485dSMiklos Szeredi { 78334f485dSMiklos Szeredi sigprocmask(SIG_SETMASK, oldset, NULL); 79334f485dSMiklos Szeredi } 80334f485dSMiklos Szeredi 81334f485dSMiklos Szeredi static void __fuse_get_request(struct fuse_req *req) 82334f485dSMiklos Szeredi { 83334f485dSMiklos Szeredi atomic_inc(&req->count); 84334f485dSMiklos Szeredi } 85334f485dSMiklos Szeredi 86334f485dSMiklos Szeredi /* Must be called with > 1 refcount */ 87334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req) 88334f485dSMiklos Szeredi { 89334f485dSMiklos Szeredi BUG_ON(atomic_read(&req->count) < 2); 90334f485dSMiklos Szeredi atomic_dec(&req->count); 91334f485dSMiklos Szeredi } 92334f485dSMiklos Szeredi 9333649c91SMiklos Szeredi static void fuse_req_init_context(struct fuse_req *req) 9433649c91SMiklos Szeredi { 952186a71cSDavid Howells req->in.h.uid = current_fsuid(); 962186a71cSDavid Howells req->in.h.gid = current_fsgid(); 9733649c91SMiklos Szeredi req->in.h.pid = current->pid; 9833649c91SMiklos Szeredi } 9933649c91SMiklos Szeredi 100ce1d5a49SMiklos Szeredi struct fuse_req *fuse_get_req(struct fuse_conn *fc) 101334f485dSMiklos Szeredi { 10208a53cdcSMiklos Szeredi struct fuse_req *req; 10308a53cdcSMiklos Szeredi sigset_t oldset; 1049bc5dddaSMiklos Szeredi int intr; 10508a53cdcSMiklos Szeredi int err; 10608a53cdcSMiklos Szeredi 1079bc5dddaSMiklos Szeredi atomic_inc(&fc->num_waiting); 10808a53cdcSMiklos Szeredi block_sigs(&oldset); 1099bc5dddaSMiklos Szeredi intr = wait_event_interruptible(fc->blocked_waitq, !fc->blocked); 11008a53cdcSMiklos Szeredi restore_sigs(&oldset); 1119bc5dddaSMiklos Szeredi err = -EINTR; 1129bc5dddaSMiklos Szeredi if (intr) 1139bc5dddaSMiklos Szeredi goto out; 11408a53cdcSMiklos Szeredi 11551eb01e7SMiklos Szeredi err = -ENOTCONN; 11651eb01e7SMiklos Szeredi if (!fc->connected) 11751eb01e7SMiklos Szeredi goto out; 11851eb01e7SMiklos Szeredi 11908a53cdcSMiklos Szeredi req = fuse_request_alloc(); 1209bc5dddaSMiklos Szeredi err = -ENOMEM; 121ce1d5a49SMiklos Szeredi if (!req) 1229bc5dddaSMiklos Szeredi goto out; 123334f485dSMiklos Szeredi 12433649c91SMiklos Szeredi fuse_req_init_context(req); 1259bc5dddaSMiklos Szeredi req->waiting = 1; 126334f485dSMiklos Szeredi return req; 1279bc5dddaSMiklos Szeredi 1289bc5dddaSMiklos Szeredi out: 1299bc5dddaSMiklos Szeredi atomic_dec(&fc->num_waiting); 1309bc5dddaSMiklos Szeredi return ERR_PTR(err); 131334f485dSMiklos Szeredi } 13208cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_get_req); 133334f485dSMiklos Szeredi 13433649c91SMiklos Szeredi /* 13533649c91SMiklos Szeredi * Return request in fuse_file->reserved_req. However that may 13633649c91SMiklos Szeredi * currently be in use. If that is the case, wait for it to become 13733649c91SMiklos Szeredi * available. 13833649c91SMiklos Szeredi */ 13933649c91SMiklos Szeredi static struct fuse_req *get_reserved_req(struct fuse_conn *fc, 14033649c91SMiklos Szeredi struct file *file) 14133649c91SMiklos Szeredi { 14233649c91SMiklos Szeredi struct fuse_req *req = NULL; 14333649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 14433649c91SMiklos Szeredi 14533649c91SMiklos Szeredi do { 146de5e3decSMiklos Szeredi wait_event(fc->reserved_req_waitq, ff->reserved_req); 14733649c91SMiklos Szeredi spin_lock(&fc->lock); 14833649c91SMiklos Szeredi if (ff->reserved_req) { 14933649c91SMiklos Szeredi req = ff->reserved_req; 15033649c91SMiklos Szeredi ff->reserved_req = NULL; 15133649c91SMiklos Szeredi get_file(file); 15233649c91SMiklos Szeredi req->stolen_file = file; 15333649c91SMiklos Szeredi } 15433649c91SMiklos Szeredi spin_unlock(&fc->lock); 15533649c91SMiklos Szeredi } while (!req); 15633649c91SMiklos Szeredi 15733649c91SMiklos Szeredi return req; 15833649c91SMiklos Szeredi } 15933649c91SMiklos Szeredi 16033649c91SMiklos Szeredi /* 16133649c91SMiklos Szeredi * Put stolen request back into fuse_file->reserved_req 16233649c91SMiklos Szeredi */ 16333649c91SMiklos Szeredi static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req) 16433649c91SMiklos Szeredi { 16533649c91SMiklos Szeredi struct file *file = req->stolen_file; 16633649c91SMiklos Szeredi struct fuse_file *ff = file->private_data; 16733649c91SMiklos Szeredi 16833649c91SMiklos Szeredi spin_lock(&fc->lock); 16933649c91SMiklos Szeredi fuse_request_init(req); 17033649c91SMiklos Szeredi BUG_ON(ff->reserved_req); 17133649c91SMiklos Szeredi ff->reserved_req = req; 172de5e3decSMiklos Szeredi wake_up_all(&fc->reserved_req_waitq); 17333649c91SMiklos Szeredi spin_unlock(&fc->lock); 17433649c91SMiklos Szeredi fput(file); 17533649c91SMiklos Szeredi } 17633649c91SMiklos Szeredi 17733649c91SMiklos Szeredi /* 17833649c91SMiklos Szeredi * Gets a requests for a file operation, always succeeds 17933649c91SMiklos Szeredi * 18033649c91SMiklos Szeredi * This is used for sending the FLUSH request, which must get to 18133649c91SMiklos Szeredi * userspace, due to POSIX locks which may need to be unlocked. 18233649c91SMiklos Szeredi * 18333649c91SMiklos Szeredi * If allocation fails due to OOM, use the reserved request in 18433649c91SMiklos Szeredi * fuse_file. 18533649c91SMiklos Szeredi * 18633649c91SMiklos Szeredi * This is very unlikely to deadlock accidentally, since the 18733649c91SMiklos Szeredi * filesystem should not have it's own file open. If deadlock is 18833649c91SMiklos Szeredi * intentional, it can still be broken by "aborting" the filesystem. 18933649c91SMiklos Szeredi */ 19033649c91SMiklos Szeredi struct fuse_req *fuse_get_req_nofail(struct fuse_conn *fc, struct file *file) 19133649c91SMiklos Szeredi { 19233649c91SMiklos Szeredi struct fuse_req *req; 19333649c91SMiklos Szeredi 19433649c91SMiklos Szeredi atomic_inc(&fc->num_waiting); 19533649c91SMiklos Szeredi wait_event(fc->blocked_waitq, !fc->blocked); 19633649c91SMiklos Szeredi req = fuse_request_alloc(); 19733649c91SMiklos Szeredi if (!req) 19833649c91SMiklos Szeredi req = get_reserved_req(fc, file); 19933649c91SMiklos Szeredi 20033649c91SMiklos Szeredi fuse_req_init_context(req); 20133649c91SMiklos Szeredi req->waiting = 1; 20233649c91SMiklos Szeredi return req; 20333649c91SMiklos Szeredi } 20433649c91SMiklos Szeredi 205334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) 206334f485dSMiklos Szeredi { 2077128ec2aSMiklos Szeredi if (atomic_dec_and_test(&req->count)) { 2089bc5dddaSMiklos Szeredi if (req->waiting) 209ce1d5a49SMiklos Szeredi atomic_dec(&fc->num_waiting); 21033649c91SMiklos Szeredi 21133649c91SMiklos Szeredi if (req->stolen_file) 21233649c91SMiklos Szeredi put_reserved_req(fc, req); 21333649c91SMiklos Szeredi else 214ce1d5a49SMiklos Szeredi fuse_request_free(req); 2157128ec2aSMiklos Szeredi } 2167128ec2aSMiklos Szeredi } 21708cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_put_request); 2187128ec2aSMiklos Szeredi 219d12def1bSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args) 220d12def1bSMiklos Szeredi { 221d12def1bSMiklos Szeredi unsigned nbytes = 0; 222d12def1bSMiklos Szeredi unsigned i; 223d12def1bSMiklos Szeredi 224d12def1bSMiklos Szeredi for (i = 0; i < numargs; i++) 225d12def1bSMiklos Szeredi nbytes += args[i].size; 226d12def1bSMiklos Szeredi 227d12def1bSMiklos Szeredi return nbytes; 228d12def1bSMiklos Szeredi } 229d12def1bSMiklos Szeredi 230d12def1bSMiklos Szeredi static u64 fuse_get_unique(struct fuse_conn *fc) 231d12def1bSMiklos Szeredi { 232d12def1bSMiklos Szeredi fc->reqctr++; 233d12def1bSMiklos Szeredi /* zero is special */ 234d12def1bSMiklos Szeredi if (fc->reqctr == 0) 235d12def1bSMiklos Szeredi fc->reqctr = 1; 236d12def1bSMiklos Szeredi 237d12def1bSMiklos Szeredi return fc->reqctr; 238d12def1bSMiklos Szeredi } 239d12def1bSMiklos Szeredi 240d12def1bSMiklos Szeredi static void queue_request(struct fuse_conn *fc, struct fuse_req *req) 241d12def1bSMiklos Szeredi { 242d12def1bSMiklos Szeredi req->in.h.len = sizeof(struct fuse_in_header) + 243d12def1bSMiklos Szeredi len_args(req->in.numargs, (struct fuse_arg *) req->in.args); 244d12def1bSMiklos Szeredi list_add_tail(&req->list, &fc->pending); 245d12def1bSMiklos Szeredi req->state = FUSE_REQ_PENDING; 246d12def1bSMiklos Szeredi if (!req->waiting) { 247d12def1bSMiklos Szeredi req->waiting = 1; 248d12def1bSMiklos Szeredi atomic_inc(&fc->num_waiting); 249d12def1bSMiklos Szeredi } 250d12def1bSMiklos Szeredi wake_up(&fc->waitq); 251d12def1bSMiklos Szeredi kill_fasync(&fc->fasync, SIGIO, POLL_IN); 252d12def1bSMiklos Szeredi } 253d12def1bSMiklos Szeredi 25407e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, 25507e77dcaSMiklos Szeredi u64 nodeid, u64 nlookup) 25607e77dcaSMiklos Szeredi { 25702c048b9SMiklos Szeredi forget->forget_one.nodeid = nodeid; 25802c048b9SMiklos Szeredi forget->forget_one.nlookup = nlookup; 25907e77dcaSMiklos Szeredi 26007e77dcaSMiklos Szeredi spin_lock(&fc->lock); 26107e77dcaSMiklos Szeredi fc->forget_list_tail->next = forget; 26207e77dcaSMiklos Szeredi fc->forget_list_tail = forget; 26307e77dcaSMiklos Szeredi wake_up(&fc->waitq); 26407e77dcaSMiklos Szeredi kill_fasync(&fc->fasync, SIGIO, POLL_IN); 26507e77dcaSMiklos Szeredi spin_unlock(&fc->lock); 26607e77dcaSMiklos Szeredi } 26707e77dcaSMiklos Szeredi 268d12def1bSMiklos Szeredi static void flush_bg_queue(struct fuse_conn *fc) 269d12def1bSMiklos Szeredi { 2707a6d3c8bSCsaba Henk while (fc->active_background < fc->max_background && 271d12def1bSMiklos Szeredi !list_empty(&fc->bg_queue)) { 272d12def1bSMiklos Szeredi struct fuse_req *req; 273d12def1bSMiklos Szeredi 274d12def1bSMiklos Szeredi req = list_entry(fc->bg_queue.next, struct fuse_req, list); 275d12def1bSMiklos Szeredi list_del(&req->list); 276d12def1bSMiklos Szeredi fc->active_background++; 2772d45ba38SMiklos Szeredi req->in.h.unique = fuse_get_unique(fc); 278d12def1bSMiklos Szeredi queue_request(fc, req); 279d12def1bSMiklos Szeredi } 280d12def1bSMiklos Szeredi } 281d12def1bSMiklos Szeredi 2826dbbcb12SMiklos Szeredi /* 283334f485dSMiklos Szeredi * This function is called when a request is finished. Either a reply 284f9a2842eSMiklos Szeredi * has arrived or it was aborted (and not yet sent) or some error 285f43b155aSMiklos Szeredi * occurred during communication with userspace, or the device file 28651eb01e7SMiklos Szeredi * was closed. The requester thread is woken up (if still waiting), 28751eb01e7SMiklos Szeredi * the 'end' callback is called if given, else the reference to the 28851eb01e7SMiklos Szeredi * request is released 2897128ec2aSMiklos Szeredi * 290d7133114SMiklos Szeredi * Called with fc->lock, unlocks it 291334f485dSMiklos Szeredi */ 292334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req) 293b9ca67b2SMiklos Szeredi __releases(fc->lock) 294334f485dSMiklos Szeredi { 2957128ec2aSMiklos Szeredi void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; 2967128ec2aSMiklos Szeredi req->end = NULL; 29751eb01e7SMiklos Szeredi list_del(&req->list); 298a4d27e75SMiklos Szeredi list_del(&req->intr_entry); 29951eb01e7SMiklos Szeredi req->state = FUSE_REQ_FINISHED; 30051eb01e7SMiklos Szeredi if (req->background) { 3017a6d3c8bSCsaba Henk if (fc->num_background == fc->max_background) { 30251eb01e7SMiklos Szeredi fc->blocked = 0; 30351eb01e7SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 30451eb01e7SMiklos Szeredi } 3057a6d3c8bSCsaba Henk if (fc->num_background == fc->congestion_threshold && 306a325f9b9STejun Heo fc->connected && fc->bdi_initialized) { 3078aa7e847SJens Axboe clear_bdi_congested(&fc->bdi, BLK_RW_SYNC); 3088aa7e847SJens Axboe clear_bdi_congested(&fc->bdi, BLK_RW_ASYNC); 309f92b99b9SMiklos Szeredi } 31051eb01e7SMiklos Szeredi fc->num_background--; 311d12def1bSMiklos Szeredi fc->active_background--; 312d12def1bSMiklos Szeredi flush_bg_queue(fc); 31351eb01e7SMiklos Szeredi } 314d7133114SMiklos Szeredi spin_unlock(&fc->lock); 31551eb01e7SMiklos Szeredi wake_up(&req->waitq); 31664c6d8edSMiklos Szeredi if (end) 31764c6d8edSMiklos Szeredi end(fc, req); 318f43b155aSMiklos Szeredi fuse_put_request(fc, req); 319334f485dSMiklos Szeredi } 320334f485dSMiklos Szeredi 321a4d27e75SMiklos Szeredi static void wait_answer_interruptible(struct fuse_conn *fc, 322a4d27e75SMiklos Szeredi struct fuse_req *req) 323b9ca67b2SMiklos Szeredi __releases(fc->lock) 324b9ca67b2SMiklos Szeredi __acquires(fc->lock) 325a4d27e75SMiklos Szeredi { 326a4d27e75SMiklos Szeredi if (signal_pending(current)) 327a4d27e75SMiklos Szeredi return; 328a4d27e75SMiklos Szeredi 329a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 330a4d27e75SMiklos Szeredi wait_event_interruptible(req->waitq, req->state == FUSE_REQ_FINISHED); 331a4d27e75SMiklos Szeredi spin_lock(&fc->lock); 332a4d27e75SMiklos Szeredi } 333a4d27e75SMiklos Szeredi 334a4d27e75SMiklos Szeredi static void queue_interrupt(struct fuse_conn *fc, struct fuse_req *req) 335a4d27e75SMiklos Szeredi { 336a4d27e75SMiklos Szeredi list_add_tail(&req->intr_entry, &fc->interrupts); 337a4d27e75SMiklos Szeredi wake_up(&fc->waitq); 338a4d27e75SMiklos Szeredi kill_fasync(&fc->fasync, SIGIO, POLL_IN); 339a4d27e75SMiklos Szeredi } 340a4d27e75SMiklos Szeredi 3417c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) 342b9ca67b2SMiklos Szeredi __releases(fc->lock) 343b9ca67b2SMiklos Szeredi __acquires(fc->lock) 344334f485dSMiklos Szeredi { 345a4d27e75SMiklos Szeredi if (!fc->no_interrupt) { 346a4d27e75SMiklos Szeredi /* Any signal may interrupt this */ 347a4d27e75SMiklos Szeredi wait_answer_interruptible(fc, req); 348334f485dSMiklos Szeredi 349a4d27e75SMiklos Szeredi if (req->aborted) 350a4d27e75SMiklos Szeredi goto aborted; 351a4d27e75SMiklos Szeredi if (req->state == FUSE_REQ_FINISHED) 352334f485dSMiklos Szeredi return; 353334f485dSMiklos Szeredi 354a4d27e75SMiklos Szeredi req->interrupted = 1; 355a4d27e75SMiklos Szeredi if (req->state == FUSE_REQ_SENT) 356a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 357a4d27e75SMiklos Szeredi } 358a4d27e75SMiklos Szeredi 359a131de0aSMiklos Szeredi if (!req->force) { 360a4d27e75SMiklos Szeredi sigset_t oldset; 361a4d27e75SMiklos Szeredi 362a4d27e75SMiklos Szeredi /* Only fatal signals may interrupt this */ 363a4d27e75SMiklos Szeredi block_sigs(&oldset); 364a4d27e75SMiklos Szeredi wait_answer_interruptible(fc, req); 365a4d27e75SMiklos Szeredi restore_sigs(&oldset); 366a4d27e75SMiklos Szeredi 367a4d27e75SMiklos Szeredi if (req->aborted) 368a4d27e75SMiklos Szeredi goto aborted; 369a4d27e75SMiklos Szeredi if (req->state == FUSE_REQ_FINISHED) 370a4d27e75SMiklos Szeredi return; 371a4d27e75SMiklos Szeredi 372a131de0aSMiklos Szeredi /* Request is not yet in userspace, bail out */ 373a131de0aSMiklos Szeredi if (req->state == FUSE_REQ_PENDING) { 374a131de0aSMiklos Szeredi list_del(&req->list); 375a131de0aSMiklos Szeredi __fuse_put_request(req); 376334f485dSMiklos Szeredi req->out.h.error = -EINTR; 377a131de0aSMiklos Szeredi return; 378a131de0aSMiklos Szeredi } 379a131de0aSMiklos Szeredi } 380a131de0aSMiklos Szeredi 381a131de0aSMiklos Szeredi /* 382a131de0aSMiklos Szeredi * Either request is already in userspace, or it was forced. 383a131de0aSMiklos Szeredi * Wait it out. 384a131de0aSMiklos Szeredi */ 385a131de0aSMiklos Szeredi spin_unlock(&fc->lock); 386a131de0aSMiklos Szeredi wait_event(req->waitq, req->state == FUSE_REQ_FINISHED); 387a131de0aSMiklos Szeredi spin_lock(&fc->lock); 388a131de0aSMiklos Szeredi 389a131de0aSMiklos Szeredi if (!req->aborted) 390a131de0aSMiklos Szeredi return; 391a4d27e75SMiklos Szeredi 392a4d27e75SMiklos Szeredi aborted: 393a131de0aSMiklos Szeredi BUG_ON(req->state != FUSE_REQ_FINISHED); 394334f485dSMiklos Szeredi if (req->locked) { 395334f485dSMiklos Szeredi /* This is uninterruptible sleep, because data is 396334f485dSMiklos Szeredi being copied to/from the buffers of req. During 397334f485dSMiklos Szeredi locked state, there mustn't be any filesystem 398334f485dSMiklos Szeredi operation (e.g. page fault), since that could lead 399334f485dSMiklos Szeredi to deadlock */ 400d7133114SMiklos Szeredi spin_unlock(&fc->lock); 401334f485dSMiklos Szeredi wait_event(req->waitq, !req->locked); 402d7133114SMiklos Szeredi spin_lock(&fc->lock); 403334f485dSMiklos Szeredi } 404334f485dSMiklos Szeredi } 405334f485dSMiklos Szeredi 406b93f858aSTejun Heo void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) 407334f485dSMiklos Szeredi { 408334f485dSMiklos Szeredi req->isreply = 1; 409d7133114SMiklos Szeredi spin_lock(&fc->lock); 4101e9a4ed9SMiklos Szeredi if (!fc->connected) 411334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 412334f485dSMiklos Szeredi else if (fc->conn_error) 413334f485dSMiklos Szeredi req->out.h.error = -ECONNREFUSED; 414334f485dSMiklos Szeredi else { 4152d45ba38SMiklos Szeredi req->in.h.unique = fuse_get_unique(fc); 416334f485dSMiklos Szeredi queue_request(fc, req); 417334f485dSMiklos Szeredi /* acquire extra reference, since request is still needed 418334f485dSMiklos Szeredi after request_end() */ 419334f485dSMiklos Szeredi __fuse_get_request(req); 420334f485dSMiklos Szeredi 4217c352bdfSMiklos Szeredi request_wait_answer(fc, req); 422334f485dSMiklos Szeredi } 423d7133114SMiklos Szeredi spin_unlock(&fc->lock); 424334f485dSMiklos Szeredi } 42508cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send); 426334f485dSMiklos Szeredi 427b93f858aSTejun Heo static void fuse_request_send_nowait_locked(struct fuse_conn *fc, 428d12def1bSMiklos Szeredi struct fuse_req *req) 429334f485dSMiklos Szeredi { 43051eb01e7SMiklos Szeredi req->background = 1; 43151eb01e7SMiklos Szeredi fc->num_background++; 4327a6d3c8bSCsaba Henk if (fc->num_background == fc->max_background) 43351eb01e7SMiklos Szeredi fc->blocked = 1; 4347a6d3c8bSCsaba Henk if (fc->num_background == fc->congestion_threshold && 435a325f9b9STejun Heo fc->bdi_initialized) { 4368aa7e847SJens Axboe set_bdi_congested(&fc->bdi, BLK_RW_SYNC); 4378aa7e847SJens Axboe set_bdi_congested(&fc->bdi, BLK_RW_ASYNC); 438f92b99b9SMiklos Szeredi } 439d12def1bSMiklos Szeredi list_add_tail(&req->list, &fc->bg_queue); 440d12def1bSMiklos Szeredi flush_bg_queue(fc); 441d12def1bSMiklos Szeredi } 44251eb01e7SMiklos Szeredi 443b93f858aSTejun Heo static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) 444d12def1bSMiklos Szeredi { 445d12def1bSMiklos Szeredi spin_lock(&fc->lock); 446d12def1bSMiklos Szeredi if (fc->connected) { 447b93f858aSTejun Heo fuse_request_send_nowait_locked(fc, req); 448d7133114SMiklos Szeredi spin_unlock(&fc->lock); 449334f485dSMiklos Szeredi } else { 450334f485dSMiklos Szeredi req->out.h.error = -ENOTCONN; 451334f485dSMiklos Szeredi request_end(fc, req); 452334f485dSMiklos Szeredi } 453334f485dSMiklos Szeredi } 454334f485dSMiklos Szeredi 455b93f858aSTejun Heo void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) 456334f485dSMiklos Szeredi { 457334f485dSMiklos Szeredi req->isreply = 1; 458b93f858aSTejun Heo fuse_request_send_nowait(fc, req); 459334f485dSMiklos Szeredi } 46008cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send_background); 461334f485dSMiklos Szeredi 4622d45ba38SMiklos Szeredi static int fuse_request_send_notify_reply(struct fuse_conn *fc, 4632d45ba38SMiklos Szeredi struct fuse_req *req, u64 unique) 4642d45ba38SMiklos Szeredi { 4652d45ba38SMiklos Szeredi int err = -ENODEV; 4662d45ba38SMiklos Szeredi 4672d45ba38SMiklos Szeredi req->isreply = 0; 4682d45ba38SMiklos Szeredi req->in.h.unique = unique; 4692d45ba38SMiklos Szeredi spin_lock(&fc->lock); 4702d45ba38SMiklos Szeredi if (fc->connected) { 4712d45ba38SMiklos Szeredi queue_request(fc, req); 4722d45ba38SMiklos Szeredi err = 0; 4732d45ba38SMiklos Szeredi } 4742d45ba38SMiklos Szeredi spin_unlock(&fc->lock); 4752d45ba38SMiklos Szeredi 4762d45ba38SMiklos Szeredi return err; 4772d45ba38SMiklos Szeredi } 4782d45ba38SMiklos Szeredi 479334f485dSMiklos Szeredi /* 4803be5a52bSMiklos Szeredi * Called under fc->lock 4813be5a52bSMiklos Szeredi * 4823be5a52bSMiklos Szeredi * fc->connected must have been checked previously 4833be5a52bSMiklos Szeredi */ 484b93f858aSTejun Heo void fuse_request_send_background_locked(struct fuse_conn *fc, 485b93f858aSTejun Heo struct fuse_req *req) 4863be5a52bSMiklos Szeredi { 4873be5a52bSMiklos Szeredi req->isreply = 1; 488b93f858aSTejun Heo fuse_request_send_nowait_locked(fc, req); 4893be5a52bSMiklos Szeredi } 4903be5a52bSMiklos Szeredi 4913be5a52bSMiklos Szeredi /* 492334f485dSMiklos Szeredi * Lock the request. Up to the next unlock_request() there mustn't be 493334f485dSMiklos Szeredi * anything that could cause a page-fault. If the request was already 494f9a2842eSMiklos Szeredi * aborted bail out. 495334f485dSMiklos Szeredi */ 496d7133114SMiklos Szeredi static int lock_request(struct fuse_conn *fc, struct fuse_req *req) 497334f485dSMiklos Szeredi { 498334f485dSMiklos Szeredi int err = 0; 499334f485dSMiklos Szeredi if (req) { 500d7133114SMiklos Szeredi spin_lock(&fc->lock); 501f9a2842eSMiklos Szeredi if (req->aborted) 502334f485dSMiklos Szeredi err = -ENOENT; 503334f485dSMiklos Szeredi else 504334f485dSMiklos Szeredi req->locked = 1; 505d7133114SMiklos Szeredi spin_unlock(&fc->lock); 506334f485dSMiklos Szeredi } 507334f485dSMiklos Szeredi return err; 508334f485dSMiklos Szeredi } 509334f485dSMiklos Szeredi 510334f485dSMiklos Szeredi /* 511f9a2842eSMiklos Szeredi * Unlock request. If it was aborted during being locked, the 512334f485dSMiklos Szeredi * requester thread is currently waiting for it to be unlocked, so 513334f485dSMiklos Szeredi * wake it up. 514334f485dSMiklos Szeredi */ 515d7133114SMiklos Szeredi static void unlock_request(struct fuse_conn *fc, struct fuse_req *req) 516334f485dSMiklos Szeredi { 517334f485dSMiklos Szeredi if (req) { 518d7133114SMiklos Szeredi spin_lock(&fc->lock); 519334f485dSMiklos Szeredi req->locked = 0; 520f9a2842eSMiklos Szeredi if (req->aborted) 521334f485dSMiklos Szeredi wake_up(&req->waitq); 522d7133114SMiklos Szeredi spin_unlock(&fc->lock); 523334f485dSMiklos Szeredi } 524334f485dSMiklos Szeredi } 525334f485dSMiklos Szeredi 526334f485dSMiklos Szeredi struct fuse_copy_state { 527d7133114SMiklos Szeredi struct fuse_conn *fc; 528334f485dSMiklos Szeredi int write; 529334f485dSMiklos Szeredi struct fuse_req *req; 530334f485dSMiklos Szeredi const struct iovec *iov; 531dd3bb14fSMiklos Szeredi struct pipe_buffer *pipebufs; 532dd3bb14fSMiklos Szeredi struct pipe_buffer *currbuf; 533dd3bb14fSMiklos Szeredi struct pipe_inode_info *pipe; 534334f485dSMiklos Szeredi unsigned long nr_segs; 535334f485dSMiklos Szeredi unsigned long seglen; 536334f485dSMiklos Szeredi unsigned long addr; 537334f485dSMiklos Szeredi struct page *pg; 538334f485dSMiklos Szeredi void *mapaddr; 539334f485dSMiklos Szeredi void *buf; 540334f485dSMiklos Szeredi unsigned len; 541ce534fb0SMiklos Szeredi unsigned move_pages:1; 542334f485dSMiklos Szeredi }; 543334f485dSMiklos Szeredi 544d7133114SMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc, 545c3021629SMiklos Szeredi int write, 546d7133114SMiklos Szeredi const struct iovec *iov, unsigned long nr_segs) 547334f485dSMiklos Szeredi { 548334f485dSMiklos Szeredi memset(cs, 0, sizeof(*cs)); 549d7133114SMiklos Szeredi cs->fc = fc; 550334f485dSMiklos Szeredi cs->write = write; 551334f485dSMiklos Szeredi cs->iov = iov; 552334f485dSMiklos Szeredi cs->nr_segs = nr_segs; 553334f485dSMiklos Szeredi } 554334f485dSMiklos Szeredi 555334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */ 5568bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs) 557334f485dSMiklos Szeredi { 558dd3bb14fSMiklos Szeredi if (cs->currbuf) { 559dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->currbuf; 560dd3bb14fSMiklos Szeredi 561c3021629SMiklos Szeredi if (!cs->write) { 562dd3bb14fSMiklos Szeredi buf->ops->unmap(cs->pipe, buf, cs->mapaddr); 563c3021629SMiklos Szeredi } else { 5647909b1c6SMiklos Szeredi kunmap(buf->page); 565c3021629SMiklos Szeredi buf->len = PAGE_SIZE - cs->len; 566c3021629SMiklos Szeredi } 567dd3bb14fSMiklos Szeredi cs->currbuf = NULL; 568dd3bb14fSMiklos Szeredi cs->mapaddr = NULL; 569dd3bb14fSMiklos Szeredi } else if (cs->mapaddr) { 5707909b1c6SMiklos Szeredi kunmap(cs->pg); 571334f485dSMiklos Szeredi if (cs->write) { 572334f485dSMiklos Szeredi flush_dcache_page(cs->pg); 573334f485dSMiklos Szeredi set_page_dirty_lock(cs->pg); 574334f485dSMiklos Szeredi } 575334f485dSMiklos Szeredi put_page(cs->pg); 576334f485dSMiklos Szeredi cs->mapaddr = NULL; 577334f485dSMiklos Szeredi } 578334f485dSMiklos Szeredi } 579334f485dSMiklos Szeredi 580334f485dSMiklos Szeredi /* 581334f485dSMiklos Szeredi * Get another pagefull of userspace buffer, and map it to kernel 582334f485dSMiklos Szeredi * address space, and lock request 583334f485dSMiklos Szeredi */ 584334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs) 585334f485dSMiklos Szeredi { 586334f485dSMiklos Szeredi unsigned long offset; 587334f485dSMiklos Szeredi int err; 588334f485dSMiklos Szeredi 589d7133114SMiklos Szeredi unlock_request(cs->fc, cs->req); 590334f485dSMiklos Szeredi fuse_copy_finish(cs); 591dd3bb14fSMiklos Szeredi if (cs->pipebufs) { 592dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 593dd3bb14fSMiklos Szeredi 594c3021629SMiklos Szeredi if (!cs->write) { 595dd3bb14fSMiklos Szeredi err = buf->ops->confirm(cs->pipe, buf); 596dd3bb14fSMiklos Szeredi if (err) 597dd3bb14fSMiklos Szeredi return err; 598dd3bb14fSMiklos Szeredi 599dd3bb14fSMiklos Szeredi BUG_ON(!cs->nr_segs); 600dd3bb14fSMiklos Szeredi cs->currbuf = buf; 6017909b1c6SMiklos Szeredi cs->mapaddr = buf->ops->map(cs->pipe, buf, 0); 602dd3bb14fSMiklos Szeredi cs->len = buf->len; 603dd3bb14fSMiklos Szeredi cs->buf = cs->mapaddr + buf->offset; 604dd3bb14fSMiklos Szeredi cs->pipebufs++; 605dd3bb14fSMiklos Szeredi cs->nr_segs--; 606dd3bb14fSMiklos Szeredi } else { 607c3021629SMiklos Szeredi struct page *page; 608c3021629SMiklos Szeredi 609c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 610c3021629SMiklos Szeredi return -EIO; 611c3021629SMiklos Szeredi 612c3021629SMiklos Szeredi page = alloc_page(GFP_HIGHUSER); 613c3021629SMiklos Szeredi if (!page) 614c3021629SMiklos Szeredi return -ENOMEM; 615c3021629SMiklos Szeredi 616c3021629SMiklos Szeredi buf->page = page; 617c3021629SMiklos Szeredi buf->offset = 0; 618c3021629SMiklos Szeredi buf->len = 0; 619c3021629SMiklos Szeredi 620c3021629SMiklos Szeredi cs->currbuf = buf; 6217909b1c6SMiklos Szeredi cs->mapaddr = kmap(page); 622c3021629SMiklos Szeredi cs->buf = cs->mapaddr; 623c3021629SMiklos Szeredi cs->len = PAGE_SIZE; 624c3021629SMiklos Szeredi cs->pipebufs++; 625c3021629SMiklos Szeredi cs->nr_segs++; 626c3021629SMiklos Szeredi } 627c3021629SMiklos Szeredi } else { 628334f485dSMiklos Szeredi if (!cs->seglen) { 629334f485dSMiklos Szeredi BUG_ON(!cs->nr_segs); 630334f485dSMiklos Szeredi cs->seglen = cs->iov[0].iov_len; 631334f485dSMiklos Szeredi cs->addr = (unsigned long) cs->iov[0].iov_base; 632334f485dSMiklos Szeredi cs->iov++; 633334f485dSMiklos Szeredi cs->nr_segs--; 634334f485dSMiklos Szeredi } 6351bf94ca7SMiklos Szeredi err = get_user_pages_fast(cs->addr, 1, cs->write, &cs->pg); 636334f485dSMiklos Szeredi if (err < 0) 637334f485dSMiklos Szeredi return err; 638334f485dSMiklos Szeredi BUG_ON(err != 1); 639334f485dSMiklos Szeredi offset = cs->addr % PAGE_SIZE; 6407909b1c6SMiklos Szeredi cs->mapaddr = kmap(cs->pg); 641334f485dSMiklos Szeredi cs->buf = cs->mapaddr + offset; 642334f485dSMiklos Szeredi cs->len = min(PAGE_SIZE - offset, cs->seglen); 643334f485dSMiklos Szeredi cs->seglen -= cs->len; 644334f485dSMiklos Szeredi cs->addr += cs->len; 645dd3bb14fSMiklos Szeredi } 646334f485dSMiklos Szeredi 647d7133114SMiklos Szeredi return lock_request(cs->fc, cs->req); 648334f485dSMiklos Szeredi } 649334f485dSMiklos Szeredi 650334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */ 6518bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size) 652334f485dSMiklos Szeredi { 653334f485dSMiklos Szeredi unsigned ncpy = min(*size, cs->len); 654334f485dSMiklos Szeredi if (val) { 655334f485dSMiklos Szeredi if (cs->write) 656334f485dSMiklos Szeredi memcpy(cs->buf, *val, ncpy); 657334f485dSMiklos Szeredi else 658334f485dSMiklos Szeredi memcpy(*val, cs->buf, ncpy); 659334f485dSMiklos Szeredi *val += ncpy; 660334f485dSMiklos Szeredi } 661334f485dSMiklos Szeredi *size -= ncpy; 662334f485dSMiklos Szeredi cs->len -= ncpy; 663334f485dSMiklos Szeredi cs->buf += ncpy; 664334f485dSMiklos Szeredi return ncpy; 665334f485dSMiklos Szeredi } 666334f485dSMiklos Szeredi 667ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page) 668ce534fb0SMiklos Szeredi { 669ce534fb0SMiklos Szeredi if (page_mapcount(page) || 670ce534fb0SMiklos Szeredi page->mapping != NULL || 671ce534fb0SMiklos Szeredi page_count(page) != 1 || 672ce534fb0SMiklos Szeredi (page->flags & PAGE_FLAGS_CHECK_AT_PREP & 673ce534fb0SMiklos Szeredi ~(1 << PG_locked | 674ce534fb0SMiklos Szeredi 1 << PG_referenced | 675ce534fb0SMiklos Szeredi 1 << PG_uptodate | 676ce534fb0SMiklos Szeredi 1 << PG_lru | 677ce534fb0SMiklos Szeredi 1 << PG_active | 678ce534fb0SMiklos Szeredi 1 << PG_reclaim))) { 679ce534fb0SMiklos Szeredi printk(KERN_WARNING "fuse: trying to steal weird page\n"); 680ce534fb0SMiklos 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); 681ce534fb0SMiklos Szeredi return 1; 682ce534fb0SMiklos Szeredi } 683ce534fb0SMiklos Szeredi return 0; 684ce534fb0SMiklos Szeredi } 685ce534fb0SMiklos Szeredi 686ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep) 687ce534fb0SMiklos Szeredi { 688ce534fb0SMiklos Szeredi int err; 689ce534fb0SMiklos Szeredi struct page *oldpage = *pagep; 690ce534fb0SMiklos Szeredi struct page *newpage; 691ce534fb0SMiklos Szeredi struct pipe_buffer *buf = cs->pipebufs; 692ce534fb0SMiklos Szeredi struct address_space *mapping; 693ce534fb0SMiklos Szeredi pgoff_t index; 694ce534fb0SMiklos Szeredi 695ce534fb0SMiklos Szeredi unlock_request(cs->fc, cs->req); 696ce534fb0SMiklos Szeredi fuse_copy_finish(cs); 697ce534fb0SMiklos Szeredi 698ce534fb0SMiklos Szeredi err = buf->ops->confirm(cs->pipe, buf); 699ce534fb0SMiklos Szeredi if (err) 700ce534fb0SMiklos Szeredi return err; 701ce534fb0SMiklos Szeredi 702ce534fb0SMiklos Szeredi BUG_ON(!cs->nr_segs); 703ce534fb0SMiklos Szeredi cs->currbuf = buf; 704ce534fb0SMiklos Szeredi cs->len = buf->len; 705ce534fb0SMiklos Szeredi cs->pipebufs++; 706ce534fb0SMiklos Szeredi cs->nr_segs--; 707ce534fb0SMiklos Szeredi 708ce534fb0SMiklos Szeredi if (cs->len != PAGE_SIZE) 709ce534fb0SMiklos Szeredi goto out_fallback; 710ce534fb0SMiklos Szeredi 711ce534fb0SMiklos Szeredi if (buf->ops->steal(cs->pipe, buf) != 0) 712ce534fb0SMiklos Szeredi goto out_fallback; 713ce534fb0SMiklos Szeredi 714ce534fb0SMiklos Szeredi newpage = buf->page; 715ce534fb0SMiklos Szeredi 716ce534fb0SMiklos Szeredi if (WARN_ON(!PageUptodate(newpage))) 717ce534fb0SMiklos Szeredi return -EIO; 718ce534fb0SMiklos Szeredi 719ce534fb0SMiklos Szeredi ClearPageMappedToDisk(newpage); 720ce534fb0SMiklos Szeredi 721ce534fb0SMiklos Szeredi if (fuse_check_page(newpage) != 0) 722ce534fb0SMiklos Szeredi goto out_fallback_unlock; 723ce534fb0SMiklos Szeredi 724ce534fb0SMiklos Szeredi mapping = oldpage->mapping; 725ce534fb0SMiklos Szeredi index = oldpage->index; 726ce534fb0SMiklos Szeredi 727ce534fb0SMiklos Szeredi /* 728ce534fb0SMiklos Szeredi * This is a new and locked page, it shouldn't be mapped or 729ce534fb0SMiklos Szeredi * have any special flags on it 730ce534fb0SMiklos Szeredi */ 731ce534fb0SMiklos Szeredi if (WARN_ON(page_mapped(oldpage))) 732ce534fb0SMiklos Szeredi goto out_fallback_unlock; 733ce534fb0SMiklos Szeredi if (WARN_ON(page_has_private(oldpage))) 734ce534fb0SMiklos Szeredi goto out_fallback_unlock; 735ce534fb0SMiklos Szeredi if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage))) 736ce534fb0SMiklos Szeredi goto out_fallback_unlock; 737ce534fb0SMiklos Szeredi if (WARN_ON(PageMlocked(oldpage))) 738ce534fb0SMiklos Szeredi goto out_fallback_unlock; 739ce534fb0SMiklos Szeredi 740ce534fb0SMiklos Szeredi remove_from_page_cache(oldpage); 741ce534fb0SMiklos Szeredi page_cache_release(oldpage); 742ce534fb0SMiklos Szeredi 743ce534fb0SMiklos Szeredi err = add_to_page_cache_locked(newpage, mapping, index, GFP_KERNEL); 744ce534fb0SMiklos Szeredi if (err) { 745ce534fb0SMiklos Szeredi printk(KERN_WARNING "fuse_try_move_page: failed to add page"); 746ce534fb0SMiklos Szeredi goto out_fallback_unlock; 747ce534fb0SMiklos Szeredi } 748ce534fb0SMiklos Szeredi page_cache_get(newpage); 749ce534fb0SMiklos Szeredi 750ce534fb0SMiklos Szeredi if (!(buf->flags & PIPE_BUF_FLAG_LRU)) 751ce534fb0SMiklos Szeredi lru_cache_add_file(newpage); 752ce534fb0SMiklos Szeredi 753ce534fb0SMiklos Szeredi err = 0; 754ce534fb0SMiklos Szeredi spin_lock(&cs->fc->lock); 755ce534fb0SMiklos Szeredi if (cs->req->aborted) 756ce534fb0SMiklos Szeredi err = -ENOENT; 757ce534fb0SMiklos Szeredi else 758ce534fb0SMiklos Szeredi *pagep = newpage; 759ce534fb0SMiklos Szeredi spin_unlock(&cs->fc->lock); 760ce534fb0SMiklos Szeredi 761ce534fb0SMiklos Szeredi if (err) { 762ce534fb0SMiklos Szeredi unlock_page(newpage); 763ce534fb0SMiklos Szeredi page_cache_release(newpage); 764ce534fb0SMiklos Szeredi return err; 765ce534fb0SMiklos Szeredi } 766ce534fb0SMiklos Szeredi 767ce534fb0SMiklos Szeredi unlock_page(oldpage); 768ce534fb0SMiklos Szeredi page_cache_release(oldpage); 769ce534fb0SMiklos Szeredi cs->len = 0; 770ce534fb0SMiklos Szeredi 771ce534fb0SMiklos Szeredi return 0; 772ce534fb0SMiklos Szeredi 773ce534fb0SMiklos Szeredi out_fallback_unlock: 774ce534fb0SMiklos Szeredi unlock_page(newpage); 775ce534fb0SMiklos Szeredi out_fallback: 776ce534fb0SMiklos Szeredi cs->mapaddr = buf->ops->map(cs->pipe, buf, 1); 777ce534fb0SMiklos Szeredi cs->buf = cs->mapaddr + buf->offset; 778ce534fb0SMiklos Szeredi 779ce534fb0SMiklos Szeredi err = lock_request(cs->fc, cs->req); 780ce534fb0SMiklos Szeredi if (err) 781ce534fb0SMiklos Szeredi return err; 782ce534fb0SMiklos Szeredi 783ce534fb0SMiklos Szeredi return 1; 784ce534fb0SMiklos Szeredi } 785ce534fb0SMiklos Szeredi 786c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page, 787c3021629SMiklos Szeredi unsigned offset, unsigned count) 788c3021629SMiklos Szeredi { 789c3021629SMiklos Szeredi struct pipe_buffer *buf; 790c3021629SMiklos Szeredi 791c3021629SMiklos Szeredi if (cs->nr_segs == cs->pipe->buffers) 792c3021629SMiklos Szeredi return -EIO; 793c3021629SMiklos Szeredi 794c3021629SMiklos Szeredi unlock_request(cs->fc, cs->req); 795c3021629SMiklos Szeredi fuse_copy_finish(cs); 796c3021629SMiklos Szeredi 797c3021629SMiklos Szeredi buf = cs->pipebufs; 798c3021629SMiklos Szeredi page_cache_get(page); 799c3021629SMiklos Szeredi buf->page = page; 800c3021629SMiklos Szeredi buf->offset = offset; 801c3021629SMiklos Szeredi buf->len = count; 802c3021629SMiklos Szeredi 803c3021629SMiklos Szeredi cs->pipebufs++; 804c3021629SMiklos Szeredi cs->nr_segs++; 805c3021629SMiklos Szeredi cs->len = 0; 806c3021629SMiklos Szeredi 807c3021629SMiklos Szeredi return 0; 808c3021629SMiklos Szeredi } 809c3021629SMiklos Szeredi 810334f485dSMiklos Szeredi /* 811334f485dSMiklos Szeredi * Copy a page in the request to/from the userspace buffer. Must be 812334f485dSMiklos Szeredi * done atomically 813334f485dSMiklos Szeredi */ 814ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep, 815334f485dSMiklos Szeredi unsigned offset, unsigned count, int zeroing) 816334f485dSMiklos Szeredi { 817ce534fb0SMiklos Szeredi int err; 818ce534fb0SMiklos Szeredi struct page *page = *pagep; 819ce534fb0SMiklos Szeredi 820b6777c40SMiklos Szeredi if (page && zeroing && count < PAGE_SIZE) 821b6777c40SMiklos Szeredi clear_highpage(page); 822b6777c40SMiklos Szeredi 823334f485dSMiklos Szeredi while (count) { 824c3021629SMiklos Szeredi if (cs->write && cs->pipebufs && page) { 825c3021629SMiklos Szeredi return fuse_ref_page(cs, page, offset, count); 826c3021629SMiklos Szeredi } else if (!cs->len) { 827ce534fb0SMiklos Szeredi if (cs->move_pages && page && 828ce534fb0SMiklos Szeredi offset == 0 && count == PAGE_SIZE) { 829ce534fb0SMiklos Szeredi err = fuse_try_move_page(cs, pagep); 830ce534fb0SMiklos Szeredi if (err <= 0) 831ce534fb0SMiklos Szeredi return err; 832ce534fb0SMiklos Szeredi } else { 833ce534fb0SMiklos Szeredi err = fuse_copy_fill(cs); 8341729a16cSMiklos Szeredi if (err) 835334f485dSMiklos Szeredi return err; 8361729a16cSMiklos Szeredi } 837ce534fb0SMiklos Szeredi } 838334f485dSMiklos Szeredi if (page) { 839b6777c40SMiklos Szeredi void *mapaddr = kmap_atomic(page, KM_USER0); 840334f485dSMiklos Szeredi void *buf = mapaddr + offset; 841334f485dSMiklos Szeredi offset += fuse_copy_do(cs, &buf, &count); 842b6777c40SMiklos Szeredi kunmap_atomic(mapaddr, KM_USER0); 843334f485dSMiklos Szeredi } else 844334f485dSMiklos Szeredi offset += fuse_copy_do(cs, NULL, &count); 845334f485dSMiklos Szeredi } 846334f485dSMiklos Szeredi if (page && !cs->write) 847334f485dSMiklos Szeredi flush_dcache_page(page); 848334f485dSMiklos Szeredi return 0; 849334f485dSMiklos Szeredi } 850334f485dSMiklos Szeredi 851334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */ 852334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes, 853334f485dSMiklos Szeredi int zeroing) 854334f485dSMiklos Szeredi { 855334f485dSMiklos Szeredi unsigned i; 856334f485dSMiklos Szeredi struct fuse_req *req = cs->req; 857334f485dSMiklos Szeredi unsigned offset = req->page_offset; 858334f485dSMiklos Szeredi unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset); 859334f485dSMiklos Szeredi 860334f485dSMiklos Szeredi for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) { 861ce534fb0SMiklos Szeredi int err; 862ce534fb0SMiklos Szeredi 863ce534fb0SMiklos Szeredi err = fuse_copy_page(cs, &req->pages[i], offset, count, 864ce534fb0SMiklos Szeredi zeroing); 865334f485dSMiklos Szeredi if (err) 866334f485dSMiklos Szeredi return err; 867334f485dSMiklos Szeredi 868334f485dSMiklos Szeredi nbytes -= count; 869334f485dSMiklos Szeredi count = min(nbytes, (unsigned) PAGE_SIZE); 870334f485dSMiklos Szeredi offset = 0; 871334f485dSMiklos Szeredi } 872334f485dSMiklos Szeredi return 0; 873334f485dSMiklos Szeredi } 874334f485dSMiklos Szeredi 875334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */ 876334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size) 877334f485dSMiklos Szeredi { 878334f485dSMiklos Szeredi while (size) { 8791729a16cSMiklos Szeredi if (!cs->len) { 8801729a16cSMiklos Szeredi int err = fuse_copy_fill(cs); 8811729a16cSMiklos Szeredi if (err) 882334f485dSMiklos Szeredi return err; 8831729a16cSMiklos Szeredi } 884334f485dSMiklos Szeredi fuse_copy_do(cs, &val, &size); 885334f485dSMiklos Szeredi } 886334f485dSMiklos Szeredi return 0; 887334f485dSMiklos Szeredi } 888334f485dSMiklos Szeredi 889334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */ 890334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs, 891334f485dSMiklos Szeredi unsigned argpages, struct fuse_arg *args, 892334f485dSMiklos Szeredi int zeroing) 893334f485dSMiklos Szeredi { 894334f485dSMiklos Szeredi int err = 0; 895334f485dSMiklos Szeredi unsigned i; 896334f485dSMiklos Szeredi 897334f485dSMiklos Szeredi for (i = 0; !err && i < numargs; i++) { 898334f485dSMiklos Szeredi struct fuse_arg *arg = &args[i]; 899334f485dSMiklos Szeredi if (i == numargs - 1 && argpages) 900334f485dSMiklos Szeredi err = fuse_copy_pages(cs, arg->size, zeroing); 901334f485dSMiklos Szeredi else 902334f485dSMiklos Szeredi err = fuse_copy_one(cs, arg->value, arg->size); 903334f485dSMiklos Szeredi } 904334f485dSMiklos Szeredi return err; 905334f485dSMiklos Szeredi } 906334f485dSMiklos Szeredi 90707e77dcaSMiklos Szeredi static int forget_pending(struct fuse_conn *fc) 90807e77dcaSMiklos Szeredi { 90907e77dcaSMiklos Szeredi return fc->forget_list_head.next != NULL; 91007e77dcaSMiklos Szeredi } 91107e77dcaSMiklos Szeredi 912a4d27e75SMiklos Szeredi static int request_pending(struct fuse_conn *fc) 913a4d27e75SMiklos Szeredi { 91407e77dcaSMiklos Szeredi return !list_empty(&fc->pending) || !list_empty(&fc->interrupts) || 91507e77dcaSMiklos Szeredi forget_pending(fc); 916a4d27e75SMiklos Szeredi } 917a4d27e75SMiklos Szeredi 918334f485dSMiklos Szeredi /* Wait until a request is available on the pending list */ 919334f485dSMiklos Szeredi static void request_wait(struct fuse_conn *fc) 920b9ca67b2SMiklos Szeredi __releases(fc->lock) 921b9ca67b2SMiklos Szeredi __acquires(fc->lock) 922334f485dSMiklos Szeredi { 923334f485dSMiklos Szeredi DECLARE_WAITQUEUE(wait, current); 924334f485dSMiklos Szeredi 925334f485dSMiklos Szeredi add_wait_queue_exclusive(&fc->waitq, &wait); 926a4d27e75SMiklos Szeredi while (fc->connected && !request_pending(fc)) { 927334f485dSMiklos Szeredi set_current_state(TASK_INTERRUPTIBLE); 928334f485dSMiklos Szeredi if (signal_pending(current)) 929334f485dSMiklos Szeredi break; 930334f485dSMiklos Szeredi 931d7133114SMiklos Szeredi spin_unlock(&fc->lock); 932334f485dSMiklos Szeredi schedule(); 933d7133114SMiklos Szeredi spin_lock(&fc->lock); 934334f485dSMiklos Szeredi } 935334f485dSMiklos Szeredi set_current_state(TASK_RUNNING); 936334f485dSMiklos Szeredi remove_wait_queue(&fc->waitq, &wait); 937334f485dSMiklos Szeredi } 938334f485dSMiklos Szeredi 939334f485dSMiklos Szeredi /* 940a4d27e75SMiklos Szeredi * Transfer an interrupt request to userspace 941a4d27e75SMiklos Szeredi * 942a4d27e75SMiklos Szeredi * Unlike other requests this is assembled on demand, without a need 943a4d27e75SMiklos Szeredi * to allocate a separate fuse_req structure. 944a4d27e75SMiklos Szeredi * 945a4d27e75SMiklos Szeredi * Called with fc->lock held, releases it 946a4d27e75SMiklos Szeredi */ 947c3021629SMiklos Szeredi static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_copy_state *cs, 948c3021629SMiklos Szeredi size_t nbytes, struct fuse_req *req) 949b9ca67b2SMiklos Szeredi __releases(fc->lock) 950a4d27e75SMiklos Szeredi { 951a4d27e75SMiklos Szeredi struct fuse_in_header ih; 952a4d27e75SMiklos Szeredi struct fuse_interrupt_in arg; 953a4d27e75SMiklos Szeredi unsigned reqsize = sizeof(ih) + sizeof(arg); 954a4d27e75SMiklos Szeredi int err; 955a4d27e75SMiklos Szeredi 956a4d27e75SMiklos Szeredi list_del_init(&req->intr_entry); 957a4d27e75SMiklos Szeredi req->intr_unique = fuse_get_unique(fc); 958a4d27e75SMiklos Szeredi memset(&ih, 0, sizeof(ih)); 959a4d27e75SMiklos Szeredi memset(&arg, 0, sizeof(arg)); 960a4d27e75SMiklos Szeredi ih.len = reqsize; 961a4d27e75SMiklos Szeredi ih.opcode = FUSE_INTERRUPT; 962a4d27e75SMiklos Szeredi ih.unique = req->intr_unique; 963a4d27e75SMiklos Szeredi arg.unique = req->in.h.unique; 964a4d27e75SMiklos Szeredi 965a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 966c3021629SMiklos Szeredi if (nbytes < reqsize) 967a4d27e75SMiklos Szeredi return -EINVAL; 968a4d27e75SMiklos Szeredi 969c3021629SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 970a4d27e75SMiklos Szeredi if (!err) 971c3021629SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 972c3021629SMiklos Szeredi fuse_copy_finish(cs); 973a4d27e75SMiklos Szeredi 974a4d27e75SMiklos Szeredi return err ? err : reqsize; 975a4d27e75SMiklos Szeredi } 976a4d27e75SMiklos Szeredi 97702c048b9SMiklos Szeredi static struct fuse_forget_link *dequeue_forget(struct fuse_conn *fc, 97802c048b9SMiklos Szeredi unsigned max, 97902c048b9SMiklos Szeredi unsigned *countp) 98007e77dcaSMiklos Szeredi { 98102c048b9SMiklos Szeredi struct fuse_forget_link *head = fc->forget_list_head.next; 98202c048b9SMiklos Szeredi struct fuse_forget_link **newhead = &head; 98302c048b9SMiklos Szeredi unsigned count; 98407e77dcaSMiklos Szeredi 98502c048b9SMiklos Szeredi for (count = 0; *newhead != NULL && count < max; count++) 98602c048b9SMiklos Szeredi newhead = &(*newhead)->next; 98702c048b9SMiklos Szeredi 98802c048b9SMiklos Szeredi fc->forget_list_head.next = *newhead; 98902c048b9SMiklos Szeredi *newhead = NULL; 99007e77dcaSMiklos Szeredi if (fc->forget_list_head.next == NULL) 99107e77dcaSMiklos Szeredi fc->forget_list_tail = &fc->forget_list_head; 99207e77dcaSMiklos Szeredi 99302c048b9SMiklos Szeredi if (countp != NULL) 99402c048b9SMiklos Szeredi *countp = count; 99502c048b9SMiklos Szeredi 99602c048b9SMiklos Szeredi return head; 99707e77dcaSMiklos Szeredi } 99807e77dcaSMiklos Szeredi 99907e77dcaSMiklos Szeredi static int fuse_read_single_forget(struct fuse_conn *fc, 100007e77dcaSMiklos Szeredi struct fuse_copy_state *cs, 100107e77dcaSMiklos Szeredi size_t nbytes) 100207e77dcaSMiklos Szeredi __releases(fc->lock) 100307e77dcaSMiklos Szeredi { 100407e77dcaSMiklos Szeredi int err; 100502c048b9SMiklos Szeredi struct fuse_forget_link *forget = dequeue_forget(fc, 1, NULL); 100607e77dcaSMiklos Szeredi struct fuse_forget_in arg = { 100702c048b9SMiklos Szeredi .nlookup = forget->forget_one.nlookup, 100807e77dcaSMiklos Szeredi }; 100907e77dcaSMiklos Szeredi struct fuse_in_header ih = { 101007e77dcaSMiklos Szeredi .opcode = FUSE_FORGET, 101102c048b9SMiklos Szeredi .nodeid = forget->forget_one.nodeid, 101207e77dcaSMiklos Szeredi .unique = fuse_get_unique(fc), 101307e77dcaSMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 101407e77dcaSMiklos Szeredi }; 101507e77dcaSMiklos Szeredi 101607e77dcaSMiklos Szeredi spin_unlock(&fc->lock); 101707e77dcaSMiklos Szeredi kfree(forget); 101807e77dcaSMiklos Szeredi if (nbytes < ih.len) 101907e77dcaSMiklos Szeredi return -EINVAL; 102007e77dcaSMiklos Szeredi 102107e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 102207e77dcaSMiklos Szeredi if (!err) 102307e77dcaSMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 102407e77dcaSMiklos Szeredi fuse_copy_finish(cs); 102507e77dcaSMiklos Szeredi 102607e77dcaSMiklos Szeredi if (err) 102707e77dcaSMiklos Szeredi return err; 102807e77dcaSMiklos Szeredi 102907e77dcaSMiklos Szeredi return ih.len; 103007e77dcaSMiklos Szeredi } 103107e77dcaSMiklos Szeredi 103202c048b9SMiklos Szeredi static int fuse_read_batch_forget(struct fuse_conn *fc, 103302c048b9SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 103402c048b9SMiklos Szeredi __releases(fc->lock) 103502c048b9SMiklos Szeredi { 103602c048b9SMiklos Szeredi int err; 103702c048b9SMiklos Szeredi unsigned max_forgets; 103802c048b9SMiklos Szeredi unsigned count; 103902c048b9SMiklos Szeredi struct fuse_forget_link *head; 104002c048b9SMiklos Szeredi struct fuse_batch_forget_in arg = { .count = 0 }; 104102c048b9SMiklos Szeredi struct fuse_in_header ih = { 104202c048b9SMiklos Szeredi .opcode = FUSE_BATCH_FORGET, 104302c048b9SMiklos Szeredi .unique = fuse_get_unique(fc), 104402c048b9SMiklos Szeredi .len = sizeof(ih) + sizeof(arg), 104502c048b9SMiklos Szeredi }; 104602c048b9SMiklos Szeredi 104702c048b9SMiklos Szeredi if (nbytes < ih.len) { 104802c048b9SMiklos Szeredi spin_unlock(&fc->lock); 104902c048b9SMiklos Szeredi return -EINVAL; 105002c048b9SMiklos Szeredi } 105102c048b9SMiklos Szeredi 105202c048b9SMiklos Szeredi max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one); 105302c048b9SMiklos Szeredi head = dequeue_forget(fc, max_forgets, &count); 105402c048b9SMiklos Szeredi spin_unlock(&fc->lock); 105502c048b9SMiklos Szeredi 105602c048b9SMiklos Szeredi arg.count = count; 105702c048b9SMiklos Szeredi ih.len += count * sizeof(struct fuse_forget_one); 105802c048b9SMiklos Szeredi err = fuse_copy_one(cs, &ih, sizeof(ih)); 105902c048b9SMiklos Szeredi if (!err) 106002c048b9SMiklos Szeredi err = fuse_copy_one(cs, &arg, sizeof(arg)); 106102c048b9SMiklos Szeredi 106202c048b9SMiklos Szeredi while (head) { 106302c048b9SMiklos Szeredi struct fuse_forget_link *forget = head; 106402c048b9SMiklos Szeredi 106502c048b9SMiklos Szeredi if (!err) { 106602c048b9SMiklos Szeredi err = fuse_copy_one(cs, &forget->forget_one, 106702c048b9SMiklos Szeredi sizeof(forget->forget_one)); 106802c048b9SMiklos Szeredi } 106902c048b9SMiklos Szeredi head = forget->next; 107002c048b9SMiklos Szeredi kfree(forget); 107102c048b9SMiklos Szeredi } 107202c048b9SMiklos Szeredi 107302c048b9SMiklos Szeredi fuse_copy_finish(cs); 107402c048b9SMiklos Szeredi 107502c048b9SMiklos Szeredi if (err) 107602c048b9SMiklos Szeredi return err; 107702c048b9SMiklos Szeredi 107802c048b9SMiklos Szeredi return ih.len; 107902c048b9SMiklos Szeredi } 108002c048b9SMiklos Szeredi 108102c048b9SMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_copy_state *cs, 108202c048b9SMiklos Szeredi size_t nbytes) 108302c048b9SMiklos Szeredi __releases(fc->lock) 108402c048b9SMiklos Szeredi { 108502c048b9SMiklos Szeredi if (fc->minor < 16 || fc->forget_list_head.next->next == NULL) 108602c048b9SMiklos Szeredi return fuse_read_single_forget(fc, cs, nbytes); 108702c048b9SMiklos Szeredi else 108802c048b9SMiklos Szeredi return fuse_read_batch_forget(fc, cs, nbytes); 108902c048b9SMiklos Szeredi } 109002c048b9SMiklos Szeredi 1091a4d27e75SMiklos Szeredi /* 1092334f485dSMiklos Szeredi * Read a single request into the userspace filesystem's buffer. This 1093334f485dSMiklos Szeredi * function waits until a request is available, then removes it from 1094334f485dSMiklos Szeredi * the pending list and copies request data to userspace buffer. If 1095f9a2842eSMiklos Szeredi * no reply is needed (FORGET) or request has been aborted or there 1096f9a2842eSMiklos Szeredi * was an error during the copying then it's finished by calling 1097334f485dSMiklos Szeredi * request_end(). Otherwise add it to the processing list, and set 1098334f485dSMiklos Szeredi * the 'sent' flag. 1099334f485dSMiklos Szeredi */ 1100c3021629SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file, 1101c3021629SMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1102334f485dSMiklos Szeredi { 1103334f485dSMiklos Szeredi int err; 1104334f485dSMiklos Szeredi struct fuse_req *req; 1105334f485dSMiklos Szeredi struct fuse_in *in; 1106334f485dSMiklos Szeredi unsigned reqsize; 1107334f485dSMiklos Szeredi 11081d3d752bSMiklos Szeredi restart: 1109d7133114SMiklos Szeredi spin_lock(&fc->lock); 1110e5ac1d1eSJeff Dike err = -EAGAIN; 1111e5ac1d1eSJeff Dike if ((file->f_flags & O_NONBLOCK) && fc->connected && 1112a4d27e75SMiklos Szeredi !request_pending(fc)) 1113e5ac1d1eSJeff Dike goto err_unlock; 1114e5ac1d1eSJeff Dike 1115334f485dSMiklos Szeredi request_wait(fc); 1116334f485dSMiklos Szeredi err = -ENODEV; 11179ba7cbbaSMiklos Szeredi if (!fc->connected) 1118334f485dSMiklos Szeredi goto err_unlock; 1119334f485dSMiklos Szeredi err = -ERESTARTSYS; 1120a4d27e75SMiklos Szeredi if (!request_pending(fc)) 1121334f485dSMiklos Szeredi goto err_unlock; 1122334f485dSMiklos Szeredi 1123a4d27e75SMiklos Szeredi if (!list_empty(&fc->interrupts)) { 1124a4d27e75SMiklos Szeredi req = list_entry(fc->interrupts.next, struct fuse_req, 1125a4d27e75SMiklos Szeredi intr_entry); 1126c3021629SMiklos Szeredi return fuse_read_interrupt(fc, cs, nbytes, req); 1127a4d27e75SMiklos Szeredi } 1128a4d27e75SMiklos Szeredi 112907e77dcaSMiklos Szeredi if (forget_pending(fc)) { 113007e77dcaSMiklos Szeredi if (list_empty(&fc->pending) || fc->forget_batch-- > 0) 113102c048b9SMiklos Szeredi return fuse_read_forget(fc, cs, nbytes); 113207e77dcaSMiklos Szeredi 113307e77dcaSMiklos Szeredi if (fc->forget_batch <= -8) 113407e77dcaSMiklos Szeredi fc->forget_batch = 16; 113507e77dcaSMiklos Szeredi } 113607e77dcaSMiklos Szeredi 1137334f485dSMiklos Szeredi req = list_entry(fc->pending.next, struct fuse_req, list); 113883cfd493SMiklos Szeredi req->state = FUSE_REQ_READING; 1139d77a1d5bSMiklos Szeredi list_move(&req->list, &fc->io); 1140334f485dSMiklos Szeredi 1141334f485dSMiklos Szeredi in = &req->in; 11421d3d752bSMiklos Szeredi reqsize = in->h.len; 11431d3d752bSMiklos Szeredi /* If request is too large, reply with an error and restart the read */ 1144c3021629SMiklos Szeredi if (nbytes < reqsize) { 11451d3d752bSMiklos Szeredi req->out.h.error = -EIO; 11461d3d752bSMiklos Szeredi /* SETXATTR is special, since it may contain too large data */ 11471d3d752bSMiklos Szeredi if (in->h.opcode == FUSE_SETXATTR) 11481d3d752bSMiklos Szeredi req->out.h.error = -E2BIG; 11491d3d752bSMiklos Szeredi request_end(fc, req); 11501d3d752bSMiklos Szeredi goto restart; 11511d3d752bSMiklos Szeredi } 1152d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1153c3021629SMiklos Szeredi cs->req = req; 1154c3021629SMiklos Szeredi err = fuse_copy_one(cs, &in->h, sizeof(in->h)); 1155334f485dSMiklos Szeredi if (!err) 1156c3021629SMiklos Szeredi err = fuse_copy_args(cs, in->numargs, in->argpages, 1157334f485dSMiklos Szeredi (struct fuse_arg *) in->args, 0); 1158c3021629SMiklos Szeredi fuse_copy_finish(cs); 1159d7133114SMiklos Szeredi spin_lock(&fc->lock); 1160334f485dSMiklos Szeredi req->locked = 0; 1161c9c9d7dfSMiklos Szeredi if (req->aborted) { 1162c9c9d7dfSMiklos Szeredi request_end(fc, req); 1163c9c9d7dfSMiklos Szeredi return -ENODEV; 1164c9c9d7dfSMiklos Szeredi } 1165334f485dSMiklos Szeredi if (err) { 1166334f485dSMiklos Szeredi req->out.h.error = -EIO; 1167334f485dSMiklos Szeredi request_end(fc, req); 1168334f485dSMiklos Szeredi return err; 1169334f485dSMiklos Szeredi } 1170334f485dSMiklos Szeredi if (!req->isreply) 1171334f485dSMiklos Szeredi request_end(fc, req); 1172334f485dSMiklos Szeredi else { 117383cfd493SMiklos Szeredi req->state = FUSE_REQ_SENT; 1174d77a1d5bSMiklos Szeredi list_move_tail(&req->list, &fc->processing); 1175a4d27e75SMiklos Szeredi if (req->interrupted) 1176a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 1177d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1178334f485dSMiklos Szeredi } 1179334f485dSMiklos Szeredi return reqsize; 1180334f485dSMiklos Szeredi 1181334f485dSMiklos Szeredi err_unlock: 1182d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1183334f485dSMiklos Szeredi return err; 1184334f485dSMiklos Szeredi } 1185334f485dSMiklos Szeredi 1186c3021629SMiklos Szeredi static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, 1187c3021629SMiklos Szeredi unsigned long nr_segs, loff_t pos) 1188c3021629SMiklos Szeredi { 1189c3021629SMiklos Szeredi struct fuse_copy_state cs; 1190c3021629SMiklos Szeredi struct file *file = iocb->ki_filp; 1191c3021629SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 1192c3021629SMiklos Szeredi if (!fc) 1193c3021629SMiklos Szeredi return -EPERM; 1194c3021629SMiklos Szeredi 1195c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 1, iov, nr_segs); 1196c3021629SMiklos Szeredi 1197c3021629SMiklos Szeredi return fuse_dev_do_read(fc, file, &cs, iov_length(iov, nr_segs)); 1198c3021629SMiklos Szeredi } 1199c3021629SMiklos Szeredi 1200c3021629SMiklos Szeredi static int fuse_dev_pipe_buf_steal(struct pipe_inode_info *pipe, 1201c3021629SMiklos Szeredi struct pipe_buffer *buf) 1202c3021629SMiklos Szeredi { 1203c3021629SMiklos Szeredi return 1; 1204c3021629SMiklos Szeredi } 1205c3021629SMiklos Szeredi 1206c3021629SMiklos Szeredi static const struct pipe_buf_operations fuse_dev_pipe_buf_ops = { 1207c3021629SMiklos Szeredi .can_merge = 0, 1208c3021629SMiklos Szeredi .map = generic_pipe_buf_map, 1209c3021629SMiklos Szeredi .unmap = generic_pipe_buf_unmap, 1210c3021629SMiklos Szeredi .confirm = generic_pipe_buf_confirm, 1211c3021629SMiklos Szeredi .release = generic_pipe_buf_release, 1212c3021629SMiklos Szeredi .steal = fuse_dev_pipe_buf_steal, 1213c3021629SMiklos Szeredi .get = generic_pipe_buf_get, 1214c3021629SMiklos Szeredi }; 1215c3021629SMiklos Szeredi 1216c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, 1217c3021629SMiklos Szeredi struct pipe_inode_info *pipe, 1218c3021629SMiklos Szeredi size_t len, unsigned int flags) 1219c3021629SMiklos Szeredi { 1220c3021629SMiklos Szeredi int ret; 1221c3021629SMiklos Szeredi int page_nr = 0; 1222c3021629SMiklos Szeredi int do_wakeup = 0; 1223c3021629SMiklos Szeredi struct pipe_buffer *bufs; 1224c3021629SMiklos Szeredi struct fuse_copy_state cs; 1225c3021629SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(in); 1226c3021629SMiklos Szeredi if (!fc) 1227c3021629SMiklos Szeredi return -EPERM; 1228c3021629SMiklos Szeredi 1229c3021629SMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1230c3021629SMiklos Szeredi if (!bufs) 1231c3021629SMiklos Szeredi return -ENOMEM; 1232c3021629SMiklos Szeredi 1233c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 1, NULL, 0); 1234c3021629SMiklos Szeredi cs.pipebufs = bufs; 1235c3021629SMiklos Szeredi cs.pipe = pipe; 1236c3021629SMiklos Szeredi ret = fuse_dev_do_read(fc, in, &cs, len); 1237c3021629SMiklos Szeredi if (ret < 0) 1238c3021629SMiklos Szeredi goto out; 1239c3021629SMiklos Szeredi 1240c3021629SMiklos Szeredi ret = 0; 1241c3021629SMiklos Szeredi pipe_lock(pipe); 1242c3021629SMiklos Szeredi 1243c3021629SMiklos Szeredi if (!pipe->readers) { 1244c3021629SMiklos Szeredi send_sig(SIGPIPE, current, 0); 1245c3021629SMiklos Szeredi if (!ret) 1246c3021629SMiklos Szeredi ret = -EPIPE; 1247c3021629SMiklos Szeredi goto out_unlock; 1248c3021629SMiklos Szeredi } 1249c3021629SMiklos Szeredi 1250c3021629SMiklos Szeredi if (pipe->nrbufs + cs.nr_segs > pipe->buffers) { 1251c3021629SMiklos Szeredi ret = -EIO; 1252c3021629SMiklos Szeredi goto out_unlock; 1253c3021629SMiklos Szeredi } 1254c3021629SMiklos Szeredi 1255c3021629SMiklos Szeredi while (page_nr < cs.nr_segs) { 1256c3021629SMiklos Szeredi int newbuf = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); 1257c3021629SMiklos Szeredi struct pipe_buffer *buf = pipe->bufs + newbuf; 1258c3021629SMiklos Szeredi 1259c3021629SMiklos Szeredi buf->page = bufs[page_nr].page; 1260c3021629SMiklos Szeredi buf->offset = bufs[page_nr].offset; 1261c3021629SMiklos Szeredi buf->len = bufs[page_nr].len; 1262c3021629SMiklos Szeredi buf->ops = &fuse_dev_pipe_buf_ops; 1263c3021629SMiklos Szeredi 1264c3021629SMiklos Szeredi pipe->nrbufs++; 1265c3021629SMiklos Szeredi page_nr++; 1266c3021629SMiklos Szeredi ret += buf->len; 1267c3021629SMiklos Szeredi 1268c3021629SMiklos Szeredi if (pipe->inode) 1269c3021629SMiklos Szeredi do_wakeup = 1; 1270c3021629SMiklos Szeredi } 1271c3021629SMiklos Szeredi 1272c3021629SMiklos Szeredi out_unlock: 1273c3021629SMiklos Szeredi pipe_unlock(pipe); 1274c3021629SMiklos Szeredi 1275c3021629SMiklos Szeredi if (do_wakeup) { 1276c3021629SMiklos Szeredi smp_mb(); 1277c3021629SMiklos Szeredi if (waitqueue_active(&pipe->wait)) 1278c3021629SMiklos Szeredi wake_up_interruptible(&pipe->wait); 1279c3021629SMiklos Szeredi kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); 1280c3021629SMiklos Szeredi } 1281c3021629SMiklos Szeredi 1282c3021629SMiklos Szeredi out: 1283c3021629SMiklos Szeredi for (; page_nr < cs.nr_segs; page_nr++) 1284c3021629SMiklos Szeredi page_cache_release(bufs[page_nr].page); 1285c3021629SMiklos Szeredi 1286c3021629SMiklos Szeredi kfree(bufs); 1287c3021629SMiklos Szeredi return ret; 1288c3021629SMiklos Szeredi } 1289c3021629SMiklos Szeredi 129095668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size, 129195668a69STejun Heo struct fuse_copy_state *cs) 129295668a69STejun Heo { 129395668a69STejun Heo struct fuse_notify_poll_wakeup_out outarg; 1294f6d47a17SMiklos Szeredi int err = -EINVAL; 129595668a69STejun Heo 129695668a69STejun Heo if (size != sizeof(outarg)) 1297f6d47a17SMiklos Szeredi goto err; 129895668a69STejun Heo 129995668a69STejun Heo err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 130095668a69STejun Heo if (err) 1301f6d47a17SMiklos Szeredi goto err; 130295668a69STejun Heo 1303f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 130495668a69STejun Heo return fuse_notify_poll_wakeup(fc, &outarg); 1305f6d47a17SMiklos Szeredi 1306f6d47a17SMiklos Szeredi err: 1307f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 1308f6d47a17SMiklos Szeredi return err; 130995668a69STejun Heo } 131095668a69STejun Heo 13113b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size, 13123b463ae0SJohn Muir struct fuse_copy_state *cs) 13133b463ae0SJohn Muir { 13143b463ae0SJohn Muir struct fuse_notify_inval_inode_out outarg; 13153b463ae0SJohn Muir int err = -EINVAL; 13163b463ae0SJohn Muir 13173b463ae0SJohn Muir if (size != sizeof(outarg)) 13183b463ae0SJohn Muir goto err; 13193b463ae0SJohn Muir 13203b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 13213b463ae0SJohn Muir if (err) 13223b463ae0SJohn Muir goto err; 13233b463ae0SJohn Muir fuse_copy_finish(cs); 13243b463ae0SJohn Muir 13253b463ae0SJohn Muir down_read(&fc->killsb); 13263b463ae0SJohn Muir err = -ENOENT; 1327b21dda43SMiklos Szeredi if (fc->sb) { 13283b463ae0SJohn Muir err = fuse_reverse_inval_inode(fc->sb, outarg.ino, 13293b463ae0SJohn Muir outarg.off, outarg.len); 1330b21dda43SMiklos Szeredi } 13313b463ae0SJohn Muir up_read(&fc->killsb); 13323b463ae0SJohn Muir return err; 13333b463ae0SJohn Muir 13343b463ae0SJohn Muir err: 13353b463ae0SJohn Muir fuse_copy_finish(cs); 13363b463ae0SJohn Muir return err; 13373b463ae0SJohn Muir } 13383b463ae0SJohn Muir 13393b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size, 13403b463ae0SJohn Muir struct fuse_copy_state *cs) 13413b463ae0SJohn Muir { 13423b463ae0SJohn Muir struct fuse_notify_inval_entry_out outarg; 1343b2d82ee3SFang Wenqi int err = -ENOMEM; 1344b2d82ee3SFang Wenqi char *buf; 13453b463ae0SJohn Muir struct qstr name; 13463b463ae0SJohn Muir 1347b2d82ee3SFang Wenqi buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL); 1348b2d82ee3SFang Wenqi if (!buf) 1349b2d82ee3SFang Wenqi goto err; 1350b2d82ee3SFang Wenqi 1351b2d82ee3SFang Wenqi err = -EINVAL; 13523b463ae0SJohn Muir if (size < sizeof(outarg)) 13533b463ae0SJohn Muir goto err; 13543b463ae0SJohn Muir 13553b463ae0SJohn Muir err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 13563b463ae0SJohn Muir if (err) 13573b463ae0SJohn Muir goto err; 13583b463ae0SJohn Muir 13593b463ae0SJohn Muir err = -ENAMETOOLONG; 13603b463ae0SJohn Muir if (outarg.namelen > FUSE_NAME_MAX) 13613b463ae0SJohn Muir goto err; 13623b463ae0SJohn Muir 13633b463ae0SJohn Muir name.name = buf; 13643b463ae0SJohn Muir name.len = outarg.namelen; 13653b463ae0SJohn Muir err = fuse_copy_one(cs, buf, outarg.namelen + 1); 13663b463ae0SJohn Muir if (err) 13673b463ae0SJohn Muir goto err; 13683b463ae0SJohn Muir fuse_copy_finish(cs); 13693b463ae0SJohn Muir buf[outarg.namelen] = 0; 13703b463ae0SJohn Muir name.hash = full_name_hash(name.name, name.len); 13713b463ae0SJohn Muir 13723b463ae0SJohn Muir down_read(&fc->killsb); 13733b463ae0SJohn Muir err = -ENOENT; 1374b21dda43SMiklos Szeredi if (fc->sb) 13753b463ae0SJohn Muir err = fuse_reverse_inval_entry(fc->sb, outarg.parent, &name); 13763b463ae0SJohn Muir up_read(&fc->killsb); 1377b2d82ee3SFang Wenqi kfree(buf); 13783b463ae0SJohn Muir return err; 13793b463ae0SJohn Muir 13803b463ae0SJohn Muir err: 1381b2d82ee3SFang Wenqi kfree(buf); 13823b463ae0SJohn Muir fuse_copy_finish(cs); 13833b463ae0SJohn Muir return err; 13843b463ae0SJohn Muir } 13853b463ae0SJohn Muir 1386a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, 1387a1d75f25SMiklos Szeredi struct fuse_copy_state *cs) 1388a1d75f25SMiklos Szeredi { 1389a1d75f25SMiklos Szeredi struct fuse_notify_store_out outarg; 1390a1d75f25SMiklos Szeredi struct inode *inode; 1391a1d75f25SMiklos Szeredi struct address_space *mapping; 1392a1d75f25SMiklos Szeredi u64 nodeid; 1393a1d75f25SMiklos Szeredi int err; 1394a1d75f25SMiklos Szeredi pgoff_t index; 1395a1d75f25SMiklos Szeredi unsigned int offset; 1396a1d75f25SMiklos Szeredi unsigned int num; 1397a1d75f25SMiklos Szeredi loff_t file_size; 1398a1d75f25SMiklos Szeredi loff_t end; 1399a1d75f25SMiklos Szeredi 1400a1d75f25SMiklos Szeredi err = -EINVAL; 1401a1d75f25SMiklos Szeredi if (size < sizeof(outarg)) 1402a1d75f25SMiklos Szeredi goto out_finish; 1403a1d75f25SMiklos Szeredi 1404a1d75f25SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 1405a1d75f25SMiklos Szeredi if (err) 1406a1d75f25SMiklos Szeredi goto out_finish; 1407a1d75f25SMiklos Szeredi 1408a1d75f25SMiklos Szeredi err = -EINVAL; 1409a1d75f25SMiklos Szeredi if (size - sizeof(outarg) != outarg.size) 1410a1d75f25SMiklos Szeredi goto out_finish; 1411a1d75f25SMiklos Szeredi 1412a1d75f25SMiklos Szeredi nodeid = outarg.nodeid; 1413a1d75f25SMiklos Szeredi 1414a1d75f25SMiklos Szeredi down_read(&fc->killsb); 1415a1d75f25SMiklos Szeredi 1416a1d75f25SMiklos Szeredi err = -ENOENT; 1417a1d75f25SMiklos Szeredi if (!fc->sb) 1418a1d75f25SMiklos Szeredi goto out_up_killsb; 1419a1d75f25SMiklos Szeredi 1420a1d75f25SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 1421a1d75f25SMiklos Szeredi if (!inode) 1422a1d75f25SMiklos Szeredi goto out_up_killsb; 1423a1d75f25SMiklos Szeredi 1424a1d75f25SMiklos Szeredi mapping = inode->i_mapping; 1425a1d75f25SMiklos Szeredi index = outarg.offset >> PAGE_CACHE_SHIFT; 1426a1d75f25SMiklos Szeredi offset = outarg.offset & ~PAGE_CACHE_MASK; 1427a1d75f25SMiklos Szeredi file_size = i_size_read(inode); 1428a1d75f25SMiklos Szeredi end = outarg.offset + outarg.size; 1429a1d75f25SMiklos Szeredi if (end > file_size) { 1430a1d75f25SMiklos Szeredi file_size = end; 1431a1d75f25SMiklos Szeredi fuse_write_update_size(inode, file_size); 1432a1d75f25SMiklos Szeredi } 1433a1d75f25SMiklos Szeredi 1434a1d75f25SMiklos Szeredi num = outarg.size; 1435a1d75f25SMiklos Szeredi while (num) { 1436a1d75f25SMiklos Szeredi struct page *page; 1437a1d75f25SMiklos Szeredi unsigned int this_num; 1438a1d75f25SMiklos Szeredi 1439a1d75f25SMiklos Szeredi err = -ENOMEM; 1440a1d75f25SMiklos Szeredi page = find_or_create_page(mapping, index, 1441a1d75f25SMiklos Szeredi mapping_gfp_mask(mapping)); 1442a1d75f25SMiklos Szeredi if (!page) 1443a1d75f25SMiklos Szeredi goto out_iput; 1444a1d75f25SMiklos Szeredi 1445a1d75f25SMiklos Szeredi this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 1446a1d75f25SMiklos Szeredi err = fuse_copy_page(cs, &page, offset, this_num, 0); 1447a1d75f25SMiklos Szeredi if (!err && offset == 0 && (num != 0 || file_size == end)) 1448a1d75f25SMiklos Szeredi SetPageUptodate(page); 1449a1d75f25SMiklos Szeredi unlock_page(page); 1450a1d75f25SMiklos Szeredi page_cache_release(page); 1451a1d75f25SMiklos Szeredi 1452a1d75f25SMiklos Szeredi if (err) 1453a1d75f25SMiklos Szeredi goto out_iput; 1454a1d75f25SMiklos Szeredi 1455a1d75f25SMiklos Szeredi num -= this_num; 1456a1d75f25SMiklos Szeredi offset = 0; 1457a1d75f25SMiklos Szeredi index++; 1458a1d75f25SMiklos Szeredi } 1459a1d75f25SMiklos Szeredi 1460a1d75f25SMiklos Szeredi err = 0; 1461a1d75f25SMiklos Szeredi 1462a1d75f25SMiklos Szeredi out_iput: 1463a1d75f25SMiklos Szeredi iput(inode); 1464a1d75f25SMiklos Szeredi out_up_killsb: 1465a1d75f25SMiklos Szeredi up_read(&fc->killsb); 1466a1d75f25SMiklos Szeredi out_finish: 1467a1d75f25SMiklos Szeredi fuse_copy_finish(cs); 1468a1d75f25SMiklos Szeredi return err; 1469a1d75f25SMiklos Szeredi } 1470a1d75f25SMiklos Szeredi 14712d45ba38SMiklos Szeredi static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req) 14722d45ba38SMiklos Szeredi { 14730be8557bSMiklos Szeredi release_pages(req->pages, req->num_pages, 0); 14742d45ba38SMiklos Szeredi } 14752d45ba38SMiklos Szeredi 14762d45ba38SMiklos Szeredi static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, 14772d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out *outarg) 14782d45ba38SMiklos Szeredi { 14792d45ba38SMiklos Szeredi int err; 14802d45ba38SMiklos Szeredi struct address_space *mapping = inode->i_mapping; 14812d45ba38SMiklos Szeredi struct fuse_req *req; 14822d45ba38SMiklos Szeredi pgoff_t index; 14832d45ba38SMiklos Szeredi loff_t file_size; 14842d45ba38SMiklos Szeredi unsigned int num; 14852d45ba38SMiklos Szeredi unsigned int offset; 14860157443cSGeert Uytterhoeven size_t total_len = 0; 14872d45ba38SMiklos Szeredi 14882d45ba38SMiklos Szeredi req = fuse_get_req(fc); 14892d45ba38SMiklos Szeredi if (IS_ERR(req)) 14902d45ba38SMiklos Szeredi return PTR_ERR(req); 14912d45ba38SMiklos Szeredi 14922d45ba38SMiklos Szeredi offset = outarg->offset & ~PAGE_CACHE_MASK; 14932d45ba38SMiklos Szeredi 14942d45ba38SMiklos Szeredi req->in.h.opcode = FUSE_NOTIFY_REPLY; 14952d45ba38SMiklos Szeredi req->in.h.nodeid = outarg->nodeid; 14962d45ba38SMiklos Szeredi req->in.numargs = 2; 14972d45ba38SMiklos Szeredi req->in.argpages = 1; 14982d45ba38SMiklos Szeredi req->page_offset = offset; 14992d45ba38SMiklos Szeredi req->end = fuse_retrieve_end; 15002d45ba38SMiklos Szeredi 15012d45ba38SMiklos Szeredi index = outarg->offset >> PAGE_CACHE_SHIFT; 15022d45ba38SMiklos Szeredi file_size = i_size_read(inode); 15032d45ba38SMiklos Szeredi num = outarg->size; 15042d45ba38SMiklos Szeredi if (outarg->offset > file_size) 15052d45ba38SMiklos Szeredi num = 0; 15062d45ba38SMiklos Szeredi else if (outarg->offset + num > file_size) 15072d45ba38SMiklos Szeredi num = file_size - outarg->offset; 15082d45ba38SMiklos Szeredi 15092d45ba38SMiklos Szeredi while (num) { 15102d45ba38SMiklos Szeredi struct page *page; 15112d45ba38SMiklos Szeredi unsigned int this_num; 15122d45ba38SMiklos Szeredi 15132d45ba38SMiklos Szeredi page = find_get_page(mapping, index); 15142d45ba38SMiklos Szeredi if (!page) 15152d45ba38SMiklos Szeredi break; 15162d45ba38SMiklos Szeredi 15172d45ba38SMiklos Szeredi this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset); 15182d45ba38SMiklos Szeredi req->pages[req->num_pages] = page; 15192d45ba38SMiklos Szeredi req->num_pages++; 15202d45ba38SMiklos Szeredi 15212d45ba38SMiklos Szeredi num -= this_num; 15222d45ba38SMiklos Szeredi total_len += this_num; 15232d45ba38SMiklos Szeredi } 15242d45ba38SMiklos Szeredi req->misc.retrieve_in.offset = outarg->offset; 15252d45ba38SMiklos Szeredi req->misc.retrieve_in.size = total_len; 15262d45ba38SMiklos Szeredi req->in.args[0].size = sizeof(req->misc.retrieve_in); 15272d45ba38SMiklos Szeredi req->in.args[0].value = &req->misc.retrieve_in; 15282d45ba38SMiklos Szeredi req->in.args[1].size = total_len; 15292d45ba38SMiklos Szeredi 15302d45ba38SMiklos Szeredi err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique); 15312d45ba38SMiklos Szeredi if (err) 15322d45ba38SMiklos Szeredi fuse_retrieve_end(fc, req); 15332d45ba38SMiklos Szeredi 15342d45ba38SMiklos Szeredi return err; 15352d45ba38SMiklos Szeredi } 15362d45ba38SMiklos Szeredi 15372d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, 15382d45ba38SMiklos Szeredi struct fuse_copy_state *cs) 15392d45ba38SMiklos Szeredi { 15402d45ba38SMiklos Szeredi struct fuse_notify_retrieve_out outarg; 15412d45ba38SMiklos Szeredi struct inode *inode; 15422d45ba38SMiklos Szeredi int err; 15432d45ba38SMiklos Szeredi 15442d45ba38SMiklos Szeredi err = -EINVAL; 15452d45ba38SMiklos Szeredi if (size != sizeof(outarg)) 15462d45ba38SMiklos Szeredi goto copy_finish; 15472d45ba38SMiklos Szeredi 15482d45ba38SMiklos Szeredi err = fuse_copy_one(cs, &outarg, sizeof(outarg)); 15492d45ba38SMiklos Szeredi if (err) 15502d45ba38SMiklos Szeredi goto copy_finish; 15512d45ba38SMiklos Szeredi 15522d45ba38SMiklos Szeredi fuse_copy_finish(cs); 15532d45ba38SMiklos Szeredi 15542d45ba38SMiklos Szeredi down_read(&fc->killsb); 15552d45ba38SMiklos Szeredi err = -ENOENT; 15562d45ba38SMiklos Szeredi if (fc->sb) { 15572d45ba38SMiklos Szeredi u64 nodeid = outarg.nodeid; 15582d45ba38SMiklos Szeredi 15592d45ba38SMiklos Szeredi inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid); 15602d45ba38SMiklos Szeredi if (inode) { 15612d45ba38SMiklos Szeredi err = fuse_retrieve(fc, inode, &outarg); 15622d45ba38SMiklos Szeredi iput(inode); 15632d45ba38SMiklos Szeredi } 15642d45ba38SMiklos Szeredi } 15652d45ba38SMiklos Szeredi up_read(&fc->killsb); 15662d45ba38SMiklos Szeredi 15672d45ba38SMiklos Szeredi return err; 15682d45ba38SMiklos Szeredi 15692d45ba38SMiklos Szeredi copy_finish: 15702d45ba38SMiklos Szeredi fuse_copy_finish(cs); 15712d45ba38SMiklos Szeredi return err; 15722d45ba38SMiklos Szeredi } 15732d45ba38SMiklos Szeredi 15748599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, 15758599396bSTejun Heo unsigned int size, struct fuse_copy_state *cs) 15768599396bSTejun Heo { 15778599396bSTejun Heo switch (code) { 157895668a69STejun Heo case FUSE_NOTIFY_POLL: 157995668a69STejun Heo return fuse_notify_poll(fc, size, cs); 158095668a69STejun Heo 15813b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_INODE: 15823b463ae0SJohn Muir return fuse_notify_inval_inode(fc, size, cs); 15833b463ae0SJohn Muir 15843b463ae0SJohn Muir case FUSE_NOTIFY_INVAL_ENTRY: 15853b463ae0SJohn Muir return fuse_notify_inval_entry(fc, size, cs); 15863b463ae0SJohn Muir 1587a1d75f25SMiklos Szeredi case FUSE_NOTIFY_STORE: 1588a1d75f25SMiklos Szeredi return fuse_notify_store(fc, size, cs); 1589a1d75f25SMiklos Szeredi 15902d45ba38SMiklos Szeredi case FUSE_NOTIFY_RETRIEVE: 15912d45ba38SMiklos Szeredi return fuse_notify_retrieve(fc, size, cs); 15922d45ba38SMiklos Szeredi 15938599396bSTejun Heo default: 1594f6d47a17SMiklos Szeredi fuse_copy_finish(cs); 15958599396bSTejun Heo return -EINVAL; 15968599396bSTejun Heo } 15978599396bSTejun Heo } 15988599396bSTejun Heo 1599334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */ 1600334f485dSMiklos Szeredi static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) 1601334f485dSMiklos Szeredi { 1602334f485dSMiklos Szeredi struct list_head *entry; 1603334f485dSMiklos Szeredi 1604334f485dSMiklos Szeredi list_for_each(entry, &fc->processing) { 1605334f485dSMiklos Szeredi struct fuse_req *req; 1606334f485dSMiklos Szeredi req = list_entry(entry, struct fuse_req, list); 1607a4d27e75SMiklos Szeredi if (req->in.h.unique == unique || req->intr_unique == unique) 1608334f485dSMiklos Szeredi return req; 1609334f485dSMiklos Szeredi } 1610334f485dSMiklos Szeredi return NULL; 1611334f485dSMiklos Szeredi } 1612334f485dSMiklos Szeredi 1613334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out, 1614334f485dSMiklos Szeredi unsigned nbytes) 1615334f485dSMiklos Szeredi { 1616334f485dSMiklos Szeredi unsigned reqsize = sizeof(struct fuse_out_header); 1617334f485dSMiklos Szeredi 1618334f485dSMiklos Szeredi if (out->h.error) 1619334f485dSMiklos Szeredi return nbytes != reqsize ? -EINVAL : 0; 1620334f485dSMiklos Szeredi 1621334f485dSMiklos Szeredi reqsize += len_args(out->numargs, out->args); 1622334f485dSMiklos Szeredi 1623334f485dSMiklos Szeredi if (reqsize < nbytes || (reqsize > nbytes && !out->argvar)) 1624334f485dSMiklos Szeredi return -EINVAL; 1625334f485dSMiklos Szeredi else if (reqsize > nbytes) { 1626334f485dSMiklos Szeredi struct fuse_arg *lastarg = &out->args[out->numargs-1]; 1627334f485dSMiklos Szeredi unsigned diffsize = reqsize - nbytes; 1628334f485dSMiklos Szeredi if (diffsize > lastarg->size) 1629334f485dSMiklos Szeredi return -EINVAL; 1630334f485dSMiklos Szeredi lastarg->size -= diffsize; 1631334f485dSMiklos Szeredi } 1632334f485dSMiklos Szeredi return fuse_copy_args(cs, out->numargs, out->argpages, out->args, 1633334f485dSMiklos Szeredi out->page_zeroing); 1634334f485dSMiklos Szeredi } 1635334f485dSMiklos Szeredi 1636334f485dSMiklos Szeredi /* 1637334f485dSMiklos Szeredi * Write a single reply to a request. First the header is copied from 1638334f485dSMiklos Szeredi * the write buffer. The request is then searched on the processing 1639334f485dSMiklos Szeredi * list by the unique ID found in the header. If found, then remove 1640334f485dSMiklos Szeredi * it from the list and copy the rest of the buffer to the request. 1641334f485dSMiklos Szeredi * The request is finished by calling request_end() 1642334f485dSMiklos Szeredi */ 1643dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_conn *fc, 1644dd3bb14fSMiklos Szeredi struct fuse_copy_state *cs, size_t nbytes) 1645334f485dSMiklos Szeredi { 1646334f485dSMiklos Szeredi int err; 1647334f485dSMiklos Szeredi struct fuse_req *req; 1648334f485dSMiklos Szeredi struct fuse_out_header oh; 1649334f485dSMiklos Szeredi 1650334f485dSMiklos Szeredi if (nbytes < sizeof(struct fuse_out_header)) 1651334f485dSMiklos Szeredi return -EINVAL; 1652334f485dSMiklos Szeredi 1653dd3bb14fSMiklos Szeredi err = fuse_copy_one(cs, &oh, sizeof(oh)); 1654334f485dSMiklos Szeredi if (err) 1655334f485dSMiklos Szeredi goto err_finish; 16568599396bSTejun Heo 1657334f485dSMiklos Szeredi err = -EINVAL; 16588599396bSTejun Heo if (oh.len != nbytes) 16598599396bSTejun Heo goto err_finish; 16608599396bSTejun Heo 16618599396bSTejun Heo /* 16628599396bSTejun Heo * Zero oh.unique indicates unsolicited notification message 16638599396bSTejun Heo * and error contains notification code. 16648599396bSTejun Heo */ 16658599396bSTejun Heo if (!oh.unique) { 1666dd3bb14fSMiklos Szeredi err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs); 16678599396bSTejun Heo return err ? err : nbytes; 16688599396bSTejun Heo } 16698599396bSTejun Heo 16708599396bSTejun Heo err = -EINVAL; 16718599396bSTejun Heo if (oh.error <= -1000 || oh.error > 0) 1672334f485dSMiklos Szeredi goto err_finish; 1673334f485dSMiklos Szeredi 1674d7133114SMiklos Szeredi spin_lock(&fc->lock); 167569a53bf2SMiklos Szeredi err = -ENOENT; 167669a53bf2SMiklos Szeredi if (!fc->connected) 167769a53bf2SMiklos Szeredi goto err_unlock; 167869a53bf2SMiklos Szeredi 1679334f485dSMiklos Szeredi req = request_find(fc, oh.unique); 1680334f485dSMiklos Szeredi if (!req) 1681334f485dSMiklos Szeredi goto err_unlock; 1682334f485dSMiklos Szeredi 1683f9a2842eSMiklos Szeredi if (req->aborted) { 1684d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1685dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1686d7133114SMiklos Szeredi spin_lock(&fc->lock); 1687222f1d69SMiklos Szeredi request_end(fc, req); 1688334f485dSMiklos Szeredi return -ENOENT; 1689334f485dSMiklos Szeredi } 1690a4d27e75SMiklos Szeredi /* Is it an interrupt reply? */ 1691a4d27e75SMiklos Szeredi if (req->intr_unique == oh.unique) { 1692a4d27e75SMiklos Szeredi err = -EINVAL; 1693a4d27e75SMiklos Szeredi if (nbytes != sizeof(struct fuse_out_header)) 1694a4d27e75SMiklos Szeredi goto err_unlock; 1695a4d27e75SMiklos Szeredi 1696a4d27e75SMiklos Szeredi if (oh.error == -ENOSYS) 1697a4d27e75SMiklos Szeredi fc->no_interrupt = 1; 1698a4d27e75SMiklos Szeredi else if (oh.error == -EAGAIN) 1699a4d27e75SMiklos Szeredi queue_interrupt(fc, req); 1700a4d27e75SMiklos Szeredi 1701a4d27e75SMiklos Szeredi spin_unlock(&fc->lock); 1702dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1703a4d27e75SMiklos Szeredi return nbytes; 1704a4d27e75SMiklos Szeredi } 1705a4d27e75SMiklos Szeredi 1706a4d27e75SMiklos Szeredi req->state = FUSE_REQ_WRITING; 1707d77a1d5bSMiklos Szeredi list_move(&req->list, &fc->io); 1708334f485dSMiklos Szeredi req->out.h = oh; 1709334f485dSMiklos Szeredi req->locked = 1; 1710dd3bb14fSMiklos Szeredi cs->req = req; 1711ce534fb0SMiklos Szeredi if (!req->out.page_replace) 1712ce534fb0SMiklos Szeredi cs->move_pages = 0; 1713d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1714334f485dSMiklos Szeredi 1715dd3bb14fSMiklos Szeredi err = copy_out_args(cs, &req->out, nbytes); 1716dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1717334f485dSMiklos Szeredi 1718d7133114SMiklos Szeredi spin_lock(&fc->lock); 1719334f485dSMiklos Szeredi req->locked = 0; 1720334f485dSMiklos Szeredi if (!err) { 1721f9a2842eSMiklos Szeredi if (req->aborted) 1722334f485dSMiklos Szeredi err = -ENOENT; 1723f9a2842eSMiklos Szeredi } else if (!req->aborted) 1724334f485dSMiklos Szeredi req->out.h.error = -EIO; 1725334f485dSMiklos Szeredi request_end(fc, req); 1726334f485dSMiklos Szeredi 1727334f485dSMiklos Szeredi return err ? err : nbytes; 1728334f485dSMiklos Szeredi 1729334f485dSMiklos Szeredi err_unlock: 1730d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1731334f485dSMiklos Szeredi err_finish: 1732dd3bb14fSMiklos Szeredi fuse_copy_finish(cs); 1733334f485dSMiklos Szeredi return err; 1734334f485dSMiklos Szeredi } 1735334f485dSMiklos Szeredi 1736dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, 1737dd3bb14fSMiklos Szeredi unsigned long nr_segs, loff_t pos) 1738dd3bb14fSMiklos Szeredi { 1739dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1740dd3bb14fSMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp); 1741dd3bb14fSMiklos Szeredi if (!fc) 1742dd3bb14fSMiklos Szeredi return -EPERM; 1743dd3bb14fSMiklos Szeredi 1744c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 0, iov, nr_segs); 1745dd3bb14fSMiklos Szeredi 1746dd3bb14fSMiklos Szeredi return fuse_dev_do_write(fc, &cs, iov_length(iov, nr_segs)); 1747dd3bb14fSMiklos Szeredi } 1748dd3bb14fSMiklos Szeredi 1749dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, 1750dd3bb14fSMiklos Szeredi struct file *out, loff_t *ppos, 1751dd3bb14fSMiklos Szeredi size_t len, unsigned int flags) 1752dd3bb14fSMiklos Szeredi { 1753dd3bb14fSMiklos Szeredi unsigned nbuf; 1754dd3bb14fSMiklos Szeredi unsigned idx; 1755dd3bb14fSMiklos Szeredi struct pipe_buffer *bufs; 1756dd3bb14fSMiklos Szeredi struct fuse_copy_state cs; 1757dd3bb14fSMiklos Szeredi struct fuse_conn *fc; 1758dd3bb14fSMiklos Szeredi size_t rem; 1759dd3bb14fSMiklos Szeredi ssize_t ret; 1760dd3bb14fSMiklos Szeredi 1761dd3bb14fSMiklos Szeredi fc = fuse_get_conn(out); 1762dd3bb14fSMiklos Szeredi if (!fc) 1763dd3bb14fSMiklos Szeredi return -EPERM; 1764dd3bb14fSMiklos Szeredi 1765dd3bb14fSMiklos Szeredi bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); 1766dd3bb14fSMiklos Szeredi if (!bufs) 1767dd3bb14fSMiklos Szeredi return -ENOMEM; 1768dd3bb14fSMiklos Szeredi 1769dd3bb14fSMiklos Szeredi pipe_lock(pipe); 1770dd3bb14fSMiklos Szeredi nbuf = 0; 1771dd3bb14fSMiklos Szeredi rem = 0; 1772dd3bb14fSMiklos Szeredi for (idx = 0; idx < pipe->nrbufs && rem < len; idx++) 1773dd3bb14fSMiklos Szeredi rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len; 1774dd3bb14fSMiklos Szeredi 1775dd3bb14fSMiklos Szeredi ret = -EINVAL; 1776dd3bb14fSMiklos Szeredi if (rem < len) { 1777dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 1778dd3bb14fSMiklos Szeredi goto out; 1779dd3bb14fSMiklos Szeredi } 1780dd3bb14fSMiklos Szeredi 1781dd3bb14fSMiklos Szeredi rem = len; 1782dd3bb14fSMiklos Szeredi while (rem) { 1783dd3bb14fSMiklos Szeredi struct pipe_buffer *ibuf; 1784dd3bb14fSMiklos Szeredi struct pipe_buffer *obuf; 1785dd3bb14fSMiklos Szeredi 1786dd3bb14fSMiklos Szeredi BUG_ON(nbuf >= pipe->buffers); 1787dd3bb14fSMiklos Szeredi BUG_ON(!pipe->nrbufs); 1788dd3bb14fSMiklos Szeredi ibuf = &pipe->bufs[pipe->curbuf]; 1789dd3bb14fSMiklos Szeredi obuf = &bufs[nbuf]; 1790dd3bb14fSMiklos Szeredi 1791dd3bb14fSMiklos Szeredi if (rem >= ibuf->len) { 1792dd3bb14fSMiklos Szeredi *obuf = *ibuf; 1793dd3bb14fSMiklos Szeredi ibuf->ops = NULL; 1794dd3bb14fSMiklos Szeredi pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1); 1795dd3bb14fSMiklos Szeredi pipe->nrbufs--; 1796dd3bb14fSMiklos Szeredi } else { 1797dd3bb14fSMiklos Szeredi ibuf->ops->get(pipe, ibuf); 1798dd3bb14fSMiklos Szeredi *obuf = *ibuf; 1799dd3bb14fSMiklos Szeredi obuf->flags &= ~PIPE_BUF_FLAG_GIFT; 1800dd3bb14fSMiklos Szeredi obuf->len = rem; 1801dd3bb14fSMiklos Szeredi ibuf->offset += obuf->len; 1802dd3bb14fSMiklos Szeredi ibuf->len -= obuf->len; 1803dd3bb14fSMiklos Szeredi } 1804dd3bb14fSMiklos Szeredi nbuf++; 1805dd3bb14fSMiklos Szeredi rem -= obuf->len; 1806dd3bb14fSMiklos Szeredi } 1807dd3bb14fSMiklos Szeredi pipe_unlock(pipe); 1808dd3bb14fSMiklos Szeredi 1809c3021629SMiklos Szeredi fuse_copy_init(&cs, fc, 0, NULL, nbuf); 1810dd3bb14fSMiklos Szeredi cs.pipebufs = bufs; 1811dd3bb14fSMiklos Szeredi cs.pipe = pipe; 1812dd3bb14fSMiklos Szeredi 1813ce534fb0SMiklos Szeredi if (flags & SPLICE_F_MOVE) 1814ce534fb0SMiklos Szeredi cs.move_pages = 1; 1815ce534fb0SMiklos Szeredi 1816dd3bb14fSMiklos Szeredi ret = fuse_dev_do_write(fc, &cs, len); 1817dd3bb14fSMiklos Szeredi 1818dd3bb14fSMiklos Szeredi for (idx = 0; idx < nbuf; idx++) { 1819dd3bb14fSMiklos Szeredi struct pipe_buffer *buf = &bufs[idx]; 1820dd3bb14fSMiklos Szeredi buf->ops->release(pipe, buf); 1821dd3bb14fSMiklos Szeredi } 1822dd3bb14fSMiklos Szeredi out: 1823dd3bb14fSMiklos Szeredi kfree(bufs); 1824dd3bb14fSMiklos Szeredi return ret; 1825dd3bb14fSMiklos Szeredi } 1826dd3bb14fSMiklos Szeredi 1827334f485dSMiklos Szeredi static unsigned fuse_dev_poll(struct file *file, poll_table *wait) 1828334f485dSMiklos Szeredi { 1829334f485dSMiklos Szeredi unsigned mask = POLLOUT | POLLWRNORM; 18307025d9adSMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 1831334f485dSMiklos Szeredi if (!fc) 18327025d9adSMiklos Szeredi return POLLERR; 1833334f485dSMiklos Szeredi 1834334f485dSMiklos Szeredi poll_wait(file, &fc->waitq, wait); 1835334f485dSMiklos Szeredi 1836d7133114SMiklos Szeredi spin_lock(&fc->lock); 18377025d9adSMiklos Szeredi if (!fc->connected) 18387025d9adSMiklos Szeredi mask = POLLERR; 1839a4d27e75SMiklos Szeredi else if (request_pending(fc)) 1840334f485dSMiklos Szeredi mask |= POLLIN | POLLRDNORM; 1841d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1842334f485dSMiklos Szeredi 1843334f485dSMiklos Szeredi return mask; 1844334f485dSMiklos Szeredi } 1845334f485dSMiklos Szeredi 184669a53bf2SMiklos Szeredi /* 184769a53bf2SMiklos Szeredi * Abort all requests on the given list (pending or processing) 184869a53bf2SMiklos Szeredi * 1849d7133114SMiklos Szeredi * This function releases and reacquires fc->lock 185069a53bf2SMiklos Szeredi */ 1851334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head) 1852b9ca67b2SMiklos Szeredi __releases(fc->lock) 1853b9ca67b2SMiklos Szeredi __acquires(fc->lock) 1854334f485dSMiklos Szeredi { 1855334f485dSMiklos Szeredi while (!list_empty(head)) { 1856334f485dSMiklos Szeredi struct fuse_req *req; 1857334f485dSMiklos Szeredi req = list_entry(head->next, struct fuse_req, list); 1858334f485dSMiklos Szeredi req->out.h.error = -ECONNABORTED; 1859334f485dSMiklos Szeredi request_end(fc, req); 1860d7133114SMiklos Szeredi spin_lock(&fc->lock); 1861334f485dSMiklos Szeredi } 1862334f485dSMiklos Szeredi } 1863334f485dSMiklos Szeredi 186469a53bf2SMiklos Szeredi /* 186569a53bf2SMiklos Szeredi * Abort requests under I/O 186669a53bf2SMiklos Szeredi * 1867f9a2842eSMiklos Szeredi * The requests are set to aborted and finished, and the request 186869a53bf2SMiklos Szeredi * waiter is woken up. This will make request_wait_answer() wait 186969a53bf2SMiklos Szeredi * until the request is unlocked and then return. 187064c6d8edSMiklos Szeredi * 187164c6d8edSMiklos Szeredi * If the request is asynchronous, then the end function needs to be 187264c6d8edSMiklos Szeredi * called after waiting for the request to be unlocked (if it was 187364c6d8edSMiklos Szeredi * locked). 187469a53bf2SMiklos Szeredi */ 187569a53bf2SMiklos Szeredi static void end_io_requests(struct fuse_conn *fc) 1876b9ca67b2SMiklos Szeredi __releases(fc->lock) 1877b9ca67b2SMiklos Szeredi __acquires(fc->lock) 187869a53bf2SMiklos Szeredi { 187969a53bf2SMiklos Szeredi while (!list_empty(&fc->io)) { 188064c6d8edSMiklos Szeredi struct fuse_req *req = 188164c6d8edSMiklos Szeredi list_entry(fc->io.next, struct fuse_req, list); 188264c6d8edSMiklos Szeredi void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; 188364c6d8edSMiklos Szeredi 1884f9a2842eSMiklos Szeredi req->aborted = 1; 188569a53bf2SMiklos Szeredi req->out.h.error = -ECONNABORTED; 188669a53bf2SMiklos Szeredi req->state = FUSE_REQ_FINISHED; 188769a53bf2SMiklos Szeredi list_del_init(&req->list); 188869a53bf2SMiklos Szeredi wake_up(&req->waitq); 188964c6d8edSMiklos Szeredi if (end) { 189064c6d8edSMiklos Szeredi req->end = NULL; 189164c6d8edSMiklos Szeredi __fuse_get_request(req); 1892d7133114SMiklos Szeredi spin_unlock(&fc->lock); 189364c6d8edSMiklos Szeredi wait_event(req->waitq, !req->locked); 189464c6d8edSMiklos Szeredi end(fc, req); 1895e9bb09ddSTejun Heo fuse_put_request(fc, req); 1896d7133114SMiklos Szeredi spin_lock(&fc->lock); 189764c6d8edSMiklos Szeredi } 189869a53bf2SMiklos Szeredi } 189969a53bf2SMiklos Szeredi } 190069a53bf2SMiklos Szeredi 1901595afaf9SMiklos Szeredi static void end_queued_requests(struct fuse_conn *fc) 1902b9ca67b2SMiklos Szeredi __releases(fc->lock) 1903b9ca67b2SMiklos Szeredi __acquires(fc->lock) 1904595afaf9SMiklos Szeredi { 1905595afaf9SMiklos Szeredi fc->max_background = UINT_MAX; 1906595afaf9SMiklos Szeredi flush_bg_queue(fc); 1907595afaf9SMiklos Szeredi end_requests(fc, &fc->pending); 1908595afaf9SMiklos Szeredi end_requests(fc, &fc->processing); 190907e77dcaSMiklos Szeredi while (forget_pending(fc)) 191002c048b9SMiklos Szeredi kfree(dequeue_forget(fc, 1, NULL)); 1911595afaf9SMiklos Szeredi } 1912595afaf9SMiklos Szeredi 191369a53bf2SMiklos Szeredi /* 191469a53bf2SMiklos Szeredi * Abort all requests. 191569a53bf2SMiklos Szeredi * 191669a53bf2SMiklos Szeredi * Emergency exit in case of a malicious or accidental deadlock, or 191769a53bf2SMiklos Szeredi * just a hung filesystem. 191869a53bf2SMiklos Szeredi * 191969a53bf2SMiklos Szeredi * The same effect is usually achievable through killing the 192069a53bf2SMiklos Szeredi * filesystem daemon and all users of the filesystem. The exception 192169a53bf2SMiklos Szeredi * is the combination of an asynchronous request and the tricky 192269a53bf2SMiklos Szeredi * deadlock (see Documentation/filesystems/fuse.txt). 192369a53bf2SMiklos Szeredi * 192469a53bf2SMiklos Szeredi * During the aborting, progression of requests from the pending and 192569a53bf2SMiklos Szeredi * processing lists onto the io list, and progression of new requests 192669a53bf2SMiklos Szeredi * onto the pending list is prevented by req->connected being false. 192769a53bf2SMiklos Szeredi * 192869a53bf2SMiklos Szeredi * Progression of requests under I/O to the processing list is 1929f9a2842eSMiklos Szeredi * prevented by the req->aborted flag being true for these requests. 1930f9a2842eSMiklos Szeredi * For this reason requests on the io list must be aborted first. 193169a53bf2SMiklos Szeredi */ 193269a53bf2SMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc) 193369a53bf2SMiklos Szeredi { 1934d7133114SMiklos Szeredi spin_lock(&fc->lock); 193569a53bf2SMiklos Szeredi if (fc->connected) { 193669a53bf2SMiklos Szeredi fc->connected = 0; 193751eb01e7SMiklos Szeredi fc->blocked = 0; 193869a53bf2SMiklos Szeredi end_io_requests(fc); 1939595afaf9SMiklos Szeredi end_queued_requests(fc); 194069a53bf2SMiklos Szeredi wake_up_all(&fc->waitq); 194151eb01e7SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 1942385a17bfSJeff Dike kill_fasync(&fc->fasync, SIGIO, POLL_IN); 194369a53bf2SMiklos Szeredi } 1944d7133114SMiklos Szeredi spin_unlock(&fc->lock); 194569a53bf2SMiklos Szeredi } 194608cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn); 194769a53bf2SMiklos Szeredi 194808cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file) 1949334f485dSMiklos Szeredi { 19500720b315SMiklos Szeredi struct fuse_conn *fc = fuse_get_conn(file); 1951334f485dSMiklos Szeredi if (fc) { 1952d7133114SMiklos Szeredi spin_lock(&fc->lock); 19531e9a4ed9SMiklos Szeredi fc->connected = 0; 1954595afaf9SMiklos Szeredi fc->blocked = 0; 1955595afaf9SMiklos Szeredi end_queued_requests(fc); 1956595afaf9SMiklos Szeredi wake_up_all(&fc->blocked_waitq); 1957d7133114SMiklos Szeredi spin_unlock(&fc->lock); 1958bafa9654SMiklos Szeredi fuse_conn_put(fc); 1959385a17bfSJeff Dike } 1960f543f253SMiklos Szeredi 1961334f485dSMiklos Szeredi return 0; 1962334f485dSMiklos Szeredi } 196308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release); 1964334f485dSMiklos Szeredi 1965385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on) 1966385a17bfSJeff Dike { 1967385a17bfSJeff Dike struct fuse_conn *fc = fuse_get_conn(file); 1968385a17bfSJeff Dike if (!fc) 1969a87046d8SMiklos Szeredi return -EPERM; 1970385a17bfSJeff Dike 1971385a17bfSJeff Dike /* No locking - fasync_helper does its own locking */ 1972385a17bfSJeff Dike return fasync_helper(fd, file, on, &fc->fasync); 1973385a17bfSJeff Dike } 1974385a17bfSJeff Dike 19754b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = { 1976334f485dSMiklos Szeredi .owner = THIS_MODULE, 1977334f485dSMiklos Szeredi .llseek = no_llseek, 1978ee0b3e67SBadari Pulavarty .read = do_sync_read, 1979ee0b3e67SBadari Pulavarty .aio_read = fuse_dev_read, 1980c3021629SMiklos Szeredi .splice_read = fuse_dev_splice_read, 1981ee0b3e67SBadari Pulavarty .write = do_sync_write, 1982ee0b3e67SBadari Pulavarty .aio_write = fuse_dev_write, 1983dd3bb14fSMiklos Szeredi .splice_write = fuse_dev_splice_write, 1984334f485dSMiklos Szeredi .poll = fuse_dev_poll, 1985334f485dSMiklos Szeredi .release = fuse_dev_release, 1986385a17bfSJeff Dike .fasync = fuse_dev_fasync, 1987334f485dSMiklos Szeredi }; 198808cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations); 1989334f485dSMiklos Szeredi 1990334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = { 1991334f485dSMiklos Szeredi .minor = FUSE_MINOR, 1992334f485dSMiklos Szeredi .name = "fuse", 1993334f485dSMiklos Szeredi .fops = &fuse_dev_operations, 1994334f485dSMiklos Szeredi }; 1995334f485dSMiklos Szeredi 1996334f485dSMiklos Szeredi int __init fuse_dev_init(void) 1997334f485dSMiklos Szeredi { 1998334f485dSMiklos Szeredi int err = -ENOMEM; 1999334f485dSMiklos Szeredi fuse_req_cachep = kmem_cache_create("fuse_request", 2000334f485dSMiklos Szeredi sizeof(struct fuse_req), 200120c2df83SPaul Mundt 0, 0, NULL); 2002334f485dSMiklos Szeredi if (!fuse_req_cachep) 2003334f485dSMiklos Szeredi goto out; 2004334f485dSMiklos Szeredi 2005334f485dSMiklos Szeredi err = misc_register(&fuse_miscdevice); 2006334f485dSMiklos Szeredi if (err) 2007334f485dSMiklos Szeredi goto out_cache_clean; 2008334f485dSMiklos Szeredi 2009334f485dSMiklos Szeredi return 0; 2010334f485dSMiklos Szeredi 2011334f485dSMiklos Szeredi out_cache_clean: 2012334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2013334f485dSMiklos Szeredi out: 2014334f485dSMiklos Szeredi return err; 2015334f485dSMiklos Szeredi } 2016334f485dSMiklos Szeredi 2017334f485dSMiklos Szeredi void fuse_dev_cleanup(void) 2018334f485dSMiklos Szeredi { 2019334f485dSMiklos Szeredi misc_deregister(&fuse_miscdevice); 2020334f485dSMiklos Szeredi kmem_cache_destroy(fuse_req_cachep); 2021334f485dSMiklos Szeredi } 2022