xref: /openbmc/linux/fs/fuse/dev.c (revision eb98e3bd)
1334f485dSMiklos Szeredi /*
2334f485dSMiklos Szeredi   FUSE: Filesystem in Userspace
31729a16cSMiklos Szeredi   Copyright (C) 2001-2008  Miklos Szeredi <miklos@szeredi.hu>
4334f485dSMiklos Szeredi 
5334f485dSMiklos Szeredi   This program can be distributed under the terms of the GNU GPL.
6334f485dSMiklos Szeredi   See the file COPYING.
7334f485dSMiklos Szeredi */
8334f485dSMiklos Szeredi 
9334f485dSMiklos Szeredi #include "fuse_i.h"
10334f485dSMiklos Szeredi 
11334f485dSMiklos Szeredi #include <linux/init.h>
12334f485dSMiklos Szeredi #include <linux/module.h>
13334f485dSMiklos Szeredi #include <linux/poll.h>
14174cd4b1SIngo Molnar #include <linux/sched/signal.h>
15334f485dSMiklos Szeredi #include <linux/uio.h>
16334f485dSMiklos Szeredi #include <linux/miscdevice.h>
17334f485dSMiklos Szeredi #include <linux/pagemap.h>
18334f485dSMiklos Szeredi #include <linux/file.h>
19334f485dSMiklos Szeredi #include <linux/slab.h>
20dd3bb14fSMiklos Szeredi #include <linux/pipe_fs_i.h>
21ce534fb0SMiklos Szeredi #include <linux/swap.h>
22ce534fb0SMiklos Szeredi #include <linux/splice.h>
230b6e9ea0SSeth Forshee #include <linux/sched.h>
24334f485dSMiklos Szeredi 
25334f485dSMiklos Szeredi MODULE_ALIAS_MISCDEV(FUSE_MINOR);
26578454ffSKay Sievers MODULE_ALIAS("devname:fuse");
27334f485dSMiklos Szeredi 
28c59fd85eSKirill Tkhai /* Ordinary requests have even IDs, while interrupts IDs are odd */
29c59fd85eSKirill Tkhai #define FUSE_INT_REQ_BIT (1ULL << 0)
30c59fd85eSKirill Tkhai #define FUSE_REQ_ID_STEP (1ULL << 1)
31c59fd85eSKirill Tkhai 
32e18b890bSChristoph Lameter static struct kmem_cache *fuse_req_cachep;
33334f485dSMiklos Szeredi 
34cc080e9eSMiklos Szeredi static struct fuse_dev *fuse_get_dev(struct file *file)
35334f485dSMiklos Szeredi {
360720b315SMiklos Szeredi 	/*
370720b315SMiklos Szeredi 	 * Lockless access is OK, because file->private data is set
380720b315SMiklos Szeredi 	 * once during mount and is valid until the file is released.
390720b315SMiklos Szeredi 	 */
406aa7de05SMark Rutland 	return READ_ONCE(file->private_data);
41334f485dSMiklos Szeredi }
42334f485dSMiklos Szeredi 
434250c066SMaxim Patlasov static void fuse_request_init(struct fuse_req *req, struct page **pages,
44b2430d75SMaxim Patlasov 			      struct fuse_page_desc *page_descs,
454250c066SMaxim Patlasov 			      unsigned npages)
46334f485dSMiklos Szeredi {
47334f485dSMiklos Szeredi 	INIT_LIST_HEAD(&req->list);
48a4d27e75SMiklos Szeredi 	INIT_LIST_HEAD(&req->intr_entry);
49334f485dSMiklos Szeredi 	init_waitqueue_head(&req->waitq);
50ec99f6d3SElena Reshetova 	refcount_set(&req->count, 1);
514250c066SMaxim Patlasov 	req->pages = pages;
52b2430d75SMaxim Patlasov 	req->page_descs = page_descs;
534250c066SMaxim Patlasov 	req->max_pages = npages;
5433e14b4dSMiklos Szeredi 	__set_bit(FR_PENDING, &req->flags);
55334f485dSMiklos Szeredi }
56334f485dSMiklos Szeredi 
57e52a8250SMiklos Szeredi static struct page **fuse_req_pages_alloc(unsigned int npages, gfp_t flags,
58e52a8250SMiklos Szeredi 					  struct fuse_page_desc **desc)
59e52a8250SMiklos Szeredi {
60e52a8250SMiklos Szeredi 	struct page **pages;
61e52a8250SMiklos Szeredi 
62e52a8250SMiklos Szeredi 	pages = kzalloc(npages * (sizeof(struct page *) +
63e52a8250SMiklos Szeredi 				  sizeof(struct fuse_page_desc)), flags);
64e52a8250SMiklos Szeredi 	*desc = (void *) pages + npages * sizeof(struct page *);
65e52a8250SMiklos Szeredi 
66e52a8250SMiklos Szeredi 	return pages;
67e52a8250SMiklos Szeredi }
68e52a8250SMiklos Szeredi 
694250c066SMaxim Patlasov static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags)
70334f485dSMiklos Szeredi {
718a7aa286SMiklos Szeredi 	struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags);
724250c066SMaxim Patlasov 	if (req) {
738a7aa286SMiklos Szeredi 		struct page **pages = NULL;
748a7aa286SMiklos Szeredi 		struct fuse_page_desc *page_descs = NULL;
754250c066SMaxim Patlasov 
765da784ccSConstantine Shulyupin 		WARN_ON(npages > FUSE_MAX_MAX_PAGES);
778a7aa286SMiklos Szeredi 		if (npages > FUSE_REQ_INLINE_PAGES) {
78e52a8250SMiklos Szeredi 			pages = fuse_req_pages_alloc(npages, flags,
79e52a8250SMiklos Szeredi 						     &page_descs);
808a7aa286SMiklos Szeredi 			if (!pages) {
814250c066SMaxim Patlasov 				kmem_cache_free(fuse_req_cachep, req);
824250c066SMaxim Patlasov 				return NULL;
834250c066SMaxim Patlasov 			}
848a7aa286SMiklos Szeredi 		} else if (npages) {
858a7aa286SMiklos Szeredi 			pages = req->inline_pages;
868a7aa286SMiklos Szeredi 			page_descs = req->inline_page_descs;
878a7aa286SMiklos Szeredi 		}
884250c066SMaxim Patlasov 
89b2430d75SMaxim Patlasov 		fuse_request_init(req, pages, page_descs, npages);
904250c066SMaxim Patlasov 	}
91334f485dSMiklos Szeredi 	return req;
92334f485dSMiklos Szeredi }
934250c066SMaxim Patlasov 
944250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc(unsigned npages)
954250c066SMaxim Patlasov {
964250c066SMaxim Patlasov 	return __fuse_request_alloc(npages, GFP_KERNEL);
974250c066SMaxim Patlasov }
9808cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_alloc);
99334f485dSMiklos Szeredi 
1004250c066SMaxim Patlasov struct fuse_req *fuse_request_alloc_nofs(unsigned npages)
1013be5a52bSMiklos Szeredi {
1024250c066SMaxim Patlasov 	return __fuse_request_alloc(npages, GFP_NOFS);
1033be5a52bSMiklos Szeredi }
1043be5a52bSMiklos Szeredi 
105e52a8250SMiklos Szeredi static void fuse_req_pages_free(struct fuse_req *req)
106334f485dSMiklos Szeredi {
1078a7aa286SMiklos Szeredi 	if (req->pages != req->inline_pages)
1084250c066SMaxim Patlasov 		kfree(req->pages);
109e52a8250SMiklos Szeredi }
1108a7aa286SMiklos Szeredi 
111e52a8250SMiklos Szeredi bool fuse_req_realloc_pages(struct fuse_conn *fc, struct fuse_req *req,
112e52a8250SMiklos Szeredi 			    gfp_t flags)
113e52a8250SMiklos Szeredi {
114e52a8250SMiklos Szeredi 	struct page **pages;
115e52a8250SMiklos Szeredi 	struct fuse_page_desc *page_descs;
116e52a8250SMiklos Szeredi 	unsigned int npages = min_t(unsigned int,
117e52a8250SMiklos Szeredi 				    max_t(unsigned int, req->max_pages * 2,
118e52a8250SMiklos Szeredi 					  FUSE_DEFAULT_MAX_PAGES_PER_REQ),
119e52a8250SMiklos Szeredi 				    fc->max_pages);
120e52a8250SMiklos Szeredi 	WARN_ON(npages <= req->max_pages);
121e52a8250SMiklos Szeredi 
122e52a8250SMiklos Szeredi 	pages = fuse_req_pages_alloc(npages, flags, &page_descs);
123e52a8250SMiklos Szeredi 	if (!pages)
124e52a8250SMiklos Szeredi 		return false;
125e52a8250SMiklos Szeredi 
126e52a8250SMiklos Szeredi 	memcpy(pages, req->pages, sizeof(struct page *) * req->max_pages);
127e52a8250SMiklos Szeredi 	memcpy(page_descs, req->page_descs,
128e52a8250SMiklos Szeredi 	       sizeof(struct fuse_page_desc) * req->max_pages);
129e52a8250SMiklos Szeredi 	fuse_req_pages_free(req);
130e52a8250SMiklos Szeredi 	req->pages = pages;
131e52a8250SMiklos Szeredi 	req->page_descs = page_descs;
132e52a8250SMiklos Szeredi 	req->max_pages = npages;
133e52a8250SMiklos Szeredi 
134e52a8250SMiklos Szeredi 	return true;
135e52a8250SMiklos Szeredi }
136e52a8250SMiklos Szeredi 
137e52a8250SMiklos Szeredi void fuse_request_free(struct fuse_req *req)
138e52a8250SMiklos Szeredi {
139e52a8250SMiklos Szeredi 	fuse_req_pages_free(req);
140334f485dSMiklos Szeredi 	kmem_cache_free(fuse_req_cachep, req);
141334f485dSMiklos Szeredi }
142334f485dSMiklos Szeredi 
14336cf66edSMaxim Patlasov void __fuse_get_request(struct fuse_req *req)
144334f485dSMiklos Szeredi {
145ec99f6d3SElena Reshetova 	refcount_inc(&req->count);
146334f485dSMiklos Szeredi }
147334f485dSMiklos Szeredi 
148334f485dSMiklos Szeredi /* Must be called with > 1 refcount */
149334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req)
150334f485dSMiklos Szeredi {
151ec99f6d3SElena Reshetova 	refcount_dec(&req->count);
152334f485dSMiklos Szeredi }
153334f485dSMiklos Szeredi 
1549759bd51SMiklos Szeredi void fuse_set_initialized(struct fuse_conn *fc)
1559759bd51SMiklos Szeredi {
1569759bd51SMiklos Szeredi 	/* Make sure stores before this are seen on another CPU */
1579759bd51SMiklos Szeredi 	smp_wmb();
1589759bd51SMiklos Szeredi 	fc->initialized = 1;
1599759bd51SMiklos Szeredi }
1609759bd51SMiklos Szeredi 
1610aada884SMaxim Patlasov static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
1620aada884SMaxim Patlasov {
1630aada884SMaxim Patlasov 	return !fc->initialized || (for_background && fc->blocked);
1640aada884SMaxim Patlasov }
1650aada884SMaxim Patlasov 
166b8f95e5dSMiklos Szeredi static void fuse_drop_waiting(struct fuse_conn *fc)
167b8f95e5dSMiklos Szeredi {
1682d84a2d1SMiklos Szeredi 	/*
1692d84a2d1SMiklos Szeredi 	 * lockess check of fc->connected is okay, because atomic_dec_and_test()
1702d84a2d1SMiklos Szeredi 	 * provides a memory barrier mached with the one in fuse_wait_aborted()
1712d84a2d1SMiklos Szeredi 	 * to ensure no wake-up is missed.
1722d84a2d1SMiklos Szeredi 	 */
1732d84a2d1SMiklos Szeredi 	if (atomic_dec_and_test(&fc->num_waiting) &&
1742d84a2d1SMiklos Szeredi 	    !READ_ONCE(fc->connected)) {
175b8f95e5dSMiklos Szeredi 		/* wake up aborters */
176b8f95e5dSMiklos Szeredi 		wake_up_all(&fc->blocked_waitq);
177b8f95e5dSMiklos Szeredi 	}
178b8f95e5dSMiklos Szeredi }
179b8f95e5dSMiklos Szeredi 
1808b41e671SMaxim Patlasov static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages,
1818b41e671SMaxim Patlasov 				       bool for_background)
182334f485dSMiklos Szeredi {
18308a53cdcSMiklos Szeredi 	struct fuse_req *req;
1840aada884SMaxim Patlasov 	int err;
1850aada884SMaxim Patlasov 	atomic_inc(&fc->num_waiting);
1860aada884SMaxim Patlasov 
1870aada884SMaxim Patlasov 	if (fuse_block_alloc(fc, for_background)) {
1889bc5dddaSMiklos Szeredi 		err = -EINTR;
1897d3a07fcSAl Viro 		if (wait_event_killable_exclusive(fc->blocked_waitq,
1907d3a07fcSAl Viro 				!fuse_block_alloc(fc, for_background)))
1919bc5dddaSMiklos Szeredi 			goto out;
1920aada884SMaxim Patlasov 	}
1939759bd51SMiklos Szeredi 	/* Matches smp_wmb() in fuse_set_initialized() */
1949759bd51SMiklos Szeredi 	smp_rmb();
19508a53cdcSMiklos Szeredi 
19651eb01e7SMiklos Szeredi 	err = -ENOTCONN;
19751eb01e7SMiklos Szeredi 	if (!fc->connected)
19851eb01e7SMiklos Szeredi 		goto out;
19951eb01e7SMiklos Szeredi 
200de155226SMiklos Szeredi 	err = -ECONNREFUSED;
201de155226SMiklos Szeredi 	if (fc->conn_error)
202de155226SMiklos Szeredi 		goto out;
203de155226SMiklos Szeredi 
204b111c8c0SMaxim Patlasov 	req = fuse_request_alloc(npages);
2059bc5dddaSMiklos Szeredi 	err = -ENOMEM;
206722d2beaSMaxim Patlasov 	if (!req) {
207722d2beaSMaxim Patlasov 		if (for_background)
208722d2beaSMaxim Patlasov 			wake_up(&fc->blocked_waitq);
2099bc5dddaSMiklos Szeredi 		goto out;
210722d2beaSMaxim Patlasov 	}
211334f485dSMiklos Szeredi 
2128cb08329SEric W. Biederman 	req->in.h.uid = from_kuid(fc->user_ns, current_fsuid());
2138cb08329SEric W. Biederman 	req->in.h.gid = from_kgid(fc->user_ns, current_fsgid());
214c9582eb0SEric W. Biederman 	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
215c9582eb0SEric W. Biederman 
216825d6d33SMiklos Szeredi 	__set_bit(FR_WAITING, &req->flags);
217825d6d33SMiklos Szeredi 	if (for_background)
218825d6d33SMiklos Szeredi 		__set_bit(FR_BACKGROUND, &req->flags);
219825d6d33SMiklos Szeredi 
220c9582eb0SEric W. Biederman 	if (unlikely(req->in.h.uid == ((uid_t)-1) ||
221c9582eb0SEric W. Biederman 		     req->in.h.gid == ((gid_t)-1))) {
222c9582eb0SEric W. Biederman 		fuse_put_request(fc, req);
223c9582eb0SEric W. Biederman 		return ERR_PTR(-EOVERFLOW);
224c9582eb0SEric W. Biederman 	}
225334f485dSMiklos Szeredi 	return req;
2269bc5dddaSMiklos Szeredi 
2279bc5dddaSMiklos Szeredi  out:
228b8f95e5dSMiklos Szeredi 	fuse_drop_waiting(fc);
2299bc5dddaSMiklos Szeredi 	return ERR_PTR(err);
230334f485dSMiklos Szeredi }
2318b41e671SMaxim Patlasov 
2328b41e671SMaxim Patlasov struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages)
2338b41e671SMaxim Patlasov {
2348b41e671SMaxim Patlasov 	return __fuse_get_req(fc, npages, false);
2358b41e671SMaxim Patlasov }
23608cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_get_req);
237334f485dSMiklos Szeredi 
2388b41e671SMaxim Patlasov struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc,
2398b41e671SMaxim Patlasov 					     unsigned npages)
2408b41e671SMaxim Patlasov {
2418b41e671SMaxim Patlasov 	return __fuse_get_req(fc, npages, true);
2428b41e671SMaxim Patlasov }
2438b41e671SMaxim Patlasov EXPORT_SYMBOL_GPL(fuse_get_req_for_background);
2448b41e671SMaxim Patlasov 
24533649c91SMiklos Szeredi /*
24633649c91SMiklos Szeredi  * Return request in fuse_file->reserved_req.  However that may
24733649c91SMiklos Szeredi  * currently be in use.  If that is the case, wait for it to become
24833649c91SMiklos Szeredi  * available.
24933649c91SMiklos Szeredi  */
25033649c91SMiklos Szeredi static struct fuse_req *get_reserved_req(struct fuse_conn *fc,
25133649c91SMiklos Szeredi 					 struct file *file)
25233649c91SMiklos Szeredi {
25333649c91SMiklos Szeredi 	struct fuse_req *req = NULL;
2546b675738SKirill Tkhai 	struct fuse_inode *fi = get_fuse_inode(file_inode(file));
25533649c91SMiklos Szeredi 	struct fuse_file *ff = file->private_data;
25633649c91SMiklos Szeredi 
25733649c91SMiklos Szeredi 	do {
258de5e3decSMiklos Szeredi 		wait_event(fc->reserved_req_waitq, ff->reserved_req);
2596b675738SKirill Tkhai 		spin_lock(&fi->lock);
26033649c91SMiklos Szeredi 		if (ff->reserved_req) {
26133649c91SMiklos Szeredi 			req = ff->reserved_req;
26233649c91SMiklos Szeredi 			ff->reserved_req = NULL;
263cb0942b8SAl Viro 			req->stolen_file = get_file(file);
26433649c91SMiklos Szeredi 		}
2656b675738SKirill Tkhai 		spin_unlock(&fi->lock);
26633649c91SMiklos Szeredi 	} while (!req);
26733649c91SMiklos Szeredi 
26833649c91SMiklos Szeredi 	return req;
26933649c91SMiklos Szeredi }
27033649c91SMiklos Szeredi 
27133649c91SMiklos Szeredi /*
27233649c91SMiklos Szeredi  * Put stolen request back into fuse_file->reserved_req
27333649c91SMiklos Szeredi  */
27433649c91SMiklos Szeredi static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
27533649c91SMiklos Szeredi {
27633649c91SMiklos Szeredi 	struct file *file = req->stolen_file;
2776b675738SKirill Tkhai 	struct fuse_inode *fi = get_fuse_inode(file_inode(file));
27833649c91SMiklos Szeredi 	struct fuse_file *ff = file->private_data;
27933649c91SMiklos Szeredi 
2808a7aa286SMiklos Szeredi 	WARN_ON(req->max_pages);
2816b675738SKirill Tkhai 	spin_lock(&fi->lock);
2828a7aa286SMiklos Szeredi 	memset(req, 0, sizeof(*req));
2838a7aa286SMiklos Szeredi 	fuse_request_init(req, NULL, NULL, 0);
28433649c91SMiklos Szeredi 	BUG_ON(ff->reserved_req);
28533649c91SMiklos Szeredi 	ff->reserved_req = req;
286de5e3decSMiklos Szeredi 	wake_up_all(&fc->reserved_req_waitq);
2876b675738SKirill Tkhai 	spin_unlock(&fi->lock);
28833649c91SMiklos Szeredi 	fput(file);
28933649c91SMiklos Szeredi }
29033649c91SMiklos Szeredi 
29133649c91SMiklos Szeredi /*
29233649c91SMiklos Szeredi  * Gets a requests for a file operation, always succeeds
29333649c91SMiklos Szeredi  *
29433649c91SMiklos Szeredi  * This is used for sending the FLUSH request, which must get to
29533649c91SMiklos Szeredi  * userspace, due to POSIX locks which may need to be unlocked.
29633649c91SMiklos Szeredi  *
29733649c91SMiklos Szeredi  * If allocation fails due to OOM, use the reserved request in
29833649c91SMiklos Szeredi  * fuse_file.
29933649c91SMiklos Szeredi  *
30033649c91SMiklos Szeredi  * This is very unlikely to deadlock accidentally, since the
30133649c91SMiklos Szeredi  * filesystem should not have it's own file open.  If deadlock is
30233649c91SMiklos Szeredi  * intentional, it can still be broken by "aborting" the filesystem.
30333649c91SMiklos Szeredi  */
304b111c8c0SMaxim Patlasov struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc,
305b111c8c0SMaxim Patlasov 					     struct file *file)
30633649c91SMiklos Szeredi {
30733649c91SMiklos Szeredi 	struct fuse_req *req;
30833649c91SMiklos Szeredi 
30933649c91SMiklos Szeredi 	atomic_inc(&fc->num_waiting);
3100aada884SMaxim Patlasov 	wait_event(fc->blocked_waitq, fc->initialized);
3119759bd51SMiklos Szeredi 	/* Matches smp_wmb() in fuse_set_initialized() */
3129759bd51SMiklos Szeredi 	smp_rmb();
313b111c8c0SMaxim Patlasov 	req = fuse_request_alloc(0);
31433649c91SMiklos Szeredi 	if (!req)
31533649c91SMiklos Szeredi 		req = get_reserved_req(fc, file);
31633649c91SMiklos Szeredi 
3178cb08329SEric W. Biederman 	req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
3188cb08329SEric W. Biederman 	req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid());
319c9582eb0SEric W. Biederman 	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
320c9582eb0SEric W. Biederman 
321825d6d33SMiklos Szeredi 	__set_bit(FR_WAITING, &req->flags);
322825d6d33SMiklos Szeredi 	__clear_bit(FR_BACKGROUND, &req->flags);
32333649c91SMiklos Szeredi 	return req;
32433649c91SMiklos Szeredi }
32533649c91SMiklos Szeredi 
326334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
327334f485dSMiklos Szeredi {
328ec99f6d3SElena Reshetova 	if (refcount_dec_and_test(&req->count)) {
329825d6d33SMiklos Szeredi 		if (test_bit(FR_BACKGROUND, &req->flags)) {
330722d2beaSMaxim Patlasov 			/*
331722d2beaSMaxim Patlasov 			 * We get here in the unlikely case that a background
332722d2beaSMaxim Patlasov 			 * request was allocated but not sent
333722d2beaSMaxim Patlasov 			 */
334ae2dffa3SKirill Tkhai 			spin_lock(&fc->bg_lock);
335722d2beaSMaxim Patlasov 			if (!fc->blocked)
336722d2beaSMaxim Patlasov 				wake_up(&fc->blocked_waitq);
337ae2dffa3SKirill Tkhai 			spin_unlock(&fc->bg_lock);
338722d2beaSMaxim Patlasov 		}
339722d2beaSMaxim Patlasov 
340825d6d33SMiklos Szeredi 		if (test_bit(FR_WAITING, &req->flags)) {
341825d6d33SMiklos Szeredi 			__clear_bit(FR_WAITING, &req->flags);
342b8f95e5dSMiklos Szeredi 			fuse_drop_waiting(fc);
34373e0e738SMiklos Szeredi 		}
34433649c91SMiklos Szeredi 
34533649c91SMiklos Szeredi 		if (req->stolen_file)
34633649c91SMiklos Szeredi 			put_reserved_req(fc, req);
34733649c91SMiklos Szeredi 		else
348ce1d5a49SMiklos Szeredi 			fuse_request_free(req);
3497128ec2aSMiklos Szeredi 	}
3507128ec2aSMiklos Szeredi }
35108cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_put_request);
3527128ec2aSMiklos Szeredi 
353d12def1bSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args)
354d12def1bSMiklos Szeredi {
355d12def1bSMiklos Szeredi 	unsigned nbytes = 0;
356d12def1bSMiklos Szeredi 	unsigned i;
357d12def1bSMiklos Szeredi 
358d12def1bSMiklos Szeredi 	for (i = 0; i < numargs; i++)
359d12def1bSMiklos Szeredi 		nbytes += args[i].size;
360d12def1bSMiklos Szeredi 
361d12def1bSMiklos Szeredi 	return nbytes;
362d12def1bSMiklos Szeredi }
363d12def1bSMiklos Szeredi 
364f88996a9SMiklos Szeredi static u64 fuse_get_unique(struct fuse_iqueue *fiq)
365d12def1bSMiklos Szeredi {
366c59fd85eSKirill Tkhai 	fiq->reqctr += FUSE_REQ_ID_STEP;
367c59fd85eSKirill Tkhai 	return fiq->reqctr;
368d12def1bSMiklos Szeredi }
369d12def1bSMiklos Szeredi 
370be2ff42cSKirill Tkhai static unsigned int fuse_req_hash(u64 unique)
371be2ff42cSKirill Tkhai {
372be2ff42cSKirill Tkhai 	return hash_long(unique & ~FUSE_INT_REQ_BIT, FUSE_PQ_HASH_BITS);
373be2ff42cSKirill Tkhai }
374be2ff42cSKirill Tkhai 
375f88996a9SMiklos Szeredi static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req)
376d12def1bSMiklos Szeredi {
377d12def1bSMiklos Szeredi 	req->in.h.len = sizeof(struct fuse_in_header) +
378d12def1bSMiklos Szeredi 		len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
379f88996a9SMiklos Szeredi 	list_add_tail(&req->list, &fiq->pending);
3804ce60812SMiklos Szeredi 	wake_up_locked(&fiq->waitq);
381f88996a9SMiklos Szeredi 	kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
382d12def1bSMiklos Szeredi }
383d12def1bSMiklos Szeredi 
38407e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
38507e77dcaSMiklos Szeredi 		       u64 nodeid, u64 nlookup)
38607e77dcaSMiklos Szeredi {
387f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
388f88996a9SMiklos Szeredi 
38902c048b9SMiklos Szeredi 	forget->forget_one.nodeid = nodeid;
39002c048b9SMiklos Szeredi 	forget->forget_one.nlookup = nlookup;
39107e77dcaSMiklos Szeredi 
3924ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
393e16714d8SMiklos Szeredi 	if (fiq->connected) {
394f88996a9SMiklos Szeredi 		fiq->forget_list_tail->next = forget;
395f88996a9SMiklos Szeredi 		fiq->forget_list_tail = forget;
3964ce60812SMiklos Szeredi 		wake_up_locked(&fiq->waitq);
397f88996a9SMiklos Szeredi 		kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
3985dfcc87fSMiklos Szeredi 	} else {
3995dfcc87fSMiklos Szeredi 		kfree(forget);
4005dfcc87fSMiklos Szeredi 	}
4014ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
40207e77dcaSMiklos Szeredi }
40307e77dcaSMiklos Szeredi 
404d12def1bSMiklos Szeredi static void flush_bg_queue(struct fuse_conn *fc)
405d12def1bSMiklos Szeredi {
406e287179aSKirill Tkhai 	struct fuse_iqueue *fiq = &fc->iq;
407e287179aSKirill Tkhai 
4087a6d3c8bSCsaba Henk 	while (fc->active_background < fc->max_background &&
409d12def1bSMiklos Szeredi 	       !list_empty(&fc->bg_queue)) {
410d12def1bSMiklos Szeredi 		struct fuse_req *req;
411d12def1bSMiklos Szeredi 
412e287179aSKirill Tkhai 		req = list_first_entry(&fc->bg_queue, struct fuse_req, list);
413d12def1bSMiklos Szeredi 		list_del(&req->list);
414d12def1bSMiklos Szeredi 		fc->active_background++;
4154ce60812SMiklos Szeredi 		spin_lock(&fiq->waitq.lock);
416f88996a9SMiklos Szeredi 		req->in.h.unique = fuse_get_unique(fiq);
417f88996a9SMiklos Szeredi 		queue_request(fiq, req);
4184ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
419d12def1bSMiklos Szeredi 	}
420d12def1bSMiklos Szeredi }
421d12def1bSMiklos Szeredi 
4226dbbcb12SMiklos Szeredi /*
423334f485dSMiklos Szeredi  * This function is called when a request is finished.  Either a reply
424f9a2842eSMiklos Szeredi  * has arrived or it was aborted (and not yet sent) or some error
425f43b155aSMiklos Szeredi  * occurred during communication with userspace, or the device file
42651eb01e7SMiklos Szeredi  * was closed.  The requester thread is woken up (if still waiting),
42751eb01e7SMiklos Szeredi  * the 'end' callback is called if given, else the reference to the
42851eb01e7SMiklos Szeredi  * request is released
429334f485dSMiklos Szeredi  */
430334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req)
431334f485dSMiklos Szeredi {
4324ce60812SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
433365ae710SMiklos Szeredi 
434efe2800fSMiklos Szeredi 	if (test_and_set_bit(FR_FINISHED, &req->flags))
435b8f95e5dSMiklos Szeredi 		goto put_request;
436217316a6SKirill Tkhai 	/*
437217316a6SKirill Tkhai 	 * test_and_set_bit() implies smp_mb() between bit
438217316a6SKirill Tkhai 	 * changing and below intr_entry check. Pairs with
439217316a6SKirill Tkhai 	 * smp_mb() from queue_interrupt().
440217316a6SKirill Tkhai 	 */
441217316a6SKirill Tkhai 	if (!list_empty(&req->intr_entry)) {
4424ce60812SMiklos Szeredi 		spin_lock(&fiq->waitq.lock);
4430d8e84b0SMiklos Szeredi 		list_del_init(&req->intr_entry);
4444ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
445217316a6SKirill Tkhai 	}
44633e14b4dSMiklos Szeredi 	WARN_ON(test_bit(FR_PENDING, &req->flags));
44733e14b4dSMiklos Szeredi 	WARN_ON(test_bit(FR_SENT, &req->flags));
448825d6d33SMiklos Szeredi 	if (test_bit(FR_BACKGROUND, &req->flags)) {
449ae2dffa3SKirill Tkhai 		spin_lock(&fc->bg_lock);
450825d6d33SMiklos Szeredi 		clear_bit(FR_BACKGROUND, &req->flags);
451908a572bSMiklos Szeredi 		if (fc->num_background == fc->max_background) {
45251eb01e7SMiklos Szeredi 			fc->blocked = 0;
453722d2beaSMaxim Patlasov 			wake_up(&fc->blocked_waitq);
454908a572bSMiklos Szeredi 		} else if (!fc->blocked) {
455908a572bSMiklos Szeredi 			/*
456908a572bSMiklos Szeredi 			 * Wake up next waiter, if any.  It's okay to use
457908a572bSMiklos Szeredi 			 * waitqueue_active(), as we've already synced up
458908a572bSMiklos Szeredi 			 * fc->blocked with waiters with the wake_up() call
459908a572bSMiklos Szeredi 			 * above.
460908a572bSMiklos Szeredi 			 */
461908a572bSMiklos Szeredi 			if (waitqueue_active(&fc->blocked_waitq))
462908a572bSMiklos Szeredi 				wake_up(&fc->blocked_waitq);
463908a572bSMiklos Szeredi 		}
464722d2beaSMaxim Patlasov 
4658a301eb1STejun Heo 		if (fc->num_background == fc->congestion_threshold && fc->sb) {
4665f7f7543SJan Kara 			clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
4675f7f7543SJan Kara 			clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
468f92b99b9SMiklos Szeredi 		}
46951eb01e7SMiklos Szeredi 		fc->num_background--;
470d12def1bSMiklos Szeredi 		fc->active_background--;
471d12def1bSMiklos Szeredi 		flush_bg_queue(fc);
472ae2dffa3SKirill Tkhai 		spin_unlock(&fc->bg_lock);
4735e0fed71SKirill Tkhai 	} else {
4745e0fed71SKirill Tkhai 		/* Wake up waiter sleeping in request_wait_answer() */
47551eb01e7SMiklos Szeredi 		wake_up(&req->waitq);
4765e0fed71SKirill Tkhai 	}
4775e0fed71SKirill Tkhai 
4781e6881c3SMiklos Szeredi 	if (req->end)
4791e6881c3SMiklos Szeredi 		req->end(fc, req);
480b8f95e5dSMiklos Szeredi put_request:
481f43b155aSMiklos Szeredi 	fuse_put_request(fc, req);
482334f485dSMiklos Szeredi }
483334f485dSMiklos Szeredi 
484b782911bSKirill Tkhai static int queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
485a4d27e75SMiklos Szeredi {
4864ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
487b782911bSKirill Tkhai 	/* Check for we've sent request to interrupt this req */
488b782911bSKirill Tkhai 	if (unlikely(!test_bit(FR_INTERRUPTED, &req->flags))) {
489b782911bSKirill Tkhai 		spin_unlock(&fiq->waitq.lock);
490b782911bSKirill Tkhai 		return -EINVAL;
491b782911bSKirill Tkhai 	}
492b782911bSKirill Tkhai 
493217316a6SKirill Tkhai 	if (list_empty(&req->intr_entry)) {
494217316a6SKirill Tkhai 		list_add_tail(&req->intr_entry, &fiq->interrupts);
495217316a6SKirill Tkhai 		/*
496217316a6SKirill Tkhai 		 * Pairs with smp_mb() implied by test_and_set_bit()
497217316a6SKirill Tkhai 		 * from request_end().
498217316a6SKirill Tkhai 		 */
499217316a6SKirill Tkhai 		smp_mb();
5006ba4d272SSahitya Tummala 		if (test_bit(FR_FINISHED, &req->flags)) {
501217316a6SKirill Tkhai 			list_del_init(&req->intr_entry);
5026ba4d272SSahitya Tummala 			spin_unlock(&fiq->waitq.lock);
503b782911bSKirill Tkhai 			return 0;
5046ba4d272SSahitya Tummala 		}
5054ce60812SMiklos Szeredi 		wake_up_locked(&fiq->waitq);
5068da6e918SKirill Tkhai 		kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
5078f7bb368SMiklos Szeredi 	}
5084ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
509b782911bSKirill Tkhai 	return 0;
510a4d27e75SMiklos Szeredi }
511a4d27e75SMiklos Szeredi 
5127c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
513334f485dSMiklos Szeredi {
5144ce60812SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
515c4775267SMiklos Szeredi 	int err;
516c4775267SMiklos Szeredi 
517a4d27e75SMiklos Szeredi 	if (!fc->no_interrupt) {
518a4d27e75SMiklos Szeredi 		/* Any signal may interrupt this */
519c4775267SMiklos Szeredi 		err = wait_event_interruptible(req->waitq,
52033e14b4dSMiklos Szeredi 					test_bit(FR_FINISHED, &req->flags));
521c4775267SMiklos Szeredi 		if (!err)
522334f485dSMiklos Szeredi 			return;
523334f485dSMiklos Szeredi 
524825d6d33SMiklos Szeredi 		set_bit(FR_INTERRUPTED, &req->flags);
5258f7bb368SMiklos Szeredi 		/* matches barrier in fuse_dev_do_read() */
5268f7bb368SMiklos Szeredi 		smp_mb__after_atomic();
52733e14b4dSMiklos Szeredi 		if (test_bit(FR_SENT, &req->flags))
5284ce60812SMiklos Szeredi 			queue_interrupt(fiq, req);
529a4d27e75SMiklos Szeredi 	}
530a4d27e75SMiklos Szeredi 
531825d6d33SMiklos Szeredi 	if (!test_bit(FR_FORCE, &req->flags)) {
532a4d27e75SMiklos Szeredi 		/* Only fatal signals may interrupt this */
5337d3a07fcSAl Viro 		err = wait_event_killable(req->waitq,
53433e14b4dSMiklos Szeredi 					test_bit(FR_FINISHED, &req->flags));
535c4775267SMiklos Szeredi 		if (!err)
536a4d27e75SMiklos Szeredi 			return;
537a4d27e75SMiklos Szeredi 
5384ce60812SMiklos Szeredi 		spin_lock(&fiq->waitq.lock);
539a131de0aSMiklos Szeredi 		/* Request is not yet in userspace, bail out */
54033e14b4dSMiklos Szeredi 		if (test_bit(FR_PENDING, &req->flags)) {
541a131de0aSMiklos Szeredi 			list_del(&req->list);
5424ce60812SMiklos Szeredi 			spin_unlock(&fiq->waitq.lock);
543a131de0aSMiklos Szeredi 			__fuse_put_request(req);
544334f485dSMiklos Szeredi 			req->out.h.error = -EINTR;
545a131de0aSMiklos Szeredi 			return;
546a131de0aSMiklos Szeredi 		}
5474ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
548a131de0aSMiklos Szeredi 	}
549a131de0aSMiklos Szeredi 
550a131de0aSMiklos Szeredi 	/*
551a131de0aSMiklos Szeredi 	 * Either request is already in userspace, or it was forced.
552a131de0aSMiklos Szeredi 	 * Wait it out.
553a131de0aSMiklos Szeredi 	 */
55433e14b4dSMiklos Szeredi 	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
555334f485dSMiklos Szeredi }
556334f485dSMiklos Szeredi 
5576a4e922cSEric Wong static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
558334f485dSMiklos Szeredi {
559e16714d8SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
560e16714d8SMiklos Szeredi 
561825d6d33SMiklos Szeredi 	BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
5624ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
563e16714d8SMiklos Szeredi 	if (!fiq->connected) {
5644ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
565334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
566c4775267SMiklos Szeredi 	} else {
567f88996a9SMiklos Szeredi 		req->in.h.unique = fuse_get_unique(fiq);
568f88996a9SMiklos Szeredi 		queue_request(fiq, req);
569334f485dSMiklos Szeredi 		/* acquire extra reference, since request is still needed
570334f485dSMiklos Szeredi 		   after request_end() */
571334f485dSMiklos Szeredi 		__fuse_get_request(req);
5724ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
573334f485dSMiklos Szeredi 
5747c352bdfSMiklos Szeredi 		request_wait_answer(fc, req);
575c4775267SMiklos Szeredi 		/* Pairs with smp_wmb() in request_end() */
576c4775267SMiklos Szeredi 		smp_rmb();
577334f485dSMiklos Szeredi 	}
578334f485dSMiklos Szeredi }
5796a4e922cSEric Wong 
5806a4e922cSEric Wong void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
5816a4e922cSEric Wong {
582825d6d33SMiklos Szeredi 	__set_bit(FR_ISREPLY, &req->flags);
583825d6d33SMiklos Szeredi 	if (!test_bit(FR_WAITING, &req->flags)) {
584825d6d33SMiklos Szeredi 		__set_bit(FR_WAITING, &req->flags);
5855437f241SMiklos Szeredi 		atomic_inc(&fc->num_waiting);
5865437f241SMiklos Szeredi 	}
5876a4e922cSEric Wong 	__fuse_request_send(fc, req);
5886a4e922cSEric Wong }
58908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send);
590334f485dSMiklos Szeredi 
59121f62174SMiklos Szeredi static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args)
59221f62174SMiklos Szeredi {
59321f62174SMiklos Szeredi 	if (fc->minor < 4 && args->in.h.opcode == FUSE_STATFS)
59421f62174SMiklos Szeredi 		args->out.args[0].size = FUSE_COMPAT_STATFS_SIZE;
59521f62174SMiklos Szeredi 
59621f62174SMiklos Szeredi 	if (fc->minor < 9) {
59721f62174SMiklos Szeredi 		switch (args->in.h.opcode) {
59821f62174SMiklos Szeredi 		case FUSE_LOOKUP:
59921f62174SMiklos Szeredi 		case FUSE_CREATE:
60021f62174SMiklos Szeredi 		case FUSE_MKNOD:
60121f62174SMiklos Szeredi 		case FUSE_MKDIR:
60221f62174SMiklos Szeredi 		case FUSE_SYMLINK:
60321f62174SMiklos Szeredi 		case FUSE_LINK:
60421f62174SMiklos Szeredi 			args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
60521f62174SMiklos Szeredi 			break;
60621f62174SMiklos Szeredi 		case FUSE_GETATTR:
60721f62174SMiklos Szeredi 		case FUSE_SETATTR:
60821f62174SMiklos Szeredi 			args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
60921f62174SMiklos Szeredi 			break;
61021f62174SMiklos Szeredi 		}
61121f62174SMiklos Szeredi 	}
61221f62174SMiklos Szeredi 	if (fc->minor < 12) {
61321f62174SMiklos Szeredi 		switch (args->in.h.opcode) {
61421f62174SMiklos Szeredi 		case FUSE_CREATE:
61521f62174SMiklos Szeredi 			args->in.args[0].size = sizeof(struct fuse_open_in);
61621f62174SMiklos Szeredi 			break;
61721f62174SMiklos Szeredi 		case FUSE_MKNOD:
61821f62174SMiklos Szeredi 			args->in.args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE;
61921f62174SMiklos Szeredi 			break;
62021f62174SMiklos Szeredi 		}
62121f62174SMiklos Szeredi 	}
62221f62174SMiklos Szeredi }
62321f62174SMiklos Szeredi 
6247078187aSMiklos Szeredi ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args)
6257078187aSMiklos Szeredi {
6267078187aSMiklos Szeredi 	struct fuse_req *req;
6277078187aSMiklos Szeredi 	ssize_t ret;
6287078187aSMiklos Szeredi 
6297078187aSMiklos Szeredi 	req = fuse_get_req(fc, 0);
6307078187aSMiklos Szeredi 	if (IS_ERR(req))
6317078187aSMiklos Szeredi 		return PTR_ERR(req);
6327078187aSMiklos Szeredi 
63321f62174SMiklos Szeredi 	/* Needs to be done after fuse_get_req() so that fc->minor is valid */
63421f62174SMiklos Szeredi 	fuse_adjust_compat(fc, args);
63521f62174SMiklos Szeredi 
6367078187aSMiklos Szeredi 	req->in.h.opcode = args->in.h.opcode;
6377078187aSMiklos Szeredi 	req->in.h.nodeid = args->in.h.nodeid;
6387078187aSMiklos Szeredi 	req->in.numargs = args->in.numargs;
6397078187aSMiklos Szeredi 	memcpy(req->in.args, args->in.args,
6407078187aSMiklos Szeredi 	       args->in.numargs * sizeof(struct fuse_in_arg));
6417078187aSMiklos Szeredi 	req->out.argvar = args->out.argvar;
6427078187aSMiklos Szeredi 	req->out.numargs = args->out.numargs;
6437078187aSMiklos Szeredi 	memcpy(req->out.args, args->out.args,
6447078187aSMiklos Szeredi 	       args->out.numargs * sizeof(struct fuse_arg));
6457078187aSMiklos Szeredi 	fuse_request_send(fc, req);
6467078187aSMiklos Szeredi 	ret = req->out.h.error;
6477078187aSMiklos Szeredi 	if (!ret && args->out.argvar) {
6487078187aSMiklos Szeredi 		BUG_ON(args->out.numargs != 1);
6497078187aSMiklos Szeredi 		ret = req->out.args[0].size;
6507078187aSMiklos Szeredi 	}
6517078187aSMiklos Szeredi 	fuse_put_request(fc, req);
6527078187aSMiklos Szeredi 
6537078187aSMiklos Szeredi 	return ret;
6547078187aSMiklos Szeredi }
6557078187aSMiklos Szeredi 
65663825b4eSKirill Tkhai bool fuse_request_queue_background(struct fuse_conn *fc, struct fuse_req *req)
657334f485dSMiklos Szeredi {
65863825b4eSKirill Tkhai 	bool queued = false;
65963825b4eSKirill Tkhai 
66063825b4eSKirill Tkhai 	WARN_ON(!test_bit(FR_BACKGROUND, &req->flags));
661825d6d33SMiklos Szeredi 	if (!test_bit(FR_WAITING, &req->flags)) {
662825d6d33SMiklos Szeredi 		__set_bit(FR_WAITING, &req->flags);
6635437f241SMiklos Szeredi 		atomic_inc(&fc->num_waiting);
6645437f241SMiklos Szeredi 	}
665825d6d33SMiklos Szeredi 	__set_bit(FR_ISREPLY, &req->flags);
666ae2dffa3SKirill Tkhai 	spin_lock(&fc->bg_lock);
66763825b4eSKirill Tkhai 	if (likely(fc->connected)) {
66851eb01e7SMiklos Szeredi 		fc->num_background++;
6697a6d3c8bSCsaba Henk 		if (fc->num_background == fc->max_background)
67051eb01e7SMiklos Szeredi 			fc->blocked = 1;
6717fbbe972SJan Kara 		if (fc->num_background == fc->congestion_threshold && fc->sb) {
6725f7f7543SJan Kara 			set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
6735f7f7543SJan Kara 			set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
674f92b99b9SMiklos Szeredi 		}
675d12def1bSMiklos Szeredi 		list_add_tail(&req->list, &fc->bg_queue);
676d12def1bSMiklos Szeredi 		flush_bg_queue(fc);
67763825b4eSKirill Tkhai 		queued = true;
67863825b4eSKirill Tkhai 	}
679ae2dffa3SKirill Tkhai 	spin_unlock(&fc->bg_lock);
68063825b4eSKirill Tkhai 
68163825b4eSKirill Tkhai 	return queued;
682d12def1bSMiklos Szeredi }
68351eb01e7SMiklos Szeredi 
684f0139aa8SMiklos Szeredi void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
685d12def1bSMiklos Szeredi {
68663825b4eSKirill Tkhai 	WARN_ON(!req->end);
68763825b4eSKirill Tkhai 	if (!fuse_request_queue_background(fc, req)) {
688334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
68942dc6211SMiklos Szeredi 		req->end(fc, req);
69042dc6211SMiklos Szeredi 		fuse_put_request(fc, req);
691334f485dSMiklos Szeredi 	}
692334f485dSMiklos Szeredi }
69308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send_background);
694334f485dSMiklos Szeredi 
6952d45ba38SMiklos Szeredi static int fuse_request_send_notify_reply(struct fuse_conn *fc,
6962d45ba38SMiklos Szeredi 					  struct fuse_req *req, u64 unique)
6972d45ba38SMiklos Szeredi {
6982d45ba38SMiklos Szeredi 	int err = -ENODEV;
699f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
7002d45ba38SMiklos Szeredi 
701825d6d33SMiklos Szeredi 	__clear_bit(FR_ISREPLY, &req->flags);
7022d45ba38SMiklos Szeredi 	req->in.h.unique = unique;
7034ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
704e16714d8SMiklos Szeredi 	if (fiq->connected) {
705f88996a9SMiklos Szeredi 		queue_request(fiq, req);
7062d45ba38SMiklos Szeredi 		err = 0;
7072d45ba38SMiklos Szeredi 	}
7084ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
7092d45ba38SMiklos Szeredi 
7102d45ba38SMiklos Szeredi 	return err;
7112d45ba38SMiklos Szeredi }
7122d45ba38SMiklos Szeredi 
7130b05b183SAnand V. Avati void fuse_force_forget(struct file *file, u64 nodeid)
7140b05b183SAnand V. Avati {
7156131ffaaSAl Viro 	struct inode *inode = file_inode(file);
7160b05b183SAnand V. Avati 	struct fuse_conn *fc = get_fuse_conn(inode);
7170b05b183SAnand V. Avati 	struct fuse_req *req;
7180b05b183SAnand V. Avati 	struct fuse_forget_in inarg;
7190b05b183SAnand V. Avati 
7200b05b183SAnand V. Avati 	memset(&inarg, 0, sizeof(inarg));
7210b05b183SAnand V. Avati 	inarg.nlookup = 1;
722b111c8c0SMaxim Patlasov 	req = fuse_get_req_nofail_nopages(fc, file);
7230b05b183SAnand V. Avati 	req->in.h.opcode = FUSE_FORGET;
7240b05b183SAnand V. Avati 	req->in.h.nodeid = nodeid;
7250b05b183SAnand V. Avati 	req->in.numargs = 1;
7260b05b183SAnand V. Avati 	req->in.args[0].size = sizeof(inarg);
7270b05b183SAnand V. Avati 	req->in.args[0].value = &inarg;
728825d6d33SMiklos Szeredi 	__clear_bit(FR_ISREPLY, &req->flags);
7296a4e922cSEric Wong 	__fuse_request_send(fc, req);
7306a4e922cSEric Wong 	/* ignore errors */
7316a4e922cSEric Wong 	fuse_put_request(fc, req);
7320b05b183SAnand V. Avati }
7330b05b183SAnand V. Avati 
7343be5a52bSMiklos Szeredi /*
735334f485dSMiklos Szeredi  * Lock the request.  Up to the next unlock_request() there mustn't be
736334f485dSMiklos Szeredi  * anything that could cause a page-fault.  If the request was already
737f9a2842eSMiklos Szeredi  * aborted bail out.
738334f485dSMiklos Szeredi  */
739dc00809aSMiklos Szeredi static int lock_request(struct fuse_req *req)
740334f485dSMiklos Szeredi {
741334f485dSMiklos Szeredi 	int err = 0;
742334f485dSMiklos Szeredi 	if (req) {
743dc00809aSMiklos Szeredi 		spin_lock(&req->waitq.lock);
744825d6d33SMiklos Szeredi 		if (test_bit(FR_ABORTED, &req->flags))
745334f485dSMiklos Szeredi 			err = -ENOENT;
746334f485dSMiklos Szeredi 		else
747825d6d33SMiklos Szeredi 			set_bit(FR_LOCKED, &req->flags);
748dc00809aSMiklos Szeredi 		spin_unlock(&req->waitq.lock);
749334f485dSMiklos Szeredi 	}
750334f485dSMiklos Szeredi 	return err;
751334f485dSMiklos Szeredi }
752334f485dSMiklos Szeredi 
753334f485dSMiklos Szeredi /*
7540d8e84b0SMiklos Szeredi  * Unlock request.  If it was aborted while locked, caller is responsible
7550d8e84b0SMiklos Szeredi  * for unlocking and ending the request.
756334f485dSMiklos Szeredi  */
757dc00809aSMiklos Szeredi static int unlock_request(struct fuse_req *req)
758334f485dSMiklos Szeredi {
7590d8e84b0SMiklos Szeredi 	int err = 0;
760334f485dSMiklos Szeredi 	if (req) {
761dc00809aSMiklos Szeredi 		spin_lock(&req->waitq.lock);
762825d6d33SMiklos Szeredi 		if (test_bit(FR_ABORTED, &req->flags))
7630d8e84b0SMiklos Szeredi 			err = -ENOENT;
7640d8e84b0SMiklos Szeredi 		else
765825d6d33SMiklos Szeredi 			clear_bit(FR_LOCKED, &req->flags);
766dc00809aSMiklos Szeredi 		spin_unlock(&req->waitq.lock);
767334f485dSMiklos Szeredi 	}
7680d8e84b0SMiklos Szeredi 	return err;
769334f485dSMiklos Szeredi }
770334f485dSMiklos Szeredi 
771334f485dSMiklos Szeredi struct fuse_copy_state {
772334f485dSMiklos Szeredi 	int write;
773334f485dSMiklos Szeredi 	struct fuse_req *req;
7746c09e94aSAl Viro 	struct iov_iter *iter;
775dd3bb14fSMiklos Szeredi 	struct pipe_buffer *pipebufs;
776dd3bb14fSMiklos Szeredi 	struct pipe_buffer *currbuf;
777dd3bb14fSMiklos Szeredi 	struct pipe_inode_info *pipe;
778334f485dSMiklos Szeredi 	unsigned long nr_segs;
779334f485dSMiklos Szeredi 	struct page *pg;
780334f485dSMiklos Szeredi 	unsigned len;
781c55a01d3SMiklos Szeredi 	unsigned offset;
782ce534fb0SMiklos Szeredi 	unsigned move_pages:1;
783334f485dSMiklos Szeredi };
784334f485dSMiklos Szeredi 
785dc00809aSMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, int write,
7866c09e94aSAl Viro 			   struct iov_iter *iter)
787334f485dSMiklos Szeredi {
788334f485dSMiklos Szeredi 	memset(cs, 0, sizeof(*cs));
789334f485dSMiklos Szeredi 	cs->write = write;
7906c09e94aSAl Viro 	cs->iter = iter;
791334f485dSMiklos Szeredi }
792334f485dSMiklos Szeredi 
793334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */
7948bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs)
795334f485dSMiklos Szeredi {
796dd3bb14fSMiklos Szeredi 	if (cs->currbuf) {
797dd3bb14fSMiklos Szeredi 		struct pipe_buffer *buf = cs->currbuf;
798dd3bb14fSMiklos Szeredi 
799c55a01d3SMiklos Szeredi 		if (cs->write)
800c3021629SMiklos Szeredi 			buf->len = PAGE_SIZE - cs->len;
801dd3bb14fSMiklos Szeredi 		cs->currbuf = NULL;
802c55a01d3SMiklos Szeredi 	} else if (cs->pg) {
803334f485dSMiklos Szeredi 		if (cs->write) {
804334f485dSMiklos Szeredi 			flush_dcache_page(cs->pg);
805334f485dSMiklos Szeredi 			set_page_dirty_lock(cs->pg);
806334f485dSMiklos Szeredi 		}
807334f485dSMiklos Szeredi 		put_page(cs->pg);
808334f485dSMiklos Szeredi 	}
809c55a01d3SMiklos Szeredi 	cs->pg = NULL;
810334f485dSMiklos Szeredi }
811334f485dSMiklos Szeredi 
812334f485dSMiklos Szeredi /*
813334f485dSMiklos Szeredi  * Get another pagefull of userspace buffer, and map it to kernel
814334f485dSMiklos Szeredi  * address space, and lock request
815334f485dSMiklos Szeredi  */
816334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs)
817334f485dSMiklos Szeredi {
818c55a01d3SMiklos Szeredi 	struct page *page;
819334f485dSMiklos Szeredi 	int err;
820334f485dSMiklos Szeredi 
821dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
8220d8e84b0SMiklos Szeredi 	if (err)
8230d8e84b0SMiklos Szeredi 		return err;
8240d8e84b0SMiklos Szeredi 
825334f485dSMiklos Szeredi 	fuse_copy_finish(cs);
826dd3bb14fSMiklos Szeredi 	if (cs->pipebufs) {
827dd3bb14fSMiklos Szeredi 		struct pipe_buffer *buf = cs->pipebufs;
828dd3bb14fSMiklos Szeredi 
829c3021629SMiklos Szeredi 		if (!cs->write) {
830fba597dbSMiklos Szeredi 			err = pipe_buf_confirm(cs->pipe, buf);
831dd3bb14fSMiklos Szeredi 			if (err)
832dd3bb14fSMiklos Szeredi 				return err;
833dd3bb14fSMiklos Szeredi 
834dd3bb14fSMiklos Szeredi 			BUG_ON(!cs->nr_segs);
835dd3bb14fSMiklos Szeredi 			cs->currbuf = buf;
836c55a01d3SMiklos Szeredi 			cs->pg = buf->page;
837c55a01d3SMiklos Szeredi 			cs->offset = buf->offset;
838dd3bb14fSMiklos Szeredi 			cs->len = buf->len;
839dd3bb14fSMiklos Szeredi 			cs->pipebufs++;
840dd3bb14fSMiklos Szeredi 			cs->nr_segs--;
841dd3bb14fSMiklos Szeredi 		} else {
842c3021629SMiklos Szeredi 			if (cs->nr_segs == cs->pipe->buffers)
843c3021629SMiklos Szeredi 				return -EIO;
844c3021629SMiklos Szeredi 
845c3021629SMiklos Szeredi 			page = alloc_page(GFP_HIGHUSER);
846c3021629SMiklos Szeredi 			if (!page)
847c3021629SMiklos Szeredi 				return -ENOMEM;
848c3021629SMiklos Szeredi 
849c3021629SMiklos Szeredi 			buf->page = page;
850c3021629SMiklos Szeredi 			buf->offset = 0;
851c3021629SMiklos Szeredi 			buf->len = 0;
852c3021629SMiklos Szeredi 
853c3021629SMiklos Szeredi 			cs->currbuf = buf;
854c55a01d3SMiklos Szeredi 			cs->pg = page;
855c55a01d3SMiklos Szeredi 			cs->offset = 0;
856c3021629SMiklos Szeredi 			cs->len = PAGE_SIZE;
857c3021629SMiklos Szeredi 			cs->pipebufs++;
858c3021629SMiklos Szeredi 			cs->nr_segs++;
859c3021629SMiklos Szeredi 		}
860c3021629SMiklos Szeredi 	} else {
8616c09e94aSAl Viro 		size_t off;
8626c09e94aSAl Viro 		err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off);
863334f485dSMiklos Szeredi 		if (err < 0)
864334f485dSMiklos Szeredi 			return err;
8656c09e94aSAl Viro 		BUG_ON(!err);
8666c09e94aSAl Viro 		cs->len = err;
8676c09e94aSAl Viro 		cs->offset = off;
868c55a01d3SMiklos Szeredi 		cs->pg = page;
8696c09e94aSAl Viro 		iov_iter_advance(cs->iter, err);
870dd3bb14fSMiklos Szeredi 	}
871334f485dSMiklos Szeredi 
872dc00809aSMiklos Szeredi 	return lock_request(cs->req);
873334f485dSMiklos Szeredi }
874334f485dSMiklos Szeredi 
875334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */
8768bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
877334f485dSMiklos Szeredi {
878334f485dSMiklos Szeredi 	unsigned ncpy = min(*size, cs->len);
879334f485dSMiklos Szeredi 	if (val) {
880c55a01d3SMiklos Szeredi 		void *pgaddr = kmap_atomic(cs->pg);
881c55a01d3SMiklos Szeredi 		void *buf = pgaddr + cs->offset;
882c55a01d3SMiklos Szeredi 
883334f485dSMiklos Szeredi 		if (cs->write)
884c55a01d3SMiklos Szeredi 			memcpy(buf, *val, ncpy);
885334f485dSMiklos Szeredi 		else
886c55a01d3SMiklos Szeredi 			memcpy(*val, buf, ncpy);
887c55a01d3SMiklos Szeredi 
888c55a01d3SMiklos Szeredi 		kunmap_atomic(pgaddr);
889334f485dSMiklos Szeredi 		*val += ncpy;
890334f485dSMiklos Szeredi 	}
891334f485dSMiklos Szeredi 	*size -= ncpy;
892334f485dSMiklos Szeredi 	cs->len -= ncpy;
893c55a01d3SMiklos Szeredi 	cs->offset += ncpy;
894334f485dSMiklos Szeredi 	return ncpy;
895334f485dSMiklos Szeredi }
896334f485dSMiklos Szeredi 
897ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page)
898ce534fb0SMiklos Szeredi {
899ce534fb0SMiklos Szeredi 	if (page_mapcount(page) ||
900ce534fb0SMiklos Szeredi 	    page->mapping != NULL ||
901ce534fb0SMiklos Szeredi 	    page_count(page) != 1 ||
902ce534fb0SMiklos Szeredi 	    (page->flags & PAGE_FLAGS_CHECK_AT_PREP &
903ce534fb0SMiklos Szeredi 	     ~(1 << PG_locked |
904ce534fb0SMiklos Szeredi 	       1 << PG_referenced |
905ce534fb0SMiklos Szeredi 	       1 << PG_uptodate |
906ce534fb0SMiklos Szeredi 	       1 << PG_lru |
907ce534fb0SMiklos Szeredi 	       1 << PG_active |
908ce534fb0SMiklos Szeredi 	       1 << PG_reclaim))) {
909ce534fb0SMiklos Szeredi 		printk(KERN_WARNING "fuse: trying to steal weird page\n");
910ce534fb0SMiklos 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);
911ce534fb0SMiklos Szeredi 		return 1;
912ce534fb0SMiklos Szeredi 	}
913ce534fb0SMiklos Szeredi 	return 0;
914ce534fb0SMiklos Szeredi }
915ce534fb0SMiklos Szeredi 
916ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
917ce534fb0SMiklos Szeredi {
918ce534fb0SMiklos Szeredi 	int err;
919ce534fb0SMiklos Szeredi 	struct page *oldpage = *pagep;
920ce534fb0SMiklos Szeredi 	struct page *newpage;
921ce534fb0SMiklos Szeredi 	struct pipe_buffer *buf = cs->pipebufs;
922ce534fb0SMiklos Szeredi 
923dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
9240d8e84b0SMiklos Szeredi 	if (err)
9250d8e84b0SMiklos Szeredi 		return err;
9260d8e84b0SMiklos Szeredi 
927ce534fb0SMiklos Szeredi 	fuse_copy_finish(cs);
928ce534fb0SMiklos Szeredi 
929fba597dbSMiklos Szeredi 	err = pipe_buf_confirm(cs->pipe, buf);
930ce534fb0SMiklos Szeredi 	if (err)
931ce534fb0SMiklos Szeredi 		return err;
932ce534fb0SMiklos Szeredi 
933ce534fb0SMiklos Szeredi 	BUG_ON(!cs->nr_segs);
934ce534fb0SMiklos Szeredi 	cs->currbuf = buf;
935ce534fb0SMiklos Szeredi 	cs->len = buf->len;
936ce534fb0SMiklos Szeredi 	cs->pipebufs++;
937ce534fb0SMiklos Szeredi 	cs->nr_segs--;
938ce534fb0SMiklos Szeredi 
939ce534fb0SMiklos Szeredi 	if (cs->len != PAGE_SIZE)
940ce534fb0SMiklos Szeredi 		goto out_fallback;
941ce534fb0SMiklos Szeredi 
942ca76f5b6SMiklos Szeredi 	if (pipe_buf_steal(cs->pipe, buf) != 0)
943ce534fb0SMiklos Szeredi 		goto out_fallback;
944ce534fb0SMiklos Szeredi 
945ce534fb0SMiklos Szeredi 	newpage = buf->page;
946ce534fb0SMiklos Szeredi 
947aa991b3bSMiklos Szeredi 	if (!PageUptodate(newpage))
948aa991b3bSMiklos Szeredi 		SetPageUptodate(newpage);
949ce534fb0SMiklos Szeredi 
950ce534fb0SMiklos Szeredi 	ClearPageMappedToDisk(newpage);
951ce534fb0SMiklos Szeredi 
952ce534fb0SMiklos Szeredi 	if (fuse_check_page(newpage) != 0)
953ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
954ce534fb0SMiklos Szeredi 
955ce534fb0SMiklos Szeredi 	/*
956ce534fb0SMiklos Szeredi 	 * This is a new and locked page, it shouldn't be mapped or
957ce534fb0SMiklos Szeredi 	 * have any special flags on it
958ce534fb0SMiklos Szeredi 	 */
959ce534fb0SMiklos Szeredi 	if (WARN_ON(page_mapped(oldpage)))
960ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
961ce534fb0SMiklos Szeredi 	if (WARN_ON(page_has_private(oldpage)))
962ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
963ce534fb0SMiklos Szeredi 	if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage)))
964ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
965ce534fb0SMiklos Szeredi 	if (WARN_ON(PageMlocked(oldpage)))
966ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
967ce534fb0SMiklos Szeredi 
968ef6a3c63SMiklos Szeredi 	err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL);
969ce534fb0SMiklos Szeredi 	if (err) {
970ef6a3c63SMiklos Szeredi 		unlock_page(newpage);
971ef6a3c63SMiklos Szeredi 		return err;
972ce534fb0SMiklos Szeredi 	}
973ef6a3c63SMiklos Szeredi 
97409cbfeafSKirill A. Shutemov 	get_page(newpage);
975ce534fb0SMiklos Szeredi 
976ce534fb0SMiklos Szeredi 	if (!(buf->flags & PIPE_BUF_FLAG_LRU))
977ce534fb0SMiklos Szeredi 		lru_cache_add_file(newpage);
978ce534fb0SMiklos Szeredi 
979ce534fb0SMiklos Szeredi 	err = 0;
980dc00809aSMiklos Szeredi 	spin_lock(&cs->req->waitq.lock);
981825d6d33SMiklos Szeredi 	if (test_bit(FR_ABORTED, &cs->req->flags))
982ce534fb0SMiklos Szeredi 		err = -ENOENT;
983ce534fb0SMiklos Szeredi 	else
984ce534fb0SMiklos Szeredi 		*pagep = newpage;
985dc00809aSMiklos Szeredi 	spin_unlock(&cs->req->waitq.lock);
986ce534fb0SMiklos Szeredi 
987ce534fb0SMiklos Szeredi 	if (err) {
988ce534fb0SMiklos Szeredi 		unlock_page(newpage);
98909cbfeafSKirill A. Shutemov 		put_page(newpage);
990ce534fb0SMiklos Szeredi 		return err;
991ce534fb0SMiklos Szeredi 	}
992ce534fb0SMiklos Szeredi 
993ce534fb0SMiklos Szeredi 	unlock_page(oldpage);
99409cbfeafSKirill A. Shutemov 	put_page(oldpage);
995ce534fb0SMiklos Szeredi 	cs->len = 0;
996ce534fb0SMiklos Szeredi 
997ce534fb0SMiklos Szeredi 	return 0;
998ce534fb0SMiklos Szeredi 
999ce534fb0SMiklos Szeredi out_fallback_unlock:
1000ce534fb0SMiklos Szeredi 	unlock_page(newpage);
1001ce534fb0SMiklos Szeredi out_fallback:
1002c55a01d3SMiklos Szeredi 	cs->pg = buf->page;
1003c55a01d3SMiklos Szeredi 	cs->offset = buf->offset;
1004ce534fb0SMiklos Szeredi 
1005dc00809aSMiklos Szeredi 	err = lock_request(cs->req);
1006ce534fb0SMiklos Szeredi 	if (err)
1007ce534fb0SMiklos Szeredi 		return err;
1008ce534fb0SMiklos Szeredi 
1009ce534fb0SMiklos Szeredi 	return 1;
1010ce534fb0SMiklos Szeredi }
1011ce534fb0SMiklos Szeredi 
1012c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
1013c3021629SMiklos Szeredi 			 unsigned offset, unsigned count)
1014c3021629SMiklos Szeredi {
1015c3021629SMiklos Szeredi 	struct pipe_buffer *buf;
10160d8e84b0SMiklos Szeredi 	int err;
1017c3021629SMiklos Szeredi 
1018c3021629SMiklos Szeredi 	if (cs->nr_segs == cs->pipe->buffers)
1019c3021629SMiklos Szeredi 		return -EIO;
1020c3021629SMiklos Szeredi 
1021dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
10220d8e84b0SMiklos Szeredi 	if (err)
10230d8e84b0SMiklos Szeredi 		return err;
10240d8e84b0SMiklos Szeredi 
1025c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
1026c3021629SMiklos Szeredi 
1027c3021629SMiklos Szeredi 	buf = cs->pipebufs;
102809cbfeafSKirill A. Shutemov 	get_page(page);
1029c3021629SMiklos Szeredi 	buf->page = page;
1030c3021629SMiklos Szeredi 	buf->offset = offset;
1031c3021629SMiklos Szeredi 	buf->len = count;
1032c3021629SMiklos Szeredi 
1033c3021629SMiklos Szeredi 	cs->pipebufs++;
1034c3021629SMiklos Szeredi 	cs->nr_segs++;
1035c3021629SMiklos Szeredi 	cs->len = 0;
1036c3021629SMiklos Szeredi 
1037c3021629SMiklos Szeredi 	return 0;
1038c3021629SMiklos Szeredi }
1039c3021629SMiklos Szeredi 
1040334f485dSMiklos Szeredi /*
1041334f485dSMiklos Szeredi  * Copy a page in the request to/from the userspace buffer.  Must be
1042334f485dSMiklos Szeredi  * done atomically
1043334f485dSMiklos Szeredi  */
1044ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
1045334f485dSMiklos Szeredi 			  unsigned offset, unsigned count, int zeroing)
1046334f485dSMiklos Szeredi {
1047ce534fb0SMiklos Szeredi 	int err;
1048ce534fb0SMiklos Szeredi 	struct page *page = *pagep;
1049ce534fb0SMiklos Szeredi 
1050b6777c40SMiklos Szeredi 	if (page && zeroing && count < PAGE_SIZE)
1051b6777c40SMiklos Szeredi 		clear_highpage(page);
1052b6777c40SMiklos Szeredi 
1053334f485dSMiklos Szeredi 	while (count) {
1054c3021629SMiklos Szeredi 		if (cs->write && cs->pipebufs && page) {
1055c3021629SMiklos Szeredi 			return fuse_ref_page(cs, page, offset, count);
1056c3021629SMiklos Szeredi 		} else if (!cs->len) {
1057ce534fb0SMiklos Szeredi 			if (cs->move_pages && page &&
1058ce534fb0SMiklos Szeredi 			    offset == 0 && count == PAGE_SIZE) {
1059ce534fb0SMiklos Szeredi 				err = fuse_try_move_page(cs, pagep);
1060ce534fb0SMiklos Szeredi 				if (err <= 0)
1061ce534fb0SMiklos Szeredi 					return err;
1062ce534fb0SMiklos Szeredi 			} else {
1063ce534fb0SMiklos Szeredi 				err = fuse_copy_fill(cs);
10641729a16cSMiklos Szeredi 				if (err)
1065334f485dSMiklos Szeredi 					return err;
10661729a16cSMiklos Szeredi 			}
1067ce534fb0SMiklos Szeredi 		}
1068334f485dSMiklos Szeredi 		if (page) {
10692408f6efSCong Wang 			void *mapaddr = kmap_atomic(page);
1070334f485dSMiklos Szeredi 			void *buf = mapaddr + offset;
1071334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, &buf, &count);
10722408f6efSCong Wang 			kunmap_atomic(mapaddr);
1073334f485dSMiklos Szeredi 		} else
1074334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, NULL, &count);
1075334f485dSMiklos Szeredi 	}
1076334f485dSMiklos Szeredi 	if (page && !cs->write)
1077334f485dSMiklos Szeredi 		flush_dcache_page(page);
1078334f485dSMiklos Szeredi 	return 0;
1079334f485dSMiklos Szeredi }
1080334f485dSMiklos Szeredi 
1081334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */
1082334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
1083334f485dSMiklos Szeredi 			   int zeroing)
1084334f485dSMiklos Szeredi {
1085334f485dSMiklos Szeredi 	unsigned i;
1086334f485dSMiklos Szeredi 	struct fuse_req *req = cs->req;
1087334f485dSMiklos Szeredi 
1088334f485dSMiklos Szeredi 	for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
1089ce534fb0SMiklos Szeredi 		int err;
109085f40aecSMaxim Patlasov 		unsigned offset = req->page_descs[i].offset;
109185f40aecSMaxim Patlasov 		unsigned count = min(nbytes, req->page_descs[i].length);
1092ce534fb0SMiklos Szeredi 
1093ce534fb0SMiklos Szeredi 		err = fuse_copy_page(cs, &req->pages[i], offset, count,
1094ce534fb0SMiklos Szeredi 				     zeroing);
1095334f485dSMiklos Szeredi 		if (err)
1096334f485dSMiklos Szeredi 			return err;
1097334f485dSMiklos Szeredi 
1098334f485dSMiklos Szeredi 		nbytes -= count;
1099334f485dSMiklos Szeredi 	}
1100334f485dSMiklos Szeredi 	return 0;
1101334f485dSMiklos Szeredi }
1102334f485dSMiklos Szeredi 
1103334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */
1104334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
1105334f485dSMiklos Szeredi {
1106334f485dSMiklos Szeredi 	while (size) {
11071729a16cSMiklos Szeredi 		if (!cs->len) {
11081729a16cSMiklos Szeredi 			int err = fuse_copy_fill(cs);
11091729a16cSMiklos Szeredi 			if (err)
1110334f485dSMiklos Szeredi 				return err;
11111729a16cSMiklos Szeredi 		}
1112334f485dSMiklos Szeredi 		fuse_copy_do(cs, &val, &size);
1113334f485dSMiklos Szeredi 	}
1114334f485dSMiklos Szeredi 	return 0;
1115334f485dSMiklos Szeredi }
1116334f485dSMiklos Szeredi 
1117334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */
1118334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
1119334f485dSMiklos Szeredi 			  unsigned argpages, struct fuse_arg *args,
1120334f485dSMiklos Szeredi 			  int zeroing)
1121334f485dSMiklos Szeredi {
1122334f485dSMiklos Szeredi 	int err = 0;
1123334f485dSMiklos Szeredi 	unsigned i;
1124334f485dSMiklos Szeredi 
1125334f485dSMiklos Szeredi 	for (i = 0; !err && i < numargs; i++)  {
1126334f485dSMiklos Szeredi 		struct fuse_arg *arg = &args[i];
1127334f485dSMiklos Szeredi 		if (i == numargs - 1 && argpages)
1128334f485dSMiklos Szeredi 			err = fuse_copy_pages(cs, arg->size, zeroing);
1129334f485dSMiklos Szeredi 		else
1130334f485dSMiklos Szeredi 			err = fuse_copy_one(cs, arg->value, arg->size);
1131334f485dSMiklos Szeredi 	}
1132334f485dSMiklos Szeredi 	return err;
1133334f485dSMiklos Szeredi }
1134334f485dSMiklos Szeredi 
1135f88996a9SMiklos Szeredi static int forget_pending(struct fuse_iqueue *fiq)
113607e77dcaSMiklos Szeredi {
1137f88996a9SMiklos Szeredi 	return fiq->forget_list_head.next != NULL;
113807e77dcaSMiklos Szeredi }
113907e77dcaSMiklos Szeredi 
1140f88996a9SMiklos Szeredi static int request_pending(struct fuse_iqueue *fiq)
1141a4d27e75SMiklos Szeredi {
1142f88996a9SMiklos Szeredi 	return !list_empty(&fiq->pending) || !list_empty(&fiq->interrupts) ||
1143f88996a9SMiklos Szeredi 		forget_pending(fiq);
1144a4d27e75SMiklos Szeredi }
1145a4d27e75SMiklos Szeredi 
1146334f485dSMiklos Szeredi /*
1147a4d27e75SMiklos Szeredi  * Transfer an interrupt request to userspace
1148a4d27e75SMiklos Szeredi  *
1149a4d27e75SMiklos Szeredi  * Unlike other requests this is assembled on demand, without a need
1150a4d27e75SMiklos Szeredi  * to allocate a separate fuse_req structure.
1151a4d27e75SMiklos Szeredi  *
1152fd22d62eSMiklos Szeredi  * Called with fiq->waitq.lock held, releases it
1153a4d27e75SMiklos Szeredi  */
1154fd22d62eSMiklos Szeredi static int fuse_read_interrupt(struct fuse_iqueue *fiq,
1155fd22d62eSMiklos Szeredi 			       struct fuse_copy_state *cs,
1156c3021629SMiklos Szeredi 			       size_t nbytes, struct fuse_req *req)
1157fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock)
1158a4d27e75SMiklos Szeredi {
1159a4d27e75SMiklos Szeredi 	struct fuse_in_header ih;
1160a4d27e75SMiklos Szeredi 	struct fuse_interrupt_in arg;
1161a4d27e75SMiklos Szeredi 	unsigned reqsize = sizeof(ih) + sizeof(arg);
1162a4d27e75SMiklos Szeredi 	int err;
1163a4d27e75SMiklos Szeredi 
1164a4d27e75SMiklos Szeredi 	list_del_init(&req->intr_entry);
1165a4d27e75SMiklos Szeredi 	memset(&ih, 0, sizeof(ih));
1166a4d27e75SMiklos Szeredi 	memset(&arg, 0, sizeof(arg));
1167a4d27e75SMiklos Szeredi 	ih.len = reqsize;
1168a4d27e75SMiklos Szeredi 	ih.opcode = FUSE_INTERRUPT;
11693a5358d1SKirill Tkhai 	ih.unique = (req->in.h.unique | FUSE_INT_REQ_BIT);
1170a4d27e75SMiklos Szeredi 	arg.unique = req->in.h.unique;
1171a4d27e75SMiklos Szeredi 
11724ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
1173c3021629SMiklos Szeredi 	if (nbytes < reqsize)
1174a4d27e75SMiklos Szeredi 		return -EINVAL;
1175a4d27e75SMiklos Szeredi 
1176c3021629SMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
1177a4d27e75SMiklos Szeredi 	if (!err)
1178c3021629SMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
1179c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
1180a4d27e75SMiklos Szeredi 
1181a4d27e75SMiklos Szeredi 	return err ? err : reqsize;
1182a4d27e75SMiklos Szeredi }
1183a4d27e75SMiklos Szeredi 
1184f88996a9SMiklos Szeredi static struct fuse_forget_link *dequeue_forget(struct fuse_iqueue *fiq,
118502c048b9SMiklos Szeredi 					       unsigned max,
118602c048b9SMiklos Szeredi 					       unsigned *countp)
118707e77dcaSMiklos Szeredi {
1188f88996a9SMiklos Szeredi 	struct fuse_forget_link *head = fiq->forget_list_head.next;
118902c048b9SMiklos Szeredi 	struct fuse_forget_link **newhead = &head;
119002c048b9SMiklos Szeredi 	unsigned count;
119107e77dcaSMiklos Szeredi 
119202c048b9SMiklos Szeredi 	for (count = 0; *newhead != NULL && count < max; count++)
119302c048b9SMiklos Szeredi 		newhead = &(*newhead)->next;
119402c048b9SMiklos Szeredi 
1195f88996a9SMiklos Szeredi 	fiq->forget_list_head.next = *newhead;
119602c048b9SMiklos Szeredi 	*newhead = NULL;
1197f88996a9SMiklos Szeredi 	if (fiq->forget_list_head.next == NULL)
1198f88996a9SMiklos Szeredi 		fiq->forget_list_tail = &fiq->forget_list_head;
119907e77dcaSMiklos Szeredi 
120002c048b9SMiklos Szeredi 	if (countp != NULL)
120102c048b9SMiklos Szeredi 		*countp = count;
120202c048b9SMiklos Szeredi 
120302c048b9SMiklos Szeredi 	return head;
120407e77dcaSMiklos Szeredi }
120507e77dcaSMiklos Szeredi 
1206fd22d62eSMiklos Szeredi static int fuse_read_single_forget(struct fuse_iqueue *fiq,
120707e77dcaSMiklos Szeredi 				   struct fuse_copy_state *cs,
120807e77dcaSMiklos Szeredi 				   size_t nbytes)
1209fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock)
121007e77dcaSMiklos Szeredi {
121107e77dcaSMiklos Szeredi 	int err;
1212f88996a9SMiklos Szeredi 	struct fuse_forget_link *forget = dequeue_forget(fiq, 1, NULL);
121307e77dcaSMiklos Szeredi 	struct fuse_forget_in arg = {
121402c048b9SMiklos Szeredi 		.nlookup = forget->forget_one.nlookup,
121507e77dcaSMiklos Szeredi 	};
121607e77dcaSMiklos Szeredi 	struct fuse_in_header ih = {
121707e77dcaSMiklos Szeredi 		.opcode = FUSE_FORGET,
121802c048b9SMiklos Szeredi 		.nodeid = forget->forget_one.nodeid,
1219f88996a9SMiklos Szeredi 		.unique = fuse_get_unique(fiq),
122007e77dcaSMiklos Szeredi 		.len = sizeof(ih) + sizeof(arg),
122107e77dcaSMiklos Szeredi 	};
122207e77dcaSMiklos Szeredi 
12234ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
122407e77dcaSMiklos Szeredi 	kfree(forget);
122507e77dcaSMiklos Szeredi 	if (nbytes < ih.len)
122607e77dcaSMiklos Szeredi 		return -EINVAL;
122707e77dcaSMiklos Szeredi 
122807e77dcaSMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
122907e77dcaSMiklos Szeredi 	if (!err)
123007e77dcaSMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
123107e77dcaSMiklos Szeredi 	fuse_copy_finish(cs);
123207e77dcaSMiklos Szeredi 
123307e77dcaSMiklos Szeredi 	if (err)
123407e77dcaSMiklos Szeredi 		return err;
123507e77dcaSMiklos Szeredi 
123607e77dcaSMiklos Szeredi 	return ih.len;
123707e77dcaSMiklos Szeredi }
123807e77dcaSMiklos Szeredi 
1239fd22d62eSMiklos Szeredi static int fuse_read_batch_forget(struct fuse_iqueue *fiq,
124002c048b9SMiklos Szeredi 				   struct fuse_copy_state *cs, size_t nbytes)
1241fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock)
124202c048b9SMiklos Szeredi {
124302c048b9SMiklos Szeredi 	int err;
124402c048b9SMiklos Szeredi 	unsigned max_forgets;
124502c048b9SMiklos Szeredi 	unsigned count;
124602c048b9SMiklos Szeredi 	struct fuse_forget_link *head;
124702c048b9SMiklos Szeredi 	struct fuse_batch_forget_in arg = { .count = 0 };
124802c048b9SMiklos Szeredi 	struct fuse_in_header ih = {
124902c048b9SMiklos Szeredi 		.opcode = FUSE_BATCH_FORGET,
1250f88996a9SMiklos Szeredi 		.unique = fuse_get_unique(fiq),
125102c048b9SMiklos Szeredi 		.len = sizeof(ih) + sizeof(arg),
125202c048b9SMiklos Szeredi 	};
125302c048b9SMiklos Szeredi 
125402c048b9SMiklos Szeredi 	if (nbytes < ih.len) {
12554ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
125602c048b9SMiklos Szeredi 		return -EINVAL;
125702c048b9SMiklos Szeredi 	}
125802c048b9SMiklos Szeredi 
125902c048b9SMiklos Szeredi 	max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one);
1260f88996a9SMiklos Szeredi 	head = dequeue_forget(fiq, max_forgets, &count);
12614ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
126202c048b9SMiklos Szeredi 
126302c048b9SMiklos Szeredi 	arg.count = count;
126402c048b9SMiklos Szeredi 	ih.len += count * sizeof(struct fuse_forget_one);
126502c048b9SMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
126602c048b9SMiklos Szeredi 	if (!err)
126702c048b9SMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
126802c048b9SMiklos Szeredi 
126902c048b9SMiklos Szeredi 	while (head) {
127002c048b9SMiklos Szeredi 		struct fuse_forget_link *forget = head;
127102c048b9SMiklos Szeredi 
127202c048b9SMiklos Szeredi 		if (!err) {
127302c048b9SMiklos Szeredi 			err = fuse_copy_one(cs, &forget->forget_one,
127402c048b9SMiklos Szeredi 					    sizeof(forget->forget_one));
127502c048b9SMiklos Szeredi 		}
127602c048b9SMiklos Szeredi 		head = forget->next;
127702c048b9SMiklos Szeredi 		kfree(forget);
127802c048b9SMiklos Szeredi 	}
127902c048b9SMiklos Szeredi 
128002c048b9SMiklos Szeredi 	fuse_copy_finish(cs);
128102c048b9SMiklos Szeredi 
128202c048b9SMiklos Szeredi 	if (err)
128302c048b9SMiklos Szeredi 		return err;
128402c048b9SMiklos Szeredi 
128502c048b9SMiklos Szeredi 	return ih.len;
128602c048b9SMiklos Szeredi }
128702c048b9SMiklos Szeredi 
1288fd22d62eSMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq,
1289fd22d62eSMiklos Szeredi 			    struct fuse_copy_state *cs,
129002c048b9SMiklos Szeredi 			    size_t nbytes)
1291fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock)
129202c048b9SMiklos Szeredi {
1293f88996a9SMiklos Szeredi 	if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL)
1294fd22d62eSMiklos Szeredi 		return fuse_read_single_forget(fiq, cs, nbytes);
129502c048b9SMiklos Szeredi 	else
1296fd22d62eSMiklos Szeredi 		return fuse_read_batch_forget(fiq, cs, nbytes);
129702c048b9SMiklos Szeredi }
129802c048b9SMiklos Szeredi 
1299a4d27e75SMiklos Szeredi /*
1300334f485dSMiklos Szeredi  * Read a single request into the userspace filesystem's buffer.  This
1301334f485dSMiklos Szeredi  * function waits until a request is available, then removes it from
1302334f485dSMiklos Szeredi  * the pending list and copies request data to userspace buffer.  If
1303f9a2842eSMiklos Szeredi  * no reply is needed (FORGET) or request has been aborted or there
1304f9a2842eSMiklos Szeredi  * was an error during the copying then it's finished by calling
1305334f485dSMiklos Szeredi  * request_end().  Otherwise add it to the processing list, and set
1306334f485dSMiklos Szeredi  * the 'sent' flag.
1307334f485dSMiklos Szeredi  */
1308c3696046SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
1309c3021629SMiklos Szeredi 				struct fuse_copy_state *cs, size_t nbytes)
1310334f485dSMiklos Szeredi {
131182cbdcd3SMiklos Szeredi 	ssize_t err;
1312c3696046SMiklos Szeredi 	struct fuse_conn *fc = fud->fc;
1313f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
1314c3696046SMiklos Szeredi 	struct fuse_pqueue *fpq = &fud->pq;
1315334f485dSMiklos Szeredi 	struct fuse_req *req;
1316334f485dSMiklos Szeredi 	struct fuse_in *in;
1317334f485dSMiklos Szeredi 	unsigned reqsize;
1318be2ff42cSKirill Tkhai 	unsigned int hash;
1319334f485dSMiklos Szeredi 
13201d3d752bSMiklos Szeredi  restart:
13214ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
1322e5ac1d1eSJeff Dike 	err = -EAGAIN;
1323e16714d8SMiklos Szeredi 	if ((file->f_flags & O_NONBLOCK) && fiq->connected &&
1324f88996a9SMiklos Szeredi 	    !request_pending(fiq))
1325e5ac1d1eSJeff Dike 		goto err_unlock;
1326e5ac1d1eSJeff Dike 
13275250921bSMiklos Szeredi 	err = wait_event_interruptible_exclusive_locked(fiq->waitq,
13285250921bSMiklos Szeredi 				!fiq->connected || request_pending(fiq));
13295250921bSMiklos Szeredi 	if (err)
13305250921bSMiklos Szeredi 		goto err_unlock;
13315250921bSMiklos Szeredi 
13323b7008b2SSzymon Lukasz 	if (!fiq->connected) {
1333eb98e3bdSMiklos Szeredi 		err = fc->aborted ? -ECONNABORTED : -ENODEV;
1334334f485dSMiklos Szeredi 		goto err_unlock;
13353b7008b2SSzymon Lukasz 	}
1336334f485dSMiklos Szeredi 
1337f88996a9SMiklos Szeredi 	if (!list_empty(&fiq->interrupts)) {
1338f88996a9SMiklos Szeredi 		req = list_entry(fiq->interrupts.next, struct fuse_req,
1339a4d27e75SMiklos Szeredi 				 intr_entry);
1340fd22d62eSMiklos Szeredi 		return fuse_read_interrupt(fiq, cs, nbytes, req);
1341a4d27e75SMiklos Szeredi 	}
1342a4d27e75SMiklos Szeredi 
1343f88996a9SMiklos Szeredi 	if (forget_pending(fiq)) {
1344f88996a9SMiklos Szeredi 		if (list_empty(&fiq->pending) || fiq->forget_batch-- > 0)
1345fd22d62eSMiklos Szeredi 			return fuse_read_forget(fc, fiq, cs, nbytes);
134607e77dcaSMiklos Szeredi 
1347f88996a9SMiklos Szeredi 		if (fiq->forget_batch <= -8)
1348f88996a9SMiklos Szeredi 			fiq->forget_batch = 16;
134907e77dcaSMiklos Szeredi 	}
135007e77dcaSMiklos Szeredi 
1351f88996a9SMiklos Szeredi 	req = list_entry(fiq->pending.next, struct fuse_req, list);
135233e14b4dSMiklos Szeredi 	clear_bit(FR_PENDING, &req->flags);
1353ef759258SMiklos Szeredi 	list_del_init(&req->list);
13544ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
13554ce60812SMiklos Szeredi 
1356334f485dSMiklos Szeredi 	in = &req->in;
13571d3d752bSMiklos Szeredi 	reqsize = in->h.len;
13585d6d3a30SMiklos Szeredi 
13591d3d752bSMiklos Szeredi 	/* If request is too large, reply with an error and restart the read */
1360c3021629SMiklos Szeredi 	if (nbytes < reqsize) {
13611d3d752bSMiklos Szeredi 		req->out.h.error = -EIO;
13621d3d752bSMiklos Szeredi 		/* SETXATTR is special, since it may contain too large data */
13631d3d752bSMiklos Szeredi 		if (in->h.opcode == FUSE_SETXATTR)
13641d3d752bSMiklos Szeredi 			req->out.h.error = -E2BIG;
13651d3d752bSMiklos Szeredi 		request_end(fc, req);
13661d3d752bSMiklos Szeredi 		goto restart;
13671d3d752bSMiklos Szeredi 	}
136845a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
136982cbdcd3SMiklos Szeredi 	list_add(&req->list, &fpq->io);
137045a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1371c3021629SMiklos Szeredi 	cs->req = req;
1372c3021629SMiklos Szeredi 	err = fuse_copy_one(cs, &in->h, sizeof(in->h));
1373334f485dSMiklos Szeredi 	if (!err)
1374c3021629SMiklos Szeredi 		err = fuse_copy_args(cs, in->numargs, in->argpages,
1375334f485dSMiklos Szeredi 				     (struct fuse_arg *) in->args, 0);
1376c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
137745a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1378825d6d33SMiklos Szeredi 	clear_bit(FR_LOCKED, &req->flags);
1379e96edd94SMiklos Szeredi 	if (!fpq->connected) {
1380eb98e3bdSMiklos Szeredi 		err = fc->aborted ? -ECONNABORTED : -ENODEV;
138182cbdcd3SMiklos Szeredi 		goto out_end;
1382c9c9d7dfSMiklos Szeredi 	}
1383334f485dSMiklos Szeredi 	if (err) {
1384334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
138582cbdcd3SMiklos Szeredi 		goto out_end;
1386334f485dSMiklos Szeredi 	}
1387825d6d33SMiklos Szeredi 	if (!test_bit(FR_ISREPLY, &req->flags)) {
138882cbdcd3SMiklos Szeredi 		err = reqsize;
138982cbdcd3SMiklos Szeredi 		goto out_end;
139082cbdcd3SMiklos Szeredi 	}
1391be2ff42cSKirill Tkhai 	hash = fuse_req_hash(req->in.h.unique);
1392be2ff42cSKirill Tkhai 	list_move_tail(&req->list, &fpq->processing[hash]);
1393bc78abbdSKirill Tkhai 	__fuse_get_request(req);
13948f7bb368SMiklos Szeredi 	set_bit(FR_SENT, &req->flags);
13954c316f2fSMiklos Szeredi 	spin_unlock(&fpq->lock);
13968f7bb368SMiklos Szeredi 	/* matches barrier in request_wait_answer() */
13978f7bb368SMiklos Szeredi 	smp_mb__after_atomic();
1398825d6d33SMiklos Szeredi 	if (test_bit(FR_INTERRUPTED, &req->flags))
1399f88996a9SMiklos Szeredi 		queue_interrupt(fiq, req);
1400bc78abbdSKirill Tkhai 	fuse_put_request(fc, req);
140182cbdcd3SMiklos Szeredi 
1402334f485dSMiklos Szeredi 	return reqsize;
1403334f485dSMiklos Szeredi 
140482cbdcd3SMiklos Szeredi out_end:
140577cd9d48SMiklos Szeredi 	if (!test_bit(FR_PRIVATE, &req->flags))
140682cbdcd3SMiklos Szeredi 		list_del_init(&req->list);
140745a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
140882cbdcd3SMiklos Szeredi 	request_end(fc, req);
140982cbdcd3SMiklos Szeredi 	return err;
141082cbdcd3SMiklos Szeredi 
1411334f485dSMiklos Szeredi  err_unlock:
14124ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
1413334f485dSMiklos Szeredi 	return err;
1414334f485dSMiklos Szeredi }
1415334f485dSMiklos Szeredi 
141694e4fe2cSTom Van Braeckel static int fuse_dev_open(struct inode *inode, struct file *file)
141794e4fe2cSTom Van Braeckel {
141894e4fe2cSTom Van Braeckel 	/*
141994e4fe2cSTom Van Braeckel 	 * The fuse device's file's private_data is used to hold
142094e4fe2cSTom Van Braeckel 	 * the fuse_conn(ection) when it is mounted, and is used to
142194e4fe2cSTom Van Braeckel 	 * keep track of whether the file has been mounted already.
142294e4fe2cSTom Van Braeckel 	 */
142394e4fe2cSTom Van Braeckel 	file->private_data = NULL;
142494e4fe2cSTom Van Braeckel 	return 0;
142594e4fe2cSTom Van Braeckel }
142694e4fe2cSTom Van Braeckel 
1427fbdbaccaSAl Viro static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to)
1428c3021629SMiklos Szeredi {
1429c3021629SMiklos Szeredi 	struct fuse_copy_state cs;
1430c3021629SMiklos Szeredi 	struct file *file = iocb->ki_filp;
1431cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
1432cc080e9eSMiklos Szeredi 
1433cc080e9eSMiklos Szeredi 	if (!fud)
1434c3021629SMiklos Szeredi 		return -EPERM;
1435c3021629SMiklos Szeredi 
1436fbdbaccaSAl Viro 	if (!iter_is_iovec(to))
1437fbdbaccaSAl Viro 		return -EINVAL;
1438c3021629SMiklos Szeredi 
1439dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 1, to);
1440fbdbaccaSAl Viro 
1441c3696046SMiklos Szeredi 	return fuse_dev_do_read(fud, file, &cs, iov_iter_count(to));
1442c3021629SMiklos Szeredi }
1443c3021629SMiklos Szeredi 
1444c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
1445c3021629SMiklos Szeredi 				    struct pipe_inode_info *pipe,
1446c3021629SMiklos Szeredi 				    size_t len, unsigned int flags)
1447c3021629SMiklos Szeredi {
1448d82718e3SAl Viro 	int total, ret;
1449c3021629SMiklos Szeredi 	int page_nr = 0;
1450c3021629SMiklos Szeredi 	struct pipe_buffer *bufs;
1451c3021629SMiklos Szeredi 	struct fuse_copy_state cs;
1452cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(in);
1453cc080e9eSMiklos Szeredi 
1454cc080e9eSMiklos Szeredi 	if (!fud)
1455c3021629SMiklos Szeredi 		return -EPERM;
1456c3021629SMiklos Szeredi 
1457d6d931adSAndrey Ryabinin 	bufs = kvmalloc_array(pipe->buffers, sizeof(struct pipe_buffer),
14586da2ec56SKees Cook 			      GFP_KERNEL);
1459c3021629SMiklos Szeredi 	if (!bufs)
1460c3021629SMiklos Szeredi 		return -ENOMEM;
1461c3021629SMiklos Szeredi 
1462dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 1, NULL);
1463c3021629SMiklos Szeredi 	cs.pipebufs = bufs;
1464c3021629SMiklos Szeredi 	cs.pipe = pipe;
1465c3696046SMiklos Szeredi 	ret = fuse_dev_do_read(fud, in, &cs, len);
1466c3021629SMiklos Szeredi 	if (ret < 0)
1467c3021629SMiklos Szeredi 		goto out;
1468c3021629SMiklos Szeredi 
1469c3021629SMiklos Szeredi 	if (pipe->nrbufs + cs.nr_segs > pipe->buffers) {
1470c3021629SMiklos Szeredi 		ret = -EIO;
1471d82718e3SAl Viro 		goto out;
1472c3021629SMiklos Szeredi 	}
1473c3021629SMiklos Szeredi 
1474d82718e3SAl Viro 	for (ret = total = 0; page_nr < cs.nr_segs; total += ret) {
147528a625cbSMiklos Szeredi 		/*
147628a625cbSMiklos Szeredi 		 * Need to be careful about this.  Having buf->ops in module
147728a625cbSMiklos Szeredi 		 * code can Oops if the buffer persists after module unload.
147828a625cbSMiklos Szeredi 		 */
1479d82718e3SAl Viro 		bufs[page_nr].ops = &nosteal_pipe_buf_ops;
148084588a93SMiklos Szeredi 		bufs[page_nr].flags = 0;
1481d82718e3SAl Viro 		ret = add_to_pipe(pipe, &bufs[page_nr++]);
1482d82718e3SAl Viro 		if (unlikely(ret < 0))
1483d82718e3SAl Viro 			break;
1484c3021629SMiklos Szeredi 	}
1485d82718e3SAl Viro 	if (total)
1486d82718e3SAl Viro 		ret = total;
1487c3021629SMiklos Szeredi out:
1488c3021629SMiklos Szeredi 	for (; page_nr < cs.nr_segs; page_nr++)
148909cbfeafSKirill A. Shutemov 		put_page(bufs[page_nr].page);
1490c3021629SMiklos Szeredi 
1491d6d931adSAndrey Ryabinin 	kvfree(bufs);
1492c3021629SMiklos Szeredi 	return ret;
1493c3021629SMiklos Szeredi }
1494c3021629SMiklos Szeredi 
149595668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size,
149695668a69STejun Heo 			    struct fuse_copy_state *cs)
149795668a69STejun Heo {
149895668a69STejun Heo 	struct fuse_notify_poll_wakeup_out outarg;
1499f6d47a17SMiklos Szeredi 	int err = -EINVAL;
150095668a69STejun Heo 
150195668a69STejun Heo 	if (size != sizeof(outarg))
1502f6d47a17SMiklos Szeredi 		goto err;
150395668a69STejun Heo 
150495668a69STejun Heo 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
150595668a69STejun Heo 	if (err)
1506f6d47a17SMiklos Szeredi 		goto err;
150795668a69STejun Heo 
1508f6d47a17SMiklos Szeredi 	fuse_copy_finish(cs);
150995668a69STejun Heo 	return fuse_notify_poll_wakeup(fc, &outarg);
1510f6d47a17SMiklos Szeredi 
1511f6d47a17SMiklos Szeredi err:
1512f6d47a17SMiklos Szeredi 	fuse_copy_finish(cs);
1513f6d47a17SMiklos Szeredi 	return err;
151495668a69STejun Heo }
151595668a69STejun Heo 
15163b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size,
15173b463ae0SJohn Muir 				   struct fuse_copy_state *cs)
15183b463ae0SJohn Muir {
15193b463ae0SJohn Muir 	struct fuse_notify_inval_inode_out outarg;
15203b463ae0SJohn Muir 	int err = -EINVAL;
15213b463ae0SJohn Muir 
15223b463ae0SJohn Muir 	if (size != sizeof(outarg))
15233b463ae0SJohn Muir 		goto err;
15243b463ae0SJohn Muir 
15253b463ae0SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
15263b463ae0SJohn Muir 	if (err)
15273b463ae0SJohn Muir 		goto err;
15283b463ae0SJohn Muir 	fuse_copy_finish(cs);
15293b463ae0SJohn Muir 
15303b463ae0SJohn Muir 	down_read(&fc->killsb);
15313b463ae0SJohn Muir 	err = -ENOENT;
1532b21dda43SMiklos Szeredi 	if (fc->sb) {
15333b463ae0SJohn Muir 		err = fuse_reverse_inval_inode(fc->sb, outarg.ino,
15343b463ae0SJohn Muir 					       outarg.off, outarg.len);
1535b21dda43SMiklos Szeredi 	}
15363b463ae0SJohn Muir 	up_read(&fc->killsb);
15373b463ae0SJohn Muir 	return err;
15383b463ae0SJohn Muir 
15393b463ae0SJohn Muir err:
15403b463ae0SJohn Muir 	fuse_copy_finish(cs);
15413b463ae0SJohn Muir 	return err;
15423b463ae0SJohn Muir }
15433b463ae0SJohn Muir 
15443b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size,
15453b463ae0SJohn Muir 				   struct fuse_copy_state *cs)
15463b463ae0SJohn Muir {
15473b463ae0SJohn Muir 	struct fuse_notify_inval_entry_out outarg;
1548b2d82ee3SFang Wenqi 	int err = -ENOMEM;
1549b2d82ee3SFang Wenqi 	char *buf;
15503b463ae0SJohn Muir 	struct qstr name;
15513b463ae0SJohn Muir 
1552b2d82ee3SFang Wenqi 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
1553b2d82ee3SFang Wenqi 	if (!buf)
1554b2d82ee3SFang Wenqi 		goto err;
1555b2d82ee3SFang Wenqi 
1556b2d82ee3SFang Wenqi 	err = -EINVAL;
15573b463ae0SJohn Muir 	if (size < sizeof(outarg))
15583b463ae0SJohn Muir 		goto err;
15593b463ae0SJohn Muir 
15603b463ae0SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
15613b463ae0SJohn Muir 	if (err)
15623b463ae0SJohn Muir 		goto err;
15633b463ae0SJohn Muir 
15643b463ae0SJohn Muir 	err = -ENAMETOOLONG;
15653b463ae0SJohn Muir 	if (outarg.namelen > FUSE_NAME_MAX)
15663b463ae0SJohn Muir 		goto err;
15673b463ae0SJohn Muir 
1568c2183d1eSMiklos Szeredi 	err = -EINVAL;
1569c2183d1eSMiklos Szeredi 	if (size != sizeof(outarg) + outarg.namelen + 1)
1570c2183d1eSMiklos Szeredi 		goto err;
1571c2183d1eSMiklos Szeredi 
15723b463ae0SJohn Muir 	name.name = buf;
15733b463ae0SJohn Muir 	name.len = outarg.namelen;
15743b463ae0SJohn Muir 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
15753b463ae0SJohn Muir 	if (err)
15763b463ae0SJohn Muir 		goto err;
15773b463ae0SJohn Muir 	fuse_copy_finish(cs);
15783b463ae0SJohn Muir 	buf[outarg.namelen] = 0;
15793b463ae0SJohn Muir 
15803b463ae0SJohn Muir 	down_read(&fc->killsb);
15813b463ae0SJohn Muir 	err = -ENOENT;
1582b21dda43SMiklos Szeredi 	if (fc->sb)
1583451d0f59SJohn Muir 		err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 0, &name);
1584451d0f59SJohn Muir 	up_read(&fc->killsb);
1585451d0f59SJohn Muir 	kfree(buf);
1586451d0f59SJohn Muir 	return err;
1587451d0f59SJohn Muir 
1588451d0f59SJohn Muir err:
1589451d0f59SJohn Muir 	kfree(buf);
1590451d0f59SJohn Muir 	fuse_copy_finish(cs);
1591451d0f59SJohn Muir 	return err;
1592451d0f59SJohn Muir }
1593451d0f59SJohn Muir 
1594451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size,
1595451d0f59SJohn Muir 			      struct fuse_copy_state *cs)
1596451d0f59SJohn Muir {
1597451d0f59SJohn Muir 	struct fuse_notify_delete_out outarg;
1598451d0f59SJohn Muir 	int err = -ENOMEM;
1599451d0f59SJohn Muir 	char *buf;
1600451d0f59SJohn Muir 	struct qstr name;
1601451d0f59SJohn Muir 
1602451d0f59SJohn Muir 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
1603451d0f59SJohn Muir 	if (!buf)
1604451d0f59SJohn Muir 		goto err;
1605451d0f59SJohn Muir 
1606451d0f59SJohn Muir 	err = -EINVAL;
1607451d0f59SJohn Muir 	if (size < sizeof(outarg))
1608451d0f59SJohn Muir 		goto err;
1609451d0f59SJohn Muir 
1610451d0f59SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
1611451d0f59SJohn Muir 	if (err)
1612451d0f59SJohn Muir 		goto err;
1613451d0f59SJohn Muir 
1614451d0f59SJohn Muir 	err = -ENAMETOOLONG;
1615451d0f59SJohn Muir 	if (outarg.namelen > FUSE_NAME_MAX)
1616451d0f59SJohn Muir 		goto err;
1617451d0f59SJohn Muir 
1618451d0f59SJohn Muir 	err = -EINVAL;
1619451d0f59SJohn Muir 	if (size != sizeof(outarg) + outarg.namelen + 1)
1620451d0f59SJohn Muir 		goto err;
1621451d0f59SJohn Muir 
1622451d0f59SJohn Muir 	name.name = buf;
1623451d0f59SJohn Muir 	name.len = outarg.namelen;
1624451d0f59SJohn Muir 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
1625451d0f59SJohn Muir 	if (err)
1626451d0f59SJohn Muir 		goto err;
1627451d0f59SJohn Muir 	fuse_copy_finish(cs);
1628451d0f59SJohn Muir 	buf[outarg.namelen] = 0;
1629451d0f59SJohn Muir 
1630451d0f59SJohn Muir 	down_read(&fc->killsb);
1631451d0f59SJohn Muir 	err = -ENOENT;
1632451d0f59SJohn Muir 	if (fc->sb)
1633451d0f59SJohn Muir 		err = fuse_reverse_inval_entry(fc->sb, outarg.parent,
1634451d0f59SJohn Muir 					       outarg.child, &name);
16353b463ae0SJohn Muir 	up_read(&fc->killsb);
1636b2d82ee3SFang Wenqi 	kfree(buf);
16373b463ae0SJohn Muir 	return err;
16383b463ae0SJohn Muir 
16393b463ae0SJohn Muir err:
1640b2d82ee3SFang Wenqi 	kfree(buf);
16413b463ae0SJohn Muir 	fuse_copy_finish(cs);
16423b463ae0SJohn Muir 	return err;
16433b463ae0SJohn Muir }
16443b463ae0SJohn Muir 
1645a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
1646a1d75f25SMiklos Szeredi 			     struct fuse_copy_state *cs)
1647a1d75f25SMiklos Szeredi {
1648a1d75f25SMiklos Szeredi 	struct fuse_notify_store_out outarg;
1649a1d75f25SMiklos Szeredi 	struct inode *inode;
1650a1d75f25SMiklos Szeredi 	struct address_space *mapping;
1651a1d75f25SMiklos Szeredi 	u64 nodeid;
1652a1d75f25SMiklos Szeredi 	int err;
1653a1d75f25SMiklos Szeredi 	pgoff_t index;
1654a1d75f25SMiklos Szeredi 	unsigned int offset;
1655a1d75f25SMiklos Szeredi 	unsigned int num;
1656a1d75f25SMiklos Szeredi 	loff_t file_size;
1657a1d75f25SMiklos Szeredi 	loff_t end;
1658a1d75f25SMiklos Szeredi 
1659a1d75f25SMiklos Szeredi 	err = -EINVAL;
1660a1d75f25SMiklos Szeredi 	if (size < sizeof(outarg))
1661a1d75f25SMiklos Szeredi 		goto out_finish;
1662a1d75f25SMiklos Szeredi 
1663a1d75f25SMiklos Szeredi 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
1664a1d75f25SMiklos Szeredi 	if (err)
1665a1d75f25SMiklos Szeredi 		goto out_finish;
1666a1d75f25SMiklos Szeredi 
1667a1d75f25SMiklos Szeredi 	err = -EINVAL;
1668a1d75f25SMiklos Szeredi 	if (size - sizeof(outarg) != outarg.size)
1669a1d75f25SMiklos Szeredi 		goto out_finish;
1670a1d75f25SMiklos Szeredi 
1671a1d75f25SMiklos Szeredi 	nodeid = outarg.nodeid;
1672a1d75f25SMiklos Szeredi 
1673a1d75f25SMiklos Szeredi 	down_read(&fc->killsb);
1674a1d75f25SMiklos Szeredi 
1675a1d75f25SMiklos Szeredi 	err = -ENOENT;
1676a1d75f25SMiklos Szeredi 	if (!fc->sb)
1677a1d75f25SMiklos Szeredi 		goto out_up_killsb;
1678a1d75f25SMiklos Szeredi 
1679a1d75f25SMiklos Szeredi 	inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
1680a1d75f25SMiklos Szeredi 	if (!inode)
1681a1d75f25SMiklos Szeredi 		goto out_up_killsb;
1682a1d75f25SMiklos Szeredi 
1683a1d75f25SMiklos Szeredi 	mapping = inode->i_mapping;
168409cbfeafSKirill A. Shutemov 	index = outarg.offset >> PAGE_SHIFT;
168509cbfeafSKirill A. Shutemov 	offset = outarg.offset & ~PAGE_MASK;
1686a1d75f25SMiklos Szeredi 	file_size = i_size_read(inode);
1687a1d75f25SMiklos Szeredi 	end = outarg.offset + outarg.size;
1688a1d75f25SMiklos Szeredi 	if (end > file_size) {
1689a1d75f25SMiklos Szeredi 		file_size = end;
1690a1d75f25SMiklos Szeredi 		fuse_write_update_size(inode, file_size);
1691a1d75f25SMiklos Szeredi 	}
1692a1d75f25SMiklos Szeredi 
1693a1d75f25SMiklos Szeredi 	num = outarg.size;
1694a1d75f25SMiklos Szeredi 	while (num) {
1695a1d75f25SMiklos Szeredi 		struct page *page;
1696a1d75f25SMiklos Szeredi 		unsigned int this_num;
1697a1d75f25SMiklos Szeredi 
1698a1d75f25SMiklos Szeredi 		err = -ENOMEM;
1699a1d75f25SMiklos Szeredi 		page = find_or_create_page(mapping, index,
1700a1d75f25SMiklos Szeredi 					   mapping_gfp_mask(mapping));
1701a1d75f25SMiklos Szeredi 		if (!page)
1702a1d75f25SMiklos Szeredi 			goto out_iput;
1703a1d75f25SMiklos Szeredi 
170409cbfeafSKirill A. Shutemov 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
1705a1d75f25SMiklos Szeredi 		err = fuse_copy_page(cs, &page, offset, this_num, 0);
1706063ec1e5SMiklos Szeredi 		if (!err && offset == 0 &&
170709cbfeafSKirill A. Shutemov 		    (this_num == PAGE_SIZE || file_size == end))
1708a1d75f25SMiklos Szeredi 			SetPageUptodate(page);
1709a1d75f25SMiklos Szeredi 		unlock_page(page);
171009cbfeafSKirill A. Shutemov 		put_page(page);
1711a1d75f25SMiklos Szeredi 
1712a1d75f25SMiklos Szeredi 		if (err)
1713a1d75f25SMiklos Szeredi 			goto out_iput;
1714a1d75f25SMiklos Szeredi 
1715a1d75f25SMiklos Szeredi 		num -= this_num;
1716a1d75f25SMiklos Szeredi 		offset = 0;
1717a1d75f25SMiklos Szeredi 		index++;
1718a1d75f25SMiklos Szeredi 	}
1719a1d75f25SMiklos Szeredi 
1720a1d75f25SMiklos Szeredi 	err = 0;
1721a1d75f25SMiklos Szeredi 
1722a1d75f25SMiklos Szeredi out_iput:
1723a1d75f25SMiklos Szeredi 	iput(inode);
1724a1d75f25SMiklos Szeredi out_up_killsb:
1725a1d75f25SMiklos Szeredi 	up_read(&fc->killsb);
1726a1d75f25SMiklos Szeredi out_finish:
1727a1d75f25SMiklos Szeredi 	fuse_copy_finish(cs);
1728a1d75f25SMiklos Szeredi 	return err;
1729a1d75f25SMiklos Szeredi }
1730a1d75f25SMiklos Szeredi 
17312d45ba38SMiklos Szeredi static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req)
17322d45ba38SMiklos Szeredi {
1733c6f92f9fSMel Gorman 	release_pages(req->pages, req->num_pages);
17342d45ba38SMiklos Szeredi }
17352d45ba38SMiklos Szeredi 
17362d45ba38SMiklos Szeredi static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
17372d45ba38SMiklos Szeredi 			 struct fuse_notify_retrieve_out *outarg)
17382d45ba38SMiklos Szeredi {
17392d45ba38SMiklos Szeredi 	int err;
17402d45ba38SMiklos Szeredi 	struct address_space *mapping = inode->i_mapping;
17412d45ba38SMiklos Szeredi 	struct fuse_req *req;
17422d45ba38SMiklos Szeredi 	pgoff_t index;
17432d45ba38SMiklos Szeredi 	loff_t file_size;
17442d45ba38SMiklos Szeredi 	unsigned int num;
17452d45ba38SMiklos Szeredi 	unsigned int offset;
17460157443cSGeert Uytterhoeven 	size_t total_len = 0;
17475da784ccSConstantine Shulyupin 	unsigned int num_pages;
17482d45ba38SMiklos Szeredi 
174909cbfeafSKirill A. Shutemov 	offset = outarg->offset & ~PAGE_MASK;
17504d53dc99SMaxim Patlasov 	file_size = i_size_read(inode);
17514d53dc99SMaxim Patlasov 
17524d53dc99SMaxim Patlasov 	num = outarg->size;
17534d53dc99SMaxim Patlasov 	if (outarg->offset > file_size)
17544d53dc99SMaxim Patlasov 		num = 0;
17554d53dc99SMaxim Patlasov 	else if (outarg->offset + num > file_size)
17564d53dc99SMaxim Patlasov 		num = file_size - outarg->offset;
17574d53dc99SMaxim Patlasov 
17584d53dc99SMaxim Patlasov 	num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
17595da784ccSConstantine Shulyupin 	num_pages = min(num_pages, fc->max_pages);
17604d53dc99SMaxim Patlasov 
17614d53dc99SMaxim Patlasov 	req = fuse_get_req(fc, num_pages);
17624d53dc99SMaxim Patlasov 	if (IS_ERR(req))
17634d53dc99SMaxim Patlasov 		return PTR_ERR(req);
17642d45ba38SMiklos Szeredi 
17652d45ba38SMiklos Szeredi 	req->in.h.opcode = FUSE_NOTIFY_REPLY;
17662d45ba38SMiklos Szeredi 	req->in.h.nodeid = outarg->nodeid;
17672d45ba38SMiklos Szeredi 	req->in.numargs = 2;
17682d45ba38SMiklos Szeredi 	req->in.argpages = 1;
17692d45ba38SMiklos Szeredi 	req->end = fuse_retrieve_end;
17702d45ba38SMiklos Szeredi 
177109cbfeafSKirill A. Shutemov 	index = outarg->offset >> PAGE_SHIFT;
17722d45ba38SMiklos Szeredi 
17734d53dc99SMaxim Patlasov 	while (num && req->num_pages < num_pages) {
17742d45ba38SMiklos Szeredi 		struct page *page;
17752d45ba38SMiklos Szeredi 		unsigned int this_num;
17762d45ba38SMiklos Szeredi 
17772d45ba38SMiklos Szeredi 		page = find_get_page(mapping, index);
17782d45ba38SMiklos Szeredi 		if (!page)
17792d45ba38SMiklos Szeredi 			break;
17802d45ba38SMiklos Szeredi 
178109cbfeafSKirill A. Shutemov 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
17822d45ba38SMiklos Szeredi 		req->pages[req->num_pages] = page;
178397e1532eSMiklos Szeredi 		req->page_descs[req->num_pages].offset = offset;
178485f40aecSMaxim Patlasov 		req->page_descs[req->num_pages].length = this_num;
17852d45ba38SMiklos Szeredi 		req->num_pages++;
17862d45ba38SMiklos Szeredi 
1787c9e67d48SMiklos Szeredi 		offset = 0;
17882d45ba38SMiklos Szeredi 		num -= this_num;
17892d45ba38SMiklos Szeredi 		total_len += this_num;
179048706d0aSMiklos Szeredi 		index++;
17912d45ba38SMiklos Szeredi 	}
17922d45ba38SMiklos Szeredi 	req->misc.retrieve_in.offset = outarg->offset;
17932d45ba38SMiklos Szeredi 	req->misc.retrieve_in.size = total_len;
17942d45ba38SMiklos Szeredi 	req->in.args[0].size = sizeof(req->misc.retrieve_in);
17952d45ba38SMiklos Szeredi 	req->in.args[0].value = &req->misc.retrieve_in;
17962d45ba38SMiklos Szeredi 	req->in.args[1].size = total_len;
17972d45ba38SMiklos Szeredi 
17982d45ba38SMiklos Szeredi 	err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique);
17997fabaf30SMiklos Szeredi 	if (err) {
18002d45ba38SMiklos Szeredi 		fuse_retrieve_end(fc, req);
18017fabaf30SMiklos Szeredi 		fuse_put_request(fc, req);
18027fabaf30SMiklos Szeredi 	}
18032d45ba38SMiklos Szeredi 
18042d45ba38SMiklos Szeredi 	return err;
18052d45ba38SMiklos Szeredi }
18062d45ba38SMiklos Szeredi 
18072d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size,
18082d45ba38SMiklos Szeredi 				struct fuse_copy_state *cs)
18092d45ba38SMiklos Szeredi {
18102d45ba38SMiklos Szeredi 	struct fuse_notify_retrieve_out outarg;
18112d45ba38SMiklos Szeredi 	struct inode *inode;
18122d45ba38SMiklos Szeredi 	int err;
18132d45ba38SMiklos Szeredi 
18142d45ba38SMiklos Szeredi 	err = -EINVAL;
18152d45ba38SMiklos Szeredi 	if (size != sizeof(outarg))
18162d45ba38SMiklos Szeredi 		goto copy_finish;
18172d45ba38SMiklos Szeredi 
18182d45ba38SMiklos Szeredi 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
18192d45ba38SMiklos Szeredi 	if (err)
18202d45ba38SMiklos Szeredi 		goto copy_finish;
18212d45ba38SMiklos Szeredi 
18222d45ba38SMiklos Szeredi 	fuse_copy_finish(cs);
18232d45ba38SMiklos Szeredi 
18242d45ba38SMiklos Szeredi 	down_read(&fc->killsb);
18252d45ba38SMiklos Szeredi 	err = -ENOENT;
18262d45ba38SMiklos Szeredi 	if (fc->sb) {
18272d45ba38SMiklos Szeredi 		u64 nodeid = outarg.nodeid;
18282d45ba38SMiklos Szeredi 
18292d45ba38SMiklos Szeredi 		inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
18302d45ba38SMiklos Szeredi 		if (inode) {
18312d45ba38SMiklos Szeredi 			err = fuse_retrieve(fc, inode, &outarg);
18322d45ba38SMiklos Szeredi 			iput(inode);
18332d45ba38SMiklos Szeredi 		}
18342d45ba38SMiklos Szeredi 	}
18352d45ba38SMiklos Szeredi 	up_read(&fc->killsb);
18362d45ba38SMiklos Szeredi 
18372d45ba38SMiklos Szeredi 	return err;
18382d45ba38SMiklos Szeredi 
18392d45ba38SMiklos Szeredi copy_finish:
18402d45ba38SMiklos Szeredi 	fuse_copy_finish(cs);
18412d45ba38SMiklos Szeredi 	return err;
18422d45ba38SMiklos Szeredi }
18432d45ba38SMiklos Szeredi 
18448599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
18458599396bSTejun Heo 		       unsigned int size, struct fuse_copy_state *cs)
18468599396bSTejun Heo {
18470d278362SMiklos Szeredi 	/* Don't try to move pages (yet) */
18480d278362SMiklos Szeredi 	cs->move_pages = 0;
18490d278362SMiklos Szeredi 
18508599396bSTejun Heo 	switch (code) {
185195668a69STejun Heo 	case FUSE_NOTIFY_POLL:
185295668a69STejun Heo 		return fuse_notify_poll(fc, size, cs);
185395668a69STejun Heo 
18543b463ae0SJohn Muir 	case FUSE_NOTIFY_INVAL_INODE:
18553b463ae0SJohn Muir 		return fuse_notify_inval_inode(fc, size, cs);
18563b463ae0SJohn Muir 
18573b463ae0SJohn Muir 	case FUSE_NOTIFY_INVAL_ENTRY:
18583b463ae0SJohn Muir 		return fuse_notify_inval_entry(fc, size, cs);
18593b463ae0SJohn Muir 
1860a1d75f25SMiklos Szeredi 	case FUSE_NOTIFY_STORE:
1861a1d75f25SMiklos Szeredi 		return fuse_notify_store(fc, size, cs);
1862a1d75f25SMiklos Szeredi 
18632d45ba38SMiklos Szeredi 	case FUSE_NOTIFY_RETRIEVE:
18642d45ba38SMiklos Szeredi 		return fuse_notify_retrieve(fc, size, cs);
18652d45ba38SMiklos Szeredi 
1866451d0f59SJohn Muir 	case FUSE_NOTIFY_DELETE:
1867451d0f59SJohn Muir 		return fuse_notify_delete(fc, size, cs);
1868451d0f59SJohn Muir 
18698599396bSTejun Heo 	default:
1870f6d47a17SMiklos Szeredi 		fuse_copy_finish(cs);
18718599396bSTejun Heo 		return -EINVAL;
18728599396bSTejun Heo 	}
18738599396bSTejun Heo }
18748599396bSTejun Heo 
1875334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */
18763a2b5b9cSMiklos Szeredi static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique)
1877334f485dSMiklos Szeredi {
1878be2ff42cSKirill Tkhai 	unsigned int hash = fuse_req_hash(unique);
1879334f485dSMiklos Szeredi 	struct fuse_req *req;
188005726acaSDong Fang 
1881be2ff42cSKirill Tkhai 	list_for_each_entry(req, &fpq->processing[hash], list) {
18823a5358d1SKirill Tkhai 		if (req->in.h.unique == unique)
1883334f485dSMiklos Szeredi 			return req;
1884334f485dSMiklos Szeredi 	}
1885334f485dSMiklos Szeredi 	return NULL;
1886334f485dSMiklos Szeredi }
1887334f485dSMiklos Szeredi 
1888334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
1889334f485dSMiklos Szeredi 			 unsigned nbytes)
1890334f485dSMiklos Szeredi {
1891334f485dSMiklos Szeredi 	unsigned reqsize = sizeof(struct fuse_out_header);
1892334f485dSMiklos Szeredi 
1893334f485dSMiklos Szeredi 	if (out->h.error)
1894334f485dSMiklos Szeredi 		return nbytes != reqsize ? -EINVAL : 0;
1895334f485dSMiklos Szeredi 
1896334f485dSMiklos Szeredi 	reqsize += len_args(out->numargs, out->args);
1897334f485dSMiklos Szeredi 
1898334f485dSMiklos Szeredi 	if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))
1899334f485dSMiklos Szeredi 		return -EINVAL;
1900334f485dSMiklos Szeredi 	else if (reqsize > nbytes) {
1901334f485dSMiklos Szeredi 		struct fuse_arg *lastarg = &out->args[out->numargs-1];
1902334f485dSMiklos Szeredi 		unsigned diffsize = reqsize - nbytes;
1903334f485dSMiklos Szeredi 		if (diffsize > lastarg->size)
1904334f485dSMiklos Szeredi 			return -EINVAL;
1905334f485dSMiklos Szeredi 		lastarg->size -= diffsize;
1906334f485dSMiklos Szeredi 	}
1907334f485dSMiklos Szeredi 	return fuse_copy_args(cs, out->numargs, out->argpages, out->args,
1908334f485dSMiklos Szeredi 			      out->page_zeroing);
1909334f485dSMiklos Szeredi }
1910334f485dSMiklos Szeredi 
1911334f485dSMiklos Szeredi /*
1912334f485dSMiklos Szeredi  * Write a single reply to a request.  First the header is copied from
1913334f485dSMiklos Szeredi  * the write buffer.  The request is then searched on the processing
1914334f485dSMiklos Szeredi  * list by the unique ID found in the header.  If found, then remove
1915334f485dSMiklos Szeredi  * it from the list and copy the rest of the buffer to the request.
1916334f485dSMiklos Szeredi  * The request is finished by calling request_end()
1917334f485dSMiklos Szeredi  */
1918c3696046SMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
1919dd3bb14fSMiklos Szeredi 				 struct fuse_copy_state *cs, size_t nbytes)
1920334f485dSMiklos Szeredi {
1921334f485dSMiklos Szeredi 	int err;
1922c3696046SMiklos Szeredi 	struct fuse_conn *fc = fud->fc;
1923c3696046SMiklos Szeredi 	struct fuse_pqueue *fpq = &fud->pq;
1924334f485dSMiklos Szeredi 	struct fuse_req *req;
1925334f485dSMiklos Szeredi 	struct fuse_out_header oh;
1926334f485dSMiklos Szeredi 
19277407a10dSKirill Tkhai 	err = -EINVAL;
1928334f485dSMiklos Szeredi 	if (nbytes < sizeof(struct fuse_out_header))
19297407a10dSKirill Tkhai 		goto out;
1930334f485dSMiklos Szeredi 
1931dd3bb14fSMiklos Szeredi 	err = fuse_copy_one(cs, &oh, sizeof(oh));
1932334f485dSMiklos Szeredi 	if (err)
19337407a10dSKirill Tkhai 		goto copy_finish;
19348599396bSTejun Heo 
1935334f485dSMiklos Szeredi 	err = -EINVAL;
19368599396bSTejun Heo 	if (oh.len != nbytes)
19377407a10dSKirill Tkhai 		goto copy_finish;
19388599396bSTejun Heo 
19398599396bSTejun Heo 	/*
19408599396bSTejun Heo 	 * Zero oh.unique indicates unsolicited notification message
19418599396bSTejun Heo 	 * and error contains notification code.
19428599396bSTejun Heo 	 */
19438599396bSTejun Heo 	if (!oh.unique) {
1944dd3bb14fSMiklos Szeredi 		err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs);
19457407a10dSKirill Tkhai 		goto out;
19468599396bSTejun Heo 	}
19478599396bSTejun Heo 
19488599396bSTejun Heo 	err = -EINVAL;
19498599396bSTejun Heo 	if (oh.error <= -1000 || oh.error > 0)
19507407a10dSKirill Tkhai 		goto copy_finish;
1951334f485dSMiklos Szeredi 
195245a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
19537407a10dSKirill Tkhai 	req = NULL;
19547407a10dSKirill Tkhai 	if (fpq->connected)
19553a5358d1SKirill Tkhai 		req = request_find(fpq, oh.unique & ~FUSE_INT_REQ_BIT);
19567407a10dSKirill Tkhai 
19577407a10dSKirill Tkhai 	err = -ENOENT;
19587407a10dSKirill Tkhai 	if (!req) {
19597407a10dSKirill Tkhai 		spin_unlock(&fpq->lock);
19607407a10dSKirill Tkhai 		goto copy_finish;
19617407a10dSKirill Tkhai 	}
1962334f485dSMiklos Szeredi 
19633a5358d1SKirill Tkhai 	/* Is it an interrupt reply ID? */
19643a5358d1SKirill Tkhai 	if (oh.unique & FUSE_INT_REQ_BIT) {
1965d2d2d4fbSKirill Tkhai 		__fuse_get_request(req);
196645a91cb1SMiklos Szeredi 		spin_unlock(&fpq->lock);
196745a91cb1SMiklos Szeredi 
19687407a10dSKirill Tkhai 		err = 0;
19697407a10dSKirill Tkhai 		if (nbytes != sizeof(struct fuse_out_header))
1970a4d27e75SMiklos Szeredi 			err = -EINVAL;
19717407a10dSKirill Tkhai 		else if (oh.error == -ENOSYS)
1972a4d27e75SMiklos Szeredi 			fc->no_interrupt = 1;
1973a4d27e75SMiklos Szeredi 		else if (oh.error == -EAGAIN)
1974b782911bSKirill Tkhai 			err = queue_interrupt(&fc->iq, req);
19757407a10dSKirill Tkhai 
1976d2d2d4fbSKirill Tkhai 		fuse_put_request(fc, req);
1977a4d27e75SMiklos Szeredi 
19787407a10dSKirill Tkhai 		goto copy_finish;
1979a4d27e75SMiklos Szeredi 	}
1980a4d27e75SMiklos Szeredi 
198133e14b4dSMiklos Szeredi 	clear_bit(FR_SENT, &req->flags);
19823a2b5b9cSMiklos Szeredi 	list_move(&req->list, &fpq->io);
1983334f485dSMiklos Szeredi 	req->out.h = oh;
1984825d6d33SMiklos Szeredi 	set_bit(FR_LOCKED, &req->flags);
198545a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1986dd3bb14fSMiklos Szeredi 	cs->req = req;
1987ce534fb0SMiklos Szeredi 	if (!req->out.page_replace)
1988ce534fb0SMiklos Szeredi 		cs->move_pages = 0;
1989334f485dSMiklos Szeredi 
1990dd3bb14fSMiklos Szeredi 	err = copy_out_args(cs, &req->out, nbytes);
1991dd3bb14fSMiklos Szeredi 	fuse_copy_finish(cs);
1992334f485dSMiklos Szeredi 
199345a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1994825d6d33SMiklos Szeredi 	clear_bit(FR_LOCKED, &req->flags);
1995e96edd94SMiklos Szeredi 	if (!fpq->connected)
1996334f485dSMiklos Szeredi 		err = -ENOENT;
19970d8e84b0SMiklos Szeredi 	else if (err)
1998334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
199977cd9d48SMiklos Szeredi 	if (!test_bit(FR_PRIVATE, &req->flags))
2000f377cb79SMiklos Szeredi 		list_del_init(&req->list);
200145a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
200246c34a34SMiklos Szeredi 
2003334f485dSMiklos Szeredi 	request_end(fc, req);
20047407a10dSKirill Tkhai out:
2005334f485dSMiklos Szeredi 	return err ? err : nbytes;
2006334f485dSMiklos Szeredi 
20077407a10dSKirill Tkhai copy_finish:
2008dd3bb14fSMiklos Szeredi 	fuse_copy_finish(cs);
20097407a10dSKirill Tkhai 	goto out;
2010334f485dSMiklos Szeredi }
2011334f485dSMiklos Szeredi 
2012fbdbaccaSAl Viro static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from)
2013dd3bb14fSMiklos Szeredi {
2014dd3bb14fSMiklos Szeredi 	struct fuse_copy_state cs;
2015cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(iocb->ki_filp);
2016cc080e9eSMiklos Szeredi 
2017cc080e9eSMiklos Szeredi 	if (!fud)
2018dd3bb14fSMiklos Szeredi 		return -EPERM;
2019dd3bb14fSMiklos Szeredi 
2020fbdbaccaSAl Viro 	if (!iter_is_iovec(from))
2021fbdbaccaSAl Viro 		return -EINVAL;
2022dd3bb14fSMiklos Szeredi 
2023dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 0, from);
2024fbdbaccaSAl Viro 
2025c3696046SMiklos Szeredi 	return fuse_dev_do_write(fud, &cs, iov_iter_count(from));
2026dd3bb14fSMiklos Szeredi }
2027dd3bb14fSMiklos Szeredi 
2028dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
2029dd3bb14fSMiklos Szeredi 				     struct file *out, loff_t *ppos,
2030dd3bb14fSMiklos Szeredi 				     size_t len, unsigned int flags)
2031dd3bb14fSMiklos Szeredi {
2032dd3bb14fSMiklos Szeredi 	unsigned nbuf;
2033dd3bb14fSMiklos Szeredi 	unsigned idx;
2034dd3bb14fSMiklos Szeredi 	struct pipe_buffer *bufs;
2035dd3bb14fSMiklos Szeredi 	struct fuse_copy_state cs;
2036cc080e9eSMiklos Szeredi 	struct fuse_dev *fud;
2037dd3bb14fSMiklos Szeredi 	size_t rem;
2038dd3bb14fSMiklos Szeredi 	ssize_t ret;
2039dd3bb14fSMiklos Szeredi 
2040cc080e9eSMiklos Szeredi 	fud = fuse_get_dev(out);
2041cc080e9eSMiklos Szeredi 	if (!fud)
2042dd3bb14fSMiklos Szeredi 		return -EPERM;
2043dd3bb14fSMiklos Szeredi 
2044a2477b0eSAndrey Ryabinin 	pipe_lock(pipe);
2045a2477b0eSAndrey Ryabinin 
204696354535SAndrey Ryabinin 	bufs = kvmalloc_array(pipe->nrbufs, sizeof(struct pipe_buffer),
20476da2ec56SKees Cook 			      GFP_KERNEL);
2048a2477b0eSAndrey Ryabinin 	if (!bufs) {
2049a2477b0eSAndrey Ryabinin 		pipe_unlock(pipe);
2050dd3bb14fSMiklos Szeredi 		return -ENOMEM;
2051a2477b0eSAndrey Ryabinin 	}
2052dd3bb14fSMiklos Szeredi 
2053dd3bb14fSMiklos Szeredi 	nbuf = 0;
2054dd3bb14fSMiklos Szeredi 	rem = 0;
2055dd3bb14fSMiklos Szeredi 	for (idx = 0; idx < pipe->nrbufs && rem < len; idx++)
2056dd3bb14fSMiklos Szeredi 		rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len;
2057dd3bb14fSMiklos Szeredi 
2058dd3bb14fSMiklos Szeredi 	ret = -EINVAL;
2059dd3bb14fSMiklos Szeredi 	if (rem < len) {
2060dd3bb14fSMiklos Szeredi 		pipe_unlock(pipe);
2061dd3bb14fSMiklos Szeredi 		goto out;
2062dd3bb14fSMiklos Szeredi 	}
2063dd3bb14fSMiklos Szeredi 
2064dd3bb14fSMiklos Szeredi 	rem = len;
2065dd3bb14fSMiklos Szeredi 	while (rem) {
2066dd3bb14fSMiklos Szeredi 		struct pipe_buffer *ibuf;
2067dd3bb14fSMiklos Szeredi 		struct pipe_buffer *obuf;
2068dd3bb14fSMiklos Szeredi 
2069dd3bb14fSMiklos Szeredi 		BUG_ON(nbuf >= pipe->buffers);
2070dd3bb14fSMiklos Szeredi 		BUG_ON(!pipe->nrbufs);
2071dd3bb14fSMiklos Szeredi 		ibuf = &pipe->bufs[pipe->curbuf];
2072dd3bb14fSMiklos Szeredi 		obuf = &bufs[nbuf];
2073dd3bb14fSMiklos Szeredi 
2074dd3bb14fSMiklos Szeredi 		if (rem >= ibuf->len) {
2075dd3bb14fSMiklos Szeredi 			*obuf = *ibuf;
2076dd3bb14fSMiklos Szeredi 			ibuf->ops = NULL;
2077dd3bb14fSMiklos Szeredi 			pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1);
2078dd3bb14fSMiklos Szeredi 			pipe->nrbufs--;
2079dd3bb14fSMiklos Szeredi 		} else {
20807bf2d1dfSMiklos Szeredi 			pipe_buf_get(pipe, ibuf);
2081dd3bb14fSMiklos Szeredi 			*obuf = *ibuf;
2082dd3bb14fSMiklos Szeredi 			obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
2083dd3bb14fSMiklos Szeredi 			obuf->len = rem;
2084dd3bb14fSMiklos Szeredi 			ibuf->offset += obuf->len;
2085dd3bb14fSMiklos Szeredi 			ibuf->len -= obuf->len;
2086dd3bb14fSMiklos Szeredi 		}
2087dd3bb14fSMiklos Szeredi 		nbuf++;
2088dd3bb14fSMiklos Szeredi 		rem -= obuf->len;
2089dd3bb14fSMiklos Szeredi 	}
2090dd3bb14fSMiklos Szeredi 	pipe_unlock(pipe);
2091dd3bb14fSMiklos Szeredi 
2092dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 0, NULL);
2093dd3bb14fSMiklos Szeredi 	cs.pipebufs = bufs;
20946c09e94aSAl Viro 	cs.nr_segs = nbuf;
2095dd3bb14fSMiklos Szeredi 	cs.pipe = pipe;
2096dd3bb14fSMiklos Szeredi 
2097ce534fb0SMiklos Szeredi 	if (flags & SPLICE_F_MOVE)
2098ce534fb0SMiklos Szeredi 		cs.move_pages = 1;
2099ce534fb0SMiklos Szeredi 
2100c3696046SMiklos Szeredi 	ret = fuse_dev_do_write(fud, &cs, len);
2101dd3bb14fSMiklos Szeredi 
21029509941eSJann Horn 	pipe_lock(pipe);
2103a779638cSMiklos Szeredi 	for (idx = 0; idx < nbuf; idx++)
2104a779638cSMiklos Szeredi 		pipe_buf_release(pipe, &bufs[idx]);
21059509941eSJann Horn 	pipe_unlock(pipe);
2106a779638cSMiklos Szeredi 
2107dd3bb14fSMiklos Szeredi out:
2108d6d931adSAndrey Ryabinin 	kvfree(bufs);
2109dd3bb14fSMiklos Szeredi 	return ret;
2110dd3bb14fSMiklos Szeredi }
2111dd3bb14fSMiklos Szeredi 
2112076ccb76SAl Viro static __poll_t fuse_dev_poll(struct file *file, poll_table *wait)
2113334f485dSMiklos Szeredi {
2114a9a08845SLinus Torvalds 	__poll_t mask = EPOLLOUT | EPOLLWRNORM;
2115f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq;
2116cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2117cc080e9eSMiklos Szeredi 
2118cc080e9eSMiklos Szeredi 	if (!fud)
2119a9a08845SLinus Torvalds 		return EPOLLERR;
2120334f485dSMiklos Szeredi 
2121cc080e9eSMiklos Szeredi 	fiq = &fud->fc->iq;
2122f88996a9SMiklos Szeredi 	poll_wait(file, &fiq->waitq, wait);
2123334f485dSMiklos Szeredi 
21244ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
2125e16714d8SMiklos Szeredi 	if (!fiq->connected)
2126a9a08845SLinus Torvalds 		mask = EPOLLERR;
2127f88996a9SMiklos Szeredi 	else if (request_pending(fiq))
2128a9a08845SLinus Torvalds 		mask |= EPOLLIN | EPOLLRDNORM;
21294ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
2130334f485dSMiklos Szeredi 
2131334f485dSMiklos Szeredi 	return mask;
2132334f485dSMiklos Szeredi }
2133334f485dSMiklos Szeredi 
213434061750SKirill Tkhai /* Abort all requests on the given list (pending or processing) */
2135334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head)
2136334f485dSMiklos Szeredi {
2137334f485dSMiklos Szeredi 	while (!list_empty(head)) {
2138334f485dSMiklos Szeredi 		struct fuse_req *req;
2139334f485dSMiklos Szeredi 		req = list_entry(head->next, struct fuse_req, list);
2140334f485dSMiklos Szeredi 		req->out.h.error = -ECONNABORTED;
214133e14b4dSMiklos Szeredi 		clear_bit(FR_SENT, &req->flags);
2142f377cb79SMiklos Szeredi 		list_del_init(&req->list);
2143334f485dSMiklos Szeredi 		request_end(fc, req);
2144334f485dSMiklos Szeredi 	}
2145334f485dSMiklos Szeredi }
2146334f485dSMiklos Szeredi 
2147357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc)
2148357ccf2bSBryan Green {
2149357ccf2bSBryan Green 	struct rb_node *p;
2150357ccf2bSBryan Green 
2151357ccf2bSBryan Green 	p = rb_first(&fc->polled_files);
2152357ccf2bSBryan Green 
2153357ccf2bSBryan Green 	while (p) {
2154357ccf2bSBryan Green 		struct fuse_file *ff;
2155357ccf2bSBryan Green 		ff = rb_entry(p, struct fuse_file, polled_node);
2156357ccf2bSBryan Green 		wake_up_interruptible_all(&ff->poll_wait);
2157357ccf2bSBryan Green 
2158357ccf2bSBryan Green 		p = rb_next(p);
2159357ccf2bSBryan Green 	}
2160357ccf2bSBryan Green }
2161357ccf2bSBryan Green 
216269a53bf2SMiklos Szeredi /*
216369a53bf2SMiklos Szeredi  * Abort all requests.
216469a53bf2SMiklos Szeredi  *
2165b716d425SMiklos Szeredi  * Emergency exit in case of a malicious or accidental deadlock, or just a hung
2166b716d425SMiklos Szeredi  * filesystem.
216769a53bf2SMiklos Szeredi  *
2168b716d425SMiklos Szeredi  * The same effect is usually achievable through killing the filesystem daemon
2169b716d425SMiklos Szeredi  * and all users of the filesystem.  The exception is the combination of an
2170b716d425SMiklos Szeredi  * asynchronous request and the tricky deadlock (see
2171b716d425SMiklos Szeredi  * Documentation/filesystems/fuse.txt).
217269a53bf2SMiklos Szeredi  *
2173b716d425SMiklos Szeredi  * Aborting requests under I/O goes as follows: 1: Separate out unlocked
2174b716d425SMiklos Szeredi  * requests, they should be finished off immediately.  Locked requests will be
2175b716d425SMiklos Szeredi  * finished after unlock; see unlock_request(). 2: Finish off the unlocked
2176b716d425SMiklos Szeredi  * requests.  It is possible that some request will finish before we can.  This
2177b716d425SMiklos Szeredi  * is OK, the request will in that case be removed from the list before we touch
2178b716d425SMiklos Szeredi  * it.
217969a53bf2SMiklos Szeredi  */
2180eb98e3bdSMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc)
218169a53bf2SMiklos Szeredi {
2182f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
2183f88996a9SMiklos Szeredi 
2184d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
218569a53bf2SMiklos Szeredi 	if (fc->connected) {
2186c3696046SMiklos Szeredi 		struct fuse_dev *fud;
2187b716d425SMiklos Szeredi 		struct fuse_req *req, *next;
218875f3ee4cSMiklos Szeredi 		LIST_HEAD(to_end);
2189be2ff42cSKirill Tkhai 		unsigned int i;
2190b716d425SMiklos Szeredi 
219163825b4eSKirill Tkhai 		/* Background queuing checks fc->connected under bg_lock */
219263825b4eSKirill Tkhai 		spin_lock(&fc->bg_lock);
219369a53bf2SMiklos Szeredi 		fc->connected = 0;
219463825b4eSKirill Tkhai 		spin_unlock(&fc->bg_lock);
219563825b4eSKirill Tkhai 
21969759bd51SMiklos Szeredi 		fuse_set_initialized(fc);
2197c3696046SMiklos Szeredi 		list_for_each_entry(fud, &fc->devices, entry) {
2198c3696046SMiklos Szeredi 			struct fuse_pqueue *fpq = &fud->pq;
2199c3696046SMiklos Szeredi 
220045a91cb1SMiklos Szeredi 			spin_lock(&fpq->lock);
2201e96edd94SMiklos Szeredi 			fpq->connected = 0;
22023a2b5b9cSMiklos Szeredi 			list_for_each_entry_safe(req, next, &fpq->io, list) {
2203b716d425SMiklos Szeredi 				req->out.h.error = -ECONNABORTED;
2204b716d425SMiklos Szeredi 				spin_lock(&req->waitq.lock);
2205b716d425SMiklos Szeredi 				set_bit(FR_ABORTED, &req->flags);
220677cd9d48SMiklos Szeredi 				if (!test_bit(FR_LOCKED, &req->flags)) {
220777cd9d48SMiklos Szeredi 					set_bit(FR_PRIVATE, &req->flags);
220887114373SMiklos Szeredi 					__fuse_get_request(req);
220975f3ee4cSMiklos Szeredi 					list_move(&req->list, &to_end);
221077cd9d48SMiklos Szeredi 				}
2211b716d425SMiklos Szeredi 				spin_unlock(&req->waitq.lock);
2212b716d425SMiklos Szeredi 			}
2213be2ff42cSKirill Tkhai 			for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
2214be2ff42cSKirill Tkhai 				list_splice_tail_init(&fpq->processing[i],
2215be2ff42cSKirill Tkhai 						      &to_end);
221645a91cb1SMiklos Szeredi 			spin_unlock(&fpq->lock);
2217c3696046SMiklos Szeredi 		}
2218ae2dffa3SKirill Tkhai 		spin_lock(&fc->bg_lock);
2219ae2dffa3SKirill Tkhai 		fc->blocked = 0;
222041f98274SMiklos Szeredi 		fc->max_background = UINT_MAX;
222141f98274SMiklos Szeredi 		flush_bg_queue(fc);
2222ae2dffa3SKirill Tkhai 		spin_unlock(&fc->bg_lock);
22238c91189aSMiklos Szeredi 
22244ce60812SMiklos Szeredi 		spin_lock(&fiq->waitq.lock);
22258c91189aSMiklos Szeredi 		fiq->connected = 0;
222675f3ee4cSMiklos Szeredi 		list_for_each_entry(req, &fiq->pending, list)
2227a8a86d78STahsin Erdogan 			clear_bit(FR_PENDING, &req->flags);
222875f3ee4cSMiklos Szeredi 		list_splice_tail_init(&fiq->pending, &to_end);
22298c91189aSMiklos Szeredi 		while (forget_pending(fiq))
22308c91189aSMiklos Szeredi 			kfree(dequeue_forget(fiq, 1, NULL));
22314ce60812SMiklos Szeredi 		wake_up_all_locked(&fiq->waitq);
22324ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
22338c91189aSMiklos Szeredi 		kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
2234ee314a87SMiklos Szeredi 		end_polls(fc);
2235ee314a87SMiklos Szeredi 		wake_up_all(&fc->blocked_waitq);
2236ee314a87SMiklos Szeredi 		spin_unlock(&fc->lock);
22378c91189aSMiklos Szeredi 
223875f3ee4cSMiklos Szeredi 		end_requests(fc, &to_end);
2239ee314a87SMiklos Szeredi 	} else {
2240d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
224169a53bf2SMiklos Szeredi 	}
2242ee314a87SMiklos Szeredi }
224308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn);
224469a53bf2SMiklos Szeredi 
2245b8f95e5dSMiklos Szeredi void fuse_wait_aborted(struct fuse_conn *fc)
2246b8f95e5dSMiklos Szeredi {
22472d84a2d1SMiklos Szeredi 	/* matches implicit memory barrier in fuse_drop_waiting() */
22482d84a2d1SMiklos Szeredi 	smp_mb();
2249b8f95e5dSMiklos Szeredi 	wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
2250b8f95e5dSMiklos Szeredi }
2251b8f95e5dSMiklos Szeredi 
225208cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file)
2253334f485dSMiklos Szeredi {
2254cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2255cc080e9eSMiklos Szeredi 
2256cc080e9eSMiklos Szeredi 	if (fud) {
2257cc080e9eSMiklos Szeredi 		struct fuse_conn *fc = fud->fc;
2258c3696046SMiklos Szeredi 		struct fuse_pqueue *fpq = &fud->pq;
225945ff350bSMiklos Szeredi 		LIST_HEAD(to_end);
2260be2ff42cSKirill Tkhai 		unsigned int i;
2261cc080e9eSMiklos Szeredi 
226245ff350bSMiklos Szeredi 		spin_lock(&fpq->lock);
2263c3696046SMiklos Szeredi 		WARN_ON(!list_empty(&fpq->io));
2264be2ff42cSKirill Tkhai 		for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
2265be2ff42cSKirill Tkhai 			list_splice_init(&fpq->processing[i], &to_end);
226645ff350bSMiklos Szeredi 		spin_unlock(&fpq->lock);
226745ff350bSMiklos Szeredi 
226845ff350bSMiklos Szeredi 		end_requests(fc, &to_end);
226945ff350bSMiklos Szeredi 
2270c3696046SMiklos Szeredi 		/* Are we the last open device? */
2271c3696046SMiklos Szeredi 		if (atomic_dec_and_test(&fc->dev_count)) {
2272f88996a9SMiklos Szeredi 			WARN_ON(fc->iq.fasync != NULL);
2273eb98e3bdSMiklos Szeredi 			fuse_abort_conn(fc);
2274c3696046SMiklos Szeredi 		}
2275cc080e9eSMiklos Szeredi 		fuse_dev_free(fud);
2276385a17bfSJeff Dike 	}
2277334f485dSMiklos Szeredi 	return 0;
2278334f485dSMiklos Szeredi }
227908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release);
2280334f485dSMiklos Szeredi 
2281385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on)
2282385a17bfSJeff Dike {
2283cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2284cc080e9eSMiklos Szeredi 
2285cc080e9eSMiklos Szeredi 	if (!fud)
2286a87046d8SMiklos Szeredi 		return -EPERM;
2287385a17bfSJeff Dike 
2288385a17bfSJeff Dike 	/* No locking - fasync_helper does its own locking */
2289cc080e9eSMiklos Szeredi 	return fasync_helper(fd, file, on, &fud->fc->iq.fasync);
2290385a17bfSJeff Dike }
2291385a17bfSJeff Dike 
229200c570f4SMiklos Szeredi static int fuse_device_clone(struct fuse_conn *fc, struct file *new)
229300c570f4SMiklos Szeredi {
2294cc080e9eSMiklos Szeredi 	struct fuse_dev *fud;
2295cc080e9eSMiklos Szeredi 
229600c570f4SMiklos Szeredi 	if (new->private_data)
229700c570f4SMiklos Szeredi 		return -EINVAL;
229800c570f4SMiklos Szeredi 
2299cc080e9eSMiklos Szeredi 	fud = fuse_dev_alloc(fc);
2300cc080e9eSMiklos Szeredi 	if (!fud)
2301cc080e9eSMiklos Szeredi 		return -ENOMEM;
2302cc080e9eSMiklos Szeredi 
2303cc080e9eSMiklos Szeredi 	new->private_data = fud;
2304c3696046SMiklos Szeredi 	atomic_inc(&fc->dev_count);
230500c570f4SMiklos Szeredi 
230600c570f4SMiklos Szeredi 	return 0;
230700c570f4SMiklos Szeredi }
230800c570f4SMiklos Szeredi 
230900c570f4SMiklos Szeredi static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
231000c570f4SMiklos Szeredi 			   unsigned long arg)
231100c570f4SMiklos Szeredi {
231200c570f4SMiklos Szeredi 	int err = -ENOTTY;
231300c570f4SMiklos Szeredi 
231400c570f4SMiklos Szeredi 	if (cmd == FUSE_DEV_IOC_CLONE) {
231500c570f4SMiklos Szeredi 		int oldfd;
231600c570f4SMiklos Szeredi 
231700c570f4SMiklos Szeredi 		err = -EFAULT;
231800c570f4SMiklos Szeredi 		if (!get_user(oldfd, (__u32 __user *) arg)) {
231900c570f4SMiklos Szeredi 			struct file *old = fget(oldfd);
232000c570f4SMiklos Szeredi 
232100c570f4SMiklos Szeredi 			err = -EINVAL;
232200c570f4SMiklos Szeredi 			if (old) {
23238ed1f0e2SJann Horn 				struct fuse_dev *fud = NULL;
23248ed1f0e2SJann Horn 
23258ed1f0e2SJann Horn 				/*
23268ed1f0e2SJann Horn 				 * Check against file->f_op because CUSE
23278ed1f0e2SJann Horn 				 * uses the same ioctl handler.
23288ed1f0e2SJann Horn 				 */
23298ed1f0e2SJann Horn 				if (old->f_op == file->f_op &&
23308ed1f0e2SJann Horn 				    old->f_cred->user_ns == file->f_cred->user_ns)
23318ed1f0e2SJann Horn 					fud = fuse_get_dev(old);
233200c570f4SMiklos Szeredi 
2333cc080e9eSMiklos Szeredi 				if (fud) {
233400c570f4SMiklos Szeredi 					mutex_lock(&fuse_mutex);
2335cc080e9eSMiklos Szeredi 					err = fuse_device_clone(fud->fc, file);
233600c570f4SMiklos Szeredi 					mutex_unlock(&fuse_mutex);
233700c570f4SMiklos Szeredi 				}
233800c570f4SMiklos Szeredi 				fput(old);
233900c570f4SMiklos Szeredi 			}
234000c570f4SMiklos Szeredi 		}
234100c570f4SMiklos Szeredi 	}
234200c570f4SMiklos Szeredi 	return err;
234300c570f4SMiklos Szeredi }
234400c570f4SMiklos Szeredi 
23454b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = {
2346334f485dSMiklos Szeredi 	.owner		= THIS_MODULE,
234794e4fe2cSTom Van Braeckel 	.open		= fuse_dev_open,
2348334f485dSMiklos Szeredi 	.llseek		= no_llseek,
2349fbdbaccaSAl Viro 	.read_iter	= fuse_dev_read,
2350c3021629SMiklos Szeredi 	.splice_read	= fuse_dev_splice_read,
2351fbdbaccaSAl Viro 	.write_iter	= fuse_dev_write,
2352dd3bb14fSMiklos Szeredi 	.splice_write	= fuse_dev_splice_write,
2353334f485dSMiklos Szeredi 	.poll		= fuse_dev_poll,
2354334f485dSMiklos Szeredi 	.release	= fuse_dev_release,
2355385a17bfSJeff Dike 	.fasync		= fuse_dev_fasync,
235600c570f4SMiklos Szeredi 	.unlocked_ioctl = fuse_dev_ioctl,
235700c570f4SMiklos Szeredi 	.compat_ioctl   = fuse_dev_ioctl,
2358334f485dSMiklos Szeredi };
235908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations);
2360334f485dSMiklos Szeredi 
2361334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = {
2362334f485dSMiklos Szeredi 	.minor = FUSE_MINOR,
2363334f485dSMiklos Szeredi 	.name  = "fuse",
2364334f485dSMiklos Szeredi 	.fops = &fuse_dev_operations,
2365334f485dSMiklos Szeredi };
2366334f485dSMiklos Szeredi 
2367334f485dSMiklos Szeredi int __init fuse_dev_init(void)
2368334f485dSMiklos Szeredi {
2369334f485dSMiklos Szeredi 	int err = -ENOMEM;
2370334f485dSMiklos Szeredi 	fuse_req_cachep = kmem_cache_create("fuse_request",
2371334f485dSMiklos Szeredi 					    sizeof(struct fuse_req),
237220c2df83SPaul Mundt 					    0, 0, NULL);
2373334f485dSMiklos Szeredi 	if (!fuse_req_cachep)
2374334f485dSMiklos Szeredi 		goto out;
2375334f485dSMiklos Szeredi 
2376334f485dSMiklos Szeredi 	err = misc_register(&fuse_miscdevice);
2377334f485dSMiklos Szeredi 	if (err)
2378334f485dSMiklos Szeredi 		goto out_cache_clean;
2379334f485dSMiklos Szeredi 
2380334f485dSMiklos Szeredi 	return 0;
2381334f485dSMiklos Szeredi 
2382334f485dSMiklos Szeredi  out_cache_clean:
2383334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
2384334f485dSMiklos Szeredi  out:
2385334f485dSMiklos Szeredi 	return err;
2386334f485dSMiklos Szeredi }
2387334f485dSMiklos Szeredi 
2388334f485dSMiklos Szeredi void fuse_dev_cleanup(void)
2389334f485dSMiklos Szeredi {
2390334f485dSMiklos Szeredi 	misc_deregister(&fuse_miscdevice);
2391334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
2392334f485dSMiklos Szeredi }
2393