xref: /openbmc/linux/fs/fuse/dev.c (revision 8da6e918)
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;
25433649c91SMiklos Szeredi 	struct fuse_file *ff = file->private_data;
25533649c91SMiklos Szeredi 
25633649c91SMiklos Szeredi 	do {
257de5e3decSMiklos Szeredi 		wait_event(fc->reserved_req_waitq, ff->reserved_req);
25833649c91SMiklos Szeredi 		spin_lock(&fc->lock);
25933649c91SMiklos Szeredi 		if (ff->reserved_req) {
26033649c91SMiklos Szeredi 			req = ff->reserved_req;
26133649c91SMiklos Szeredi 			ff->reserved_req = NULL;
262cb0942b8SAl Viro 			req->stolen_file = get_file(file);
26333649c91SMiklos Szeredi 		}
26433649c91SMiklos Szeredi 		spin_unlock(&fc->lock);
26533649c91SMiklos Szeredi 	} while (!req);
26633649c91SMiklos Szeredi 
26733649c91SMiklos Szeredi 	return req;
26833649c91SMiklos Szeredi }
26933649c91SMiklos Szeredi 
27033649c91SMiklos Szeredi /*
27133649c91SMiklos Szeredi  * Put stolen request back into fuse_file->reserved_req
27233649c91SMiklos Szeredi  */
27333649c91SMiklos Szeredi static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
27433649c91SMiklos Szeredi {
27533649c91SMiklos Szeredi 	struct file *file = req->stolen_file;
27633649c91SMiklos Szeredi 	struct fuse_file *ff = file->private_data;
27733649c91SMiklos Szeredi 
2788a7aa286SMiklos Szeredi 	WARN_ON(req->max_pages);
27933649c91SMiklos Szeredi 	spin_lock(&fc->lock);
2808a7aa286SMiklos Szeredi 	memset(req, 0, sizeof(*req));
2818a7aa286SMiklos Szeredi 	fuse_request_init(req, NULL, NULL, 0);
28233649c91SMiklos Szeredi 	BUG_ON(ff->reserved_req);
28333649c91SMiklos Szeredi 	ff->reserved_req = req;
284de5e3decSMiklos Szeredi 	wake_up_all(&fc->reserved_req_waitq);
28533649c91SMiklos Szeredi 	spin_unlock(&fc->lock);
28633649c91SMiklos Szeredi 	fput(file);
28733649c91SMiklos Szeredi }
28833649c91SMiklos Szeredi 
28933649c91SMiklos Szeredi /*
29033649c91SMiklos Szeredi  * Gets a requests for a file operation, always succeeds
29133649c91SMiklos Szeredi  *
29233649c91SMiklos Szeredi  * This is used for sending the FLUSH request, which must get to
29333649c91SMiklos Szeredi  * userspace, due to POSIX locks which may need to be unlocked.
29433649c91SMiklos Szeredi  *
29533649c91SMiklos Szeredi  * If allocation fails due to OOM, use the reserved request in
29633649c91SMiklos Szeredi  * fuse_file.
29733649c91SMiklos Szeredi  *
29833649c91SMiklos Szeredi  * This is very unlikely to deadlock accidentally, since the
29933649c91SMiklos Szeredi  * filesystem should not have it's own file open.  If deadlock is
30033649c91SMiklos Szeredi  * intentional, it can still be broken by "aborting" the filesystem.
30133649c91SMiklos Szeredi  */
302b111c8c0SMaxim Patlasov struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc,
303b111c8c0SMaxim Patlasov 					     struct file *file)
30433649c91SMiklos Szeredi {
30533649c91SMiklos Szeredi 	struct fuse_req *req;
30633649c91SMiklos Szeredi 
30733649c91SMiklos Szeredi 	atomic_inc(&fc->num_waiting);
3080aada884SMaxim Patlasov 	wait_event(fc->blocked_waitq, fc->initialized);
3099759bd51SMiklos Szeredi 	/* Matches smp_wmb() in fuse_set_initialized() */
3109759bd51SMiklos Szeredi 	smp_rmb();
311b111c8c0SMaxim Patlasov 	req = fuse_request_alloc(0);
31233649c91SMiklos Szeredi 	if (!req)
31333649c91SMiklos Szeredi 		req = get_reserved_req(fc, file);
31433649c91SMiklos Szeredi 
3158cb08329SEric W. Biederman 	req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
3168cb08329SEric W. Biederman 	req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid());
317c9582eb0SEric W. Biederman 	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
318c9582eb0SEric W. Biederman 
319825d6d33SMiklos Szeredi 	__set_bit(FR_WAITING, &req->flags);
320825d6d33SMiklos Szeredi 	__clear_bit(FR_BACKGROUND, &req->flags);
32133649c91SMiklos Szeredi 	return req;
32233649c91SMiklos Szeredi }
32333649c91SMiklos Szeredi 
324334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
325334f485dSMiklos Szeredi {
326ec99f6d3SElena Reshetova 	if (refcount_dec_and_test(&req->count)) {
327825d6d33SMiklos Szeredi 		if (test_bit(FR_BACKGROUND, &req->flags)) {
328722d2beaSMaxim Patlasov 			/*
329722d2beaSMaxim Patlasov 			 * We get here in the unlikely case that a background
330722d2beaSMaxim Patlasov 			 * request was allocated but not sent
331722d2beaSMaxim Patlasov 			 */
332ae2dffa3SKirill Tkhai 			spin_lock(&fc->bg_lock);
333722d2beaSMaxim Patlasov 			if (!fc->blocked)
334722d2beaSMaxim Patlasov 				wake_up(&fc->blocked_waitq);
335ae2dffa3SKirill Tkhai 			spin_unlock(&fc->bg_lock);
336722d2beaSMaxim Patlasov 		}
337722d2beaSMaxim Patlasov 
338825d6d33SMiklos Szeredi 		if (test_bit(FR_WAITING, &req->flags)) {
339825d6d33SMiklos Szeredi 			__clear_bit(FR_WAITING, &req->flags);
340b8f95e5dSMiklos Szeredi 			fuse_drop_waiting(fc);
34173e0e738SMiklos Szeredi 		}
34233649c91SMiklos Szeredi 
34333649c91SMiklos Szeredi 		if (req->stolen_file)
34433649c91SMiklos Szeredi 			put_reserved_req(fc, req);
34533649c91SMiklos Szeredi 		else
346ce1d5a49SMiklos Szeredi 			fuse_request_free(req);
3477128ec2aSMiklos Szeredi 	}
3487128ec2aSMiklos Szeredi }
34908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_put_request);
3507128ec2aSMiklos Szeredi 
351d12def1bSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args)
352d12def1bSMiklos Szeredi {
353d12def1bSMiklos Szeredi 	unsigned nbytes = 0;
354d12def1bSMiklos Szeredi 	unsigned i;
355d12def1bSMiklos Szeredi 
356d12def1bSMiklos Szeredi 	for (i = 0; i < numargs; i++)
357d12def1bSMiklos Szeredi 		nbytes += args[i].size;
358d12def1bSMiklos Szeredi 
359d12def1bSMiklos Szeredi 	return nbytes;
360d12def1bSMiklos Szeredi }
361d12def1bSMiklos Szeredi 
362f88996a9SMiklos Szeredi static u64 fuse_get_unique(struct fuse_iqueue *fiq)
363d12def1bSMiklos Szeredi {
364c59fd85eSKirill Tkhai 	fiq->reqctr += FUSE_REQ_ID_STEP;
365c59fd85eSKirill Tkhai 	return fiq->reqctr;
366d12def1bSMiklos Szeredi }
367d12def1bSMiklos Szeredi 
368be2ff42cSKirill Tkhai static unsigned int fuse_req_hash(u64 unique)
369be2ff42cSKirill Tkhai {
370be2ff42cSKirill Tkhai 	return hash_long(unique & ~FUSE_INT_REQ_BIT, FUSE_PQ_HASH_BITS);
371be2ff42cSKirill Tkhai }
372be2ff42cSKirill Tkhai 
373f88996a9SMiklos Szeredi static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req)
374d12def1bSMiklos Szeredi {
375d12def1bSMiklos Szeredi 	req->in.h.len = sizeof(struct fuse_in_header) +
376d12def1bSMiklos Szeredi 		len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
377f88996a9SMiklos Szeredi 	list_add_tail(&req->list, &fiq->pending);
3784ce60812SMiklos Szeredi 	wake_up_locked(&fiq->waitq);
379f88996a9SMiklos Szeredi 	kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
380d12def1bSMiklos Szeredi }
381d12def1bSMiklos Szeredi 
38207e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
38307e77dcaSMiklos Szeredi 		       u64 nodeid, u64 nlookup)
38407e77dcaSMiklos Szeredi {
385f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
386f88996a9SMiklos Szeredi 
38702c048b9SMiklos Szeredi 	forget->forget_one.nodeid = nodeid;
38802c048b9SMiklos Szeredi 	forget->forget_one.nlookup = nlookup;
38907e77dcaSMiklos Szeredi 
3904ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
391e16714d8SMiklos Szeredi 	if (fiq->connected) {
392f88996a9SMiklos Szeredi 		fiq->forget_list_tail->next = forget;
393f88996a9SMiklos Szeredi 		fiq->forget_list_tail = forget;
3944ce60812SMiklos Szeredi 		wake_up_locked(&fiq->waitq);
395f88996a9SMiklos Szeredi 		kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
3965dfcc87fSMiklos Szeredi 	} else {
3975dfcc87fSMiklos Szeredi 		kfree(forget);
3985dfcc87fSMiklos Szeredi 	}
3994ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
40007e77dcaSMiklos Szeredi }
40107e77dcaSMiklos Szeredi 
402d12def1bSMiklos Szeredi static void flush_bg_queue(struct fuse_conn *fc)
403d12def1bSMiklos Szeredi {
404e287179aSKirill Tkhai 	struct fuse_iqueue *fiq = &fc->iq;
405e287179aSKirill Tkhai 
4067a6d3c8bSCsaba Henk 	while (fc->active_background < fc->max_background &&
407d12def1bSMiklos Szeredi 	       !list_empty(&fc->bg_queue)) {
408d12def1bSMiklos Szeredi 		struct fuse_req *req;
409d12def1bSMiklos Szeredi 
410e287179aSKirill Tkhai 		req = list_first_entry(&fc->bg_queue, struct fuse_req, list);
411d12def1bSMiklos Szeredi 		list_del(&req->list);
412d12def1bSMiklos Szeredi 		fc->active_background++;
4134ce60812SMiklos Szeredi 		spin_lock(&fiq->waitq.lock);
414f88996a9SMiklos Szeredi 		req->in.h.unique = fuse_get_unique(fiq);
415f88996a9SMiklos Szeredi 		queue_request(fiq, req);
4164ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
417d12def1bSMiklos Szeredi 	}
418d12def1bSMiklos Szeredi }
419d12def1bSMiklos Szeredi 
4206dbbcb12SMiklos Szeredi /*
421334f485dSMiklos Szeredi  * This function is called when a request is finished.  Either a reply
422f9a2842eSMiklos Szeredi  * has arrived or it was aborted (and not yet sent) or some error
423f43b155aSMiklos Szeredi  * occurred during communication with userspace, or the device file
42451eb01e7SMiklos Szeredi  * was closed.  The requester thread is woken up (if still waiting),
42551eb01e7SMiklos Szeredi  * the 'end' callback is called if given, else the reference to the
42651eb01e7SMiklos Szeredi  * request is released
427334f485dSMiklos Szeredi  */
428334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req)
429334f485dSMiklos Szeredi {
4304ce60812SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
431365ae710SMiklos Szeredi 
432efe2800fSMiklos Szeredi 	if (test_and_set_bit(FR_FINISHED, &req->flags))
433b8f95e5dSMiklos Szeredi 		goto put_request;
434365ae710SMiklos Szeredi 
4354ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
4360d8e84b0SMiklos Szeredi 	list_del_init(&req->intr_entry);
4374ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
43833e14b4dSMiklos Szeredi 	WARN_ON(test_bit(FR_PENDING, &req->flags));
43933e14b4dSMiklos Szeredi 	WARN_ON(test_bit(FR_SENT, &req->flags));
440825d6d33SMiklos Szeredi 	if (test_bit(FR_BACKGROUND, &req->flags)) {
441ae2dffa3SKirill Tkhai 		spin_lock(&fc->bg_lock);
442825d6d33SMiklos Szeredi 		clear_bit(FR_BACKGROUND, &req->flags);
443908a572bSMiklos Szeredi 		if (fc->num_background == fc->max_background) {
44451eb01e7SMiklos Szeredi 			fc->blocked = 0;
445722d2beaSMaxim Patlasov 			wake_up(&fc->blocked_waitq);
446908a572bSMiklos Szeredi 		} else if (!fc->blocked) {
447908a572bSMiklos Szeredi 			/*
448908a572bSMiklos Szeredi 			 * Wake up next waiter, if any.  It's okay to use
449908a572bSMiklos Szeredi 			 * waitqueue_active(), as we've already synced up
450908a572bSMiklos Szeredi 			 * fc->blocked with waiters with the wake_up() call
451908a572bSMiklos Szeredi 			 * above.
452908a572bSMiklos Szeredi 			 */
453908a572bSMiklos Szeredi 			if (waitqueue_active(&fc->blocked_waitq))
454908a572bSMiklos Szeredi 				wake_up(&fc->blocked_waitq);
455908a572bSMiklos Szeredi 		}
456722d2beaSMaxim Patlasov 
4578a301eb1STejun Heo 		if (fc->num_background == fc->congestion_threshold && fc->sb) {
4585f7f7543SJan Kara 			clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
4595f7f7543SJan Kara 			clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
460f92b99b9SMiklos Szeredi 		}
46151eb01e7SMiklos Szeredi 		fc->num_background--;
462d12def1bSMiklos Szeredi 		fc->active_background--;
463d12def1bSMiklos Szeredi 		flush_bg_queue(fc);
464ae2dffa3SKirill Tkhai 		spin_unlock(&fc->bg_lock);
465efe2800fSMiklos Szeredi 	}
46651eb01e7SMiklos Szeredi 	wake_up(&req->waitq);
4671e6881c3SMiklos Szeredi 	if (req->end)
4681e6881c3SMiklos Szeredi 		req->end(fc, req);
469b8f95e5dSMiklos Szeredi put_request:
470f43b155aSMiklos Szeredi 	fuse_put_request(fc, req);
471334f485dSMiklos Szeredi }
472334f485dSMiklos Szeredi 
473f88996a9SMiklos Szeredi static void queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
474a4d27e75SMiklos Szeredi {
4754ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
4766ba4d272SSahitya Tummala 	if (test_bit(FR_FINISHED, &req->flags)) {
4776ba4d272SSahitya Tummala 		spin_unlock(&fiq->waitq.lock);
4786ba4d272SSahitya Tummala 		return;
4796ba4d272SSahitya Tummala 	}
4808f7bb368SMiklos Szeredi 	if (list_empty(&req->intr_entry)) {
481f88996a9SMiklos Szeredi 		list_add_tail(&req->intr_entry, &fiq->interrupts);
4824ce60812SMiklos Szeredi 		wake_up_locked(&fiq->waitq);
4838da6e918SKirill Tkhai 		kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
4848f7bb368SMiklos Szeredi 	}
4854ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
486a4d27e75SMiklos Szeredi }
487a4d27e75SMiklos Szeredi 
4887c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
489334f485dSMiklos Szeredi {
4904ce60812SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
491c4775267SMiklos Szeredi 	int err;
492c4775267SMiklos Szeredi 
493a4d27e75SMiklos Szeredi 	if (!fc->no_interrupt) {
494a4d27e75SMiklos Szeredi 		/* Any signal may interrupt this */
495c4775267SMiklos Szeredi 		err = wait_event_interruptible(req->waitq,
49633e14b4dSMiklos Szeredi 					test_bit(FR_FINISHED, &req->flags));
497c4775267SMiklos Szeredi 		if (!err)
498334f485dSMiklos Szeredi 			return;
499334f485dSMiklos Szeredi 
500825d6d33SMiklos Szeredi 		set_bit(FR_INTERRUPTED, &req->flags);
5018f7bb368SMiklos Szeredi 		/* matches barrier in fuse_dev_do_read() */
5028f7bb368SMiklos Szeredi 		smp_mb__after_atomic();
50333e14b4dSMiklos Szeredi 		if (test_bit(FR_SENT, &req->flags))
5044ce60812SMiklos Szeredi 			queue_interrupt(fiq, req);
505a4d27e75SMiklos Szeredi 	}
506a4d27e75SMiklos Szeredi 
507825d6d33SMiklos Szeredi 	if (!test_bit(FR_FORCE, &req->flags)) {
508a4d27e75SMiklos Szeredi 		/* Only fatal signals may interrupt this */
5097d3a07fcSAl Viro 		err = wait_event_killable(req->waitq,
51033e14b4dSMiklos Szeredi 					test_bit(FR_FINISHED, &req->flags));
511c4775267SMiklos Szeredi 		if (!err)
512a4d27e75SMiklos Szeredi 			return;
513a4d27e75SMiklos Szeredi 
5144ce60812SMiklos Szeredi 		spin_lock(&fiq->waitq.lock);
515a131de0aSMiklos Szeredi 		/* Request is not yet in userspace, bail out */
51633e14b4dSMiklos Szeredi 		if (test_bit(FR_PENDING, &req->flags)) {
517a131de0aSMiklos Szeredi 			list_del(&req->list);
5184ce60812SMiklos Szeredi 			spin_unlock(&fiq->waitq.lock);
519a131de0aSMiklos Szeredi 			__fuse_put_request(req);
520334f485dSMiklos Szeredi 			req->out.h.error = -EINTR;
521a131de0aSMiklos Szeredi 			return;
522a131de0aSMiklos Szeredi 		}
5234ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
524a131de0aSMiklos Szeredi 	}
525a131de0aSMiklos Szeredi 
526a131de0aSMiklos Szeredi 	/*
527a131de0aSMiklos Szeredi 	 * Either request is already in userspace, or it was forced.
528a131de0aSMiklos Szeredi 	 * Wait it out.
529a131de0aSMiklos Szeredi 	 */
53033e14b4dSMiklos Szeredi 	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
531334f485dSMiklos Szeredi }
532334f485dSMiklos Szeredi 
5336a4e922cSEric Wong static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
534334f485dSMiklos Szeredi {
535e16714d8SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
536e16714d8SMiklos Szeredi 
537825d6d33SMiklos Szeredi 	BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
5384ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
539e16714d8SMiklos Szeredi 	if (!fiq->connected) {
5404ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
541334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
542c4775267SMiklos Szeredi 	} else {
543f88996a9SMiklos Szeredi 		req->in.h.unique = fuse_get_unique(fiq);
544f88996a9SMiklos Szeredi 		queue_request(fiq, req);
545334f485dSMiklos Szeredi 		/* acquire extra reference, since request is still needed
546334f485dSMiklos Szeredi 		   after request_end() */
547334f485dSMiklos Szeredi 		__fuse_get_request(req);
5484ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
549334f485dSMiklos Szeredi 
5507c352bdfSMiklos Szeredi 		request_wait_answer(fc, req);
551c4775267SMiklos Szeredi 		/* Pairs with smp_wmb() in request_end() */
552c4775267SMiklos Szeredi 		smp_rmb();
553334f485dSMiklos Szeredi 	}
554334f485dSMiklos Szeredi }
5556a4e922cSEric Wong 
5566a4e922cSEric Wong void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
5576a4e922cSEric Wong {
558825d6d33SMiklos Szeredi 	__set_bit(FR_ISREPLY, &req->flags);
559825d6d33SMiklos Szeredi 	if (!test_bit(FR_WAITING, &req->flags)) {
560825d6d33SMiklos Szeredi 		__set_bit(FR_WAITING, &req->flags);
5615437f241SMiklos Szeredi 		atomic_inc(&fc->num_waiting);
5625437f241SMiklos Szeredi 	}
5636a4e922cSEric Wong 	__fuse_request_send(fc, req);
5646a4e922cSEric Wong }
56508cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send);
566334f485dSMiklos Szeredi 
56721f62174SMiklos Szeredi static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args)
56821f62174SMiklos Szeredi {
56921f62174SMiklos Szeredi 	if (fc->minor < 4 && args->in.h.opcode == FUSE_STATFS)
57021f62174SMiklos Szeredi 		args->out.args[0].size = FUSE_COMPAT_STATFS_SIZE;
57121f62174SMiklos Szeredi 
57221f62174SMiklos Szeredi 	if (fc->minor < 9) {
57321f62174SMiklos Szeredi 		switch (args->in.h.opcode) {
57421f62174SMiklos Szeredi 		case FUSE_LOOKUP:
57521f62174SMiklos Szeredi 		case FUSE_CREATE:
57621f62174SMiklos Szeredi 		case FUSE_MKNOD:
57721f62174SMiklos Szeredi 		case FUSE_MKDIR:
57821f62174SMiklos Szeredi 		case FUSE_SYMLINK:
57921f62174SMiklos Szeredi 		case FUSE_LINK:
58021f62174SMiklos Szeredi 			args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
58121f62174SMiklos Szeredi 			break;
58221f62174SMiklos Szeredi 		case FUSE_GETATTR:
58321f62174SMiklos Szeredi 		case FUSE_SETATTR:
58421f62174SMiklos Szeredi 			args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
58521f62174SMiklos Szeredi 			break;
58621f62174SMiklos Szeredi 		}
58721f62174SMiklos Szeredi 	}
58821f62174SMiklos Szeredi 	if (fc->minor < 12) {
58921f62174SMiklos Szeredi 		switch (args->in.h.opcode) {
59021f62174SMiklos Szeredi 		case FUSE_CREATE:
59121f62174SMiklos Szeredi 			args->in.args[0].size = sizeof(struct fuse_open_in);
59221f62174SMiklos Szeredi 			break;
59321f62174SMiklos Szeredi 		case FUSE_MKNOD:
59421f62174SMiklos Szeredi 			args->in.args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE;
59521f62174SMiklos Szeredi 			break;
59621f62174SMiklos Szeredi 		}
59721f62174SMiklos Szeredi 	}
59821f62174SMiklos Szeredi }
59921f62174SMiklos Szeredi 
6007078187aSMiklos Szeredi ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args)
6017078187aSMiklos Szeredi {
6027078187aSMiklos Szeredi 	struct fuse_req *req;
6037078187aSMiklos Szeredi 	ssize_t ret;
6047078187aSMiklos Szeredi 
6057078187aSMiklos Szeredi 	req = fuse_get_req(fc, 0);
6067078187aSMiklos Szeredi 	if (IS_ERR(req))
6077078187aSMiklos Szeredi 		return PTR_ERR(req);
6087078187aSMiklos Szeredi 
60921f62174SMiklos Szeredi 	/* Needs to be done after fuse_get_req() so that fc->minor is valid */
61021f62174SMiklos Szeredi 	fuse_adjust_compat(fc, args);
61121f62174SMiklos Szeredi 
6127078187aSMiklos Szeredi 	req->in.h.opcode = args->in.h.opcode;
6137078187aSMiklos Szeredi 	req->in.h.nodeid = args->in.h.nodeid;
6147078187aSMiklos Szeredi 	req->in.numargs = args->in.numargs;
6157078187aSMiklos Szeredi 	memcpy(req->in.args, args->in.args,
6167078187aSMiklos Szeredi 	       args->in.numargs * sizeof(struct fuse_in_arg));
6177078187aSMiklos Szeredi 	req->out.argvar = args->out.argvar;
6187078187aSMiklos Szeredi 	req->out.numargs = args->out.numargs;
6197078187aSMiklos Szeredi 	memcpy(req->out.args, args->out.args,
6207078187aSMiklos Szeredi 	       args->out.numargs * sizeof(struct fuse_arg));
6217078187aSMiklos Szeredi 	fuse_request_send(fc, req);
6227078187aSMiklos Szeredi 	ret = req->out.h.error;
6237078187aSMiklos Szeredi 	if (!ret && args->out.argvar) {
6247078187aSMiklos Szeredi 		BUG_ON(args->out.numargs != 1);
6257078187aSMiklos Szeredi 		ret = req->out.args[0].size;
6267078187aSMiklos Szeredi 	}
6277078187aSMiklos Szeredi 	fuse_put_request(fc, req);
6287078187aSMiklos Szeredi 
6297078187aSMiklos Szeredi 	return ret;
6307078187aSMiklos Szeredi }
6317078187aSMiklos Szeredi 
63263825b4eSKirill Tkhai bool fuse_request_queue_background(struct fuse_conn *fc, struct fuse_req *req)
633334f485dSMiklos Szeredi {
63463825b4eSKirill Tkhai 	bool queued = false;
63563825b4eSKirill Tkhai 
63663825b4eSKirill Tkhai 	WARN_ON(!test_bit(FR_BACKGROUND, &req->flags));
637825d6d33SMiklos Szeredi 	if (!test_bit(FR_WAITING, &req->flags)) {
638825d6d33SMiklos Szeredi 		__set_bit(FR_WAITING, &req->flags);
6395437f241SMiklos Szeredi 		atomic_inc(&fc->num_waiting);
6405437f241SMiklos Szeredi 	}
641825d6d33SMiklos Szeredi 	__set_bit(FR_ISREPLY, &req->flags);
642ae2dffa3SKirill Tkhai 	spin_lock(&fc->bg_lock);
64363825b4eSKirill Tkhai 	if (likely(fc->connected)) {
64451eb01e7SMiklos Szeredi 		fc->num_background++;
6457a6d3c8bSCsaba Henk 		if (fc->num_background == fc->max_background)
64651eb01e7SMiklos Szeredi 			fc->blocked = 1;
6477fbbe972SJan Kara 		if (fc->num_background == fc->congestion_threshold && fc->sb) {
6485f7f7543SJan Kara 			set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
6495f7f7543SJan Kara 			set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
650f92b99b9SMiklos Szeredi 		}
651d12def1bSMiklos Szeredi 		list_add_tail(&req->list, &fc->bg_queue);
652d12def1bSMiklos Szeredi 		flush_bg_queue(fc);
65363825b4eSKirill Tkhai 		queued = true;
65463825b4eSKirill Tkhai 	}
655ae2dffa3SKirill Tkhai 	spin_unlock(&fc->bg_lock);
65663825b4eSKirill Tkhai 
65763825b4eSKirill Tkhai 	return queued;
658d12def1bSMiklos Szeredi }
65951eb01e7SMiklos Szeredi 
660f0139aa8SMiklos Szeredi void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
661d12def1bSMiklos Szeredi {
66263825b4eSKirill Tkhai 	WARN_ON(!req->end);
66363825b4eSKirill Tkhai 	if (!fuse_request_queue_background(fc, req)) {
664334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
66542dc6211SMiklos Szeredi 		req->end(fc, req);
66642dc6211SMiklos Szeredi 		fuse_put_request(fc, req);
667334f485dSMiklos Szeredi 	}
668334f485dSMiklos Szeredi }
66908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_request_send_background);
670334f485dSMiklos Szeredi 
6712d45ba38SMiklos Szeredi static int fuse_request_send_notify_reply(struct fuse_conn *fc,
6722d45ba38SMiklos Szeredi 					  struct fuse_req *req, u64 unique)
6732d45ba38SMiklos Szeredi {
6742d45ba38SMiklos Szeredi 	int err = -ENODEV;
675f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
6762d45ba38SMiklos Szeredi 
677825d6d33SMiklos Szeredi 	__clear_bit(FR_ISREPLY, &req->flags);
6782d45ba38SMiklos Szeredi 	req->in.h.unique = unique;
6794ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
680e16714d8SMiklos Szeredi 	if (fiq->connected) {
681f88996a9SMiklos Szeredi 		queue_request(fiq, req);
6822d45ba38SMiklos Szeredi 		err = 0;
6832d45ba38SMiklos Szeredi 	}
6844ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
6852d45ba38SMiklos Szeredi 
6862d45ba38SMiklos Szeredi 	return err;
6872d45ba38SMiklos Szeredi }
6882d45ba38SMiklos Szeredi 
6890b05b183SAnand V. Avati void fuse_force_forget(struct file *file, u64 nodeid)
6900b05b183SAnand V. Avati {
6916131ffaaSAl Viro 	struct inode *inode = file_inode(file);
6920b05b183SAnand V. Avati 	struct fuse_conn *fc = get_fuse_conn(inode);
6930b05b183SAnand V. Avati 	struct fuse_req *req;
6940b05b183SAnand V. Avati 	struct fuse_forget_in inarg;
6950b05b183SAnand V. Avati 
6960b05b183SAnand V. Avati 	memset(&inarg, 0, sizeof(inarg));
6970b05b183SAnand V. Avati 	inarg.nlookup = 1;
698b111c8c0SMaxim Patlasov 	req = fuse_get_req_nofail_nopages(fc, file);
6990b05b183SAnand V. Avati 	req->in.h.opcode = FUSE_FORGET;
7000b05b183SAnand V. Avati 	req->in.h.nodeid = nodeid;
7010b05b183SAnand V. Avati 	req->in.numargs = 1;
7020b05b183SAnand V. Avati 	req->in.args[0].size = sizeof(inarg);
7030b05b183SAnand V. Avati 	req->in.args[0].value = &inarg;
704825d6d33SMiklos Szeredi 	__clear_bit(FR_ISREPLY, &req->flags);
7056a4e922cSEric Wong 	__fuse_request_send(fc, req);
7066a4e922cSEric Wong 	/* ignore errors */
7076a4e922cSEric Wong 	fuse_put_request(fc, req);
7080b05b183SAnand V. Avati }
7090b05b183SAnand V. Avati 
7103be5a52bSMiklos Szeredi /*
711334f485dSMiklos Szeredi  * Lock the request.  Up to the next unlock_request() there mustn't be
712334f485dSMiklos Szeredi  * anything that could cause a page-fault.  If the request was already
713f9a2842eSMiklos Szeredi  * aborted bail out.
714334f485dSMiklos Szeredi  */
715dc00809aSMiklos Szeredi static int lock_request(struct fuse_req *req)
716334f485dSMiklos Szeredi {
717334f485dSMiklos Szeredi 	int err = 0;
718334f485dSMiklos Szeredi 	if (req) {
719dc00809aSMiklos Szeredi 		spin_lock(&req->waitq.lock);
720825d6d33SMiklos Szeredi 		if (test_bit(FR_ABORTED, &req->flags))
721334f485dSMiklos Szeredi 			err = -ENOENT;
722334f485dSMiklos Szeredi 		else
723825d6d33SMiklos Szeredi 			set_bit(FR_LOCKED, &req->flags);
724dc00809aSMiklos Szeredi 		spin_unlock(&req->waitq.lock);
725334f485dSMiklos Szeredi 	}
726334f485dSMiklos Szeredi 	return err;
727334f485dSMiklos Szeredi }
728334f485dSMiklos Szeredi 
729334f485dSMiklos Szeredi /*
7300d8e84b0SMiklos Szeredi  * Unlock request.  If it was aborted while locked, caller is responsible
7310d8e84b0SMiklos Szeredi  * for unlocking and ending the request.
732334f485dSMiklos Szeredi  */
733dc00809aSMiklos Szeredi static int unlock_request(struct fuse_req *req)
734334f485dSMiklos Szeredi {
7350d8e84b0SMiklos Szeredi 	int err = 0;
736334f485dSMiklos Szeredi 	if (req) {
737dc00809aSMiklos Szeredi 		spin_lock(&req->waitq.lock);
738825d6d33SMiklos Szeredi 		if (test_bit(FR_ABORTED, &req->flags))
7390d8e84b0SMiklos Szeredi 			err = -ENOENT;
7400d8e84b0SMiklos Szeredi 		else
741825d6d33SMiklos Szeredi 			clear_bit(FR_LOCKED, &req->flags);
742dc00809aSMiklos Szeredi 		spin_unlock(&req->waitq.lock);
743334f485dSMiklos Szeredi 	}
7440d8e84b0SMiklos Szeredi 	return err;
745334f485dSMiklos Szeredi }
746334f485dSMiklos Szeredi 
747334f485dSMiklos Szeredi struct fuse_copy_state {
748334f485dSMiklos Szeredi 	int write;
749334f485dSMiklos Szeredi 	struct fuse_req *req;
7506c09e94aSAl Viro 	struct iov_iter *iter;
751dd3bb14fSMiklos Szeredi 	struct pipe_buffer *pipebufs;
752dd3bb14fSMiklos Szeredi 	struct pipe_buffer *currbuf;
753dd3bb14fSMiklos Szeredi 	struct pipe_inode_info *pipe;
754334f485dSMiklos Szeredi 	unsigned long nr_segs;
755334f485dSMiklos Szeredi 	struct page *pg;
756334f485dSMiklos Szeredi 	unsigned len;
757c55a01d3SMiklos Szeredi 	unsigned offset;
758ce534fb0SMiklos Szeredi 	unsigned move_pages:1;
759334f485dSMiklos Szeredi };
760334f485dSMiklos Szeredi 
761dc00809aSMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, int write,
7626c09e94aSAl Viro 			   struct iov_iter *iter)
763334f485dSMiklos Szeredi {
764334f485dSMiklos Szeredi 	memset(cs, 0, sizeof(*cs));
765334f485dSMiklos Szeredi 	cs->write = write;
7666c09e94aSAl Viro 	cs->iter = iter;
767334f485dSMiklos Szeredi }
768334f485dSMiklos Szeredi 
769334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */
7708bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs)
771334f485dSMiklos Szeredi {
772dd3bb14fSMiklos Szeredi 	if (cs->currbuf) {
773dd3bb14fSMiklos Szeredi 		struct pipe_buffer *buf = cs->currbuf;
774dd3bb14fSMiklos Szeredi 
775c55a01d3SMiklos Szeredi 		if (cs->write)
776c3021629SMiklos Szeredi 			buf->len = PAGE_SIZE - cs->len;
777dd3bb14fSMiklos Szeredi 		cs->currbuf = NULL;
778c55a01d3SMiklos Szeredi 	} else if (cs->pg) {
779334f485dSMiklos Szeredi 		if (cs->write) {
780334f485dSMiklos Szeredi 			flush_dcache_page(cs->pg);
781334f485dSMiklos Szeredi 			set_page_dirty_lock(cs->pg);
782334f485dSMiklos Szeredi 		}
783334f485dSMiklos Szeredi 		put_page(cs->pg);
784334f485dSMiklos Szeredi 	}
785c55a01d3SMiklos Szeredi 	cs->pg = NULL;
786334f485dSMiklos Szeredi }
787334f485dSMiklos Szeredi 
788334f485dSMiklos Szeredi /*
789334f485dSMiklos Szeredi  * Get another pagefull of userspace buffer, and map it to kernel
790334f485dSMiklos Szeredi  * address space, and lock request
791334f485dSMiklos Szeredi  */
792334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs)
793334f485dSMiklos Szeredi {
794c55a01d3SMiklos Szeredi 	struct page *page;
795334f485dSMiklos Szeredi 	int err;
796334f485dSMiklos Szeredi 
797dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
7980d8e84b0SMiklos Szeredi 	if (err)
7990d8e84b0SMiklos Szeredi 		return err;
8000d8e84b0SMiklos Szeredi 
801334f485dSMiklos Szeredi 	fuse_copy_finish(cs);
802dd3bb14fSMiklos Szeredi 	if (cs->pipebufs) {
803dd3bb14fSMiklos Szeredi 		struct pipe_buffer *buf = cs->pipebufs;
804dd3bb14fSMiklos Szeredi 
805c3021629SMiklos Szeredi 		if (!cs->write) {
806fba597dbSMiklos Szeredi 			err = pipe_buf_confirm(cs->pipe, buf);
807dd3bb14fSMiklos Szeredi 			if (err)
808dd3bb14fSMiklos Szeredi 				return err;
809dd3bb14fSMiklos Szeredi 
810dd3bb14fSMiklos Szeredi 			BUG_ON(!cs->nr_segs);
811dd3bb14fSMiklos Szeredi 			cs->currbuf = buf;
812c55a01d3SMiklos Szeredi 			cs->pg = buf->page;
813c55a01d3SMiklos Szeredi 			cs->offset = buf->offset;
814dd3bb14fSMiklos Szeredi 			cs->len = buf->len;
815dd3bb14fSMiklos Szeredi 			cs->pipebufs++;
816dd3bb14fSMiklos Szeredi 			cs->nr_segs--;
817dd3bb14fSMiklos Szeredi 		} else {
818c3021629SMiklos Szeredi 			if (cs->nr_segs == cs->pipe->buffers)
819c3021629SMiklos Szeredi 				return -EIO;
820c3021629SMiklos Szeredi 
821c3021629SMiklos Szeredi 			page = alloc_page(GFP_HIGHUSER);
822c3021629SMiklos Szeredi 			if (!page)
823c3021629SMiklos Szeredi 				return -ENOMEM;
824c3021629SMiklos Szeredi 
825c3021629SMiklos Szeredi 			buf->page = page;
826c3021629SMiklos Szeredi 			buf->offset = 0;
827c3021629SMiklos Szeredi 			buf->len = 0;
828c3021629SMiklos Szeredi 
829c3021629SMiklos Szeredi 			cs->currbuf = buf;
830c55a01d3SMiklos Szeredi 			cs->pg = page;
831c55a01d3SMiklos Szeredi 			cs->offset = 0;
832c3021629SMiklos Szeredi 			cs->len = PAGE_SIZE;
833c3021629SMiklos Szeredi 			cs->pipebufs++;
834c3021629SMiklos Szeredi 			cs->nr_segs++;
835c3021629SMiklos Szeredi 		}
836c3021629SMiklos Szeredi 	} else {
8376c09e94aSAl Viro 		size_t off;
8386c09e94aSAl Viro 		err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off);
839334f485dSMiklos Szeredi 		if (err < 0)
840334f485dSMiklos Szeredi 			return err;
8416c09e94aSAl Viro 		BUG_ON(!err);
8426c09e94aSAl Viro 		cs->len = err;
8436c09e94aSAl Viro 		cs->offset = off;
844c55a01d3SMiklos Szeredi 		cs->pg = page;
8456c09e94aSAl Viro 		iov_iter_advance(cs->iter, err);
846dd3bb14fSMiklos Szeredi 	}
847334f485dSMiklos Szeredi 
848dc00809aSMiklos Szeredi 	return lock_request(cs->req);
849334f485dSMiklos Szeredi }
850334f485dSMiklos Szeredi 
851334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */
8528bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
853334f485dSMiklos Szeredi {
854334f485dSMiklos Szeredi 	unsigned ncpy = min(*size, cs->len);
855334f485dSMiklos Szeredi 	if (val) {
856c55a01d3SMiklos Szeredi 		void *pgaddr = kmap_atomic(cs->pg);
857c55a01d3SMiklos Szeredi 		void *buf = pgaddr + cs->offset;
858c55a01d3SMiklos Szeredi 
859334f485dSMiklos Szeredi 		if (cs->write)
860c55a01d3SMiklos Szeredi 			memcpy(buf, *val, ncpy);
861334f485dSMiklos Szeredi 		else
862c55a01d3SMiklos Szeredi 			memcpy(*val, buf, ncpy);
863c55a01d3SMiklos Szeredi 
864c55a01d3SMiklos Szeredi 		kunmap_atomic(pgaddr);
865334f485dSMiklos Szeredi 		*val += ncpy;
866334f485dSMiklos Szeredi 	}
867334f485dSMiklos Szeredi 	*size -= ncpy;
868334f485dSMiklos Szeredi 	cs->len -= ncpy;
869c55a01d3SMiklos Szeredi 	cs->offset += ncpy;
870334f485dSMiklos Szeredi 	return ncpy;
871334f485dSMiklos Szeredi }
872334f485dSMiklos Szeredi 
873ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page)
874ce534fb0SMiklos Szeredi {
875ce534fb0SMiklos Szeredi 	if (page_mapcount(page) ||
876ce534fb0SMiklos Szeredi 	    page->mapping != NULL ||
877ce534fb0SMiklos Szeredi 	    page_count(page) != 1 ||
878ce534fb0SMiklos Szeredi 	    (page->flags & PAGE_FLAGS_CHECK_AT_PREP &
879ce534fb0SMiklos Szeredi 	     ~(1 << PG_locked |
880ce534fb0SMiklos Szeredi 	       1 << PG_referenced |
881ce534fb0SMiklos Szeredi 	       1 << PG_uptodate |
882ce534fb0SMiklos Szeredi 	       1 << PG_lru |
883ce534fb0SMiklos Szeredi 	       1 << PG_active |
884ce534fb0SMiklos Szeredi 	       1 << PG_reclaim))) {
885ce534fb0SMiklos Szeredi 		printk(KERN_WARNING "fuse: trying to steal weird page\n");
886ce534fb0SMiklos 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);
887ce534fb0SMiklos Szeredi 		return 1;
888ce534fb0SMiklos Szeredi 	}
889ce534fb0SMiklos Szeredi 	return 0;
890ce534fb0SMiklos Szeredi }
891ce534fb0SMiklos Szeredi 
892ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
893ce534fb0SMiklos Szeredi {
894ce534fb0SMiklos Szeredi 	int err;
895ce534fb0SMiklos Szeredi 	struct page *oldpage = *pagep;
896ce534fb0SMiklos Szeredi 	struct page *newpage;
897ce534fb0SMiklos Szeredi 	struct pipe_buffer *buf = cs->pipebufs;
898ce534fb0SMiklos Szeredi 
899dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
9000d8e84b0SMiklos Szeredi 	if (err)
9010d8e84b0SMiklos Szeredi 		return err;
9020d8e84b0SMiklos Szeredi 
903ce534fb0SMiklos Szeredi 	fuse_copy_finish(cs);
904ce534fb0SMiklos Szeredi 
905fba597dbSMiklos Szeredi 	err = pipe_buf_confirm(cs->pipe, buf);
906ce534fb0SMiklos Szeredi 	if (err)
907ce534fb0SMiklos Szeredi 		return err;
908ce534fb0SMiklos Szeredi 
909ce534fb0SMiklos Szeredi 	BUG_ON(!cs->nr_segs);
910ce534fb0SMiklos Szeredi 	cs->currbuf = buf;
911ce534fb0SMiklos Szeredi 	cs->len = buf->len;
912ce534fb0SMiklos Szeredi 	cs->pipebufs++;
913ce534fb0SMiklos Szeredi 	cs->nr_segs--;
914ce534fb0SMiklos Szeredi 
915ce534fb0SMiklos Szeredi 	if (cs->len != PAGE_SIZE)
916ce534fb0SMiklos Szeredi 		goto out_fallback;
917ce534fb0SMiklos Szeredi 
918ca76f5b6SMiklos Szeredi 	if (pipe_buf_steal(cs->pipe, buf) != 0)
919ce534fb0SMiklos Szeredi 		goto out_fallback;
920ce534fb0SMiklos Szeredi 
921ce534fb0SMiklos Szeredi 	newpage = buf->page;
922ce534fb0SMiklos Szeredi 
923aa991b3bSMiklos Szeredi 	if (!PageUptodate(newpage))
924aa991b3bSMiklos Szeredi 		SetPageUptodate(newpage);
925ce534fb0SMiklos Szeredi 
926ce534fb0SMiklos Szeredi 	ClearPageMappedToDisk(newpage);
927ce534fb0SMiklos Szeredi 
928ce534fb0SMiklos Szeredi 	if (fuse_check_page(newpage) != 0)
929ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
930ce534fb0SMiklos Szeredi 
931ce534fb0SMiklos Szeredi 	/*
932ce534fb0SMiklos Szeredi 	 * This is a new and locked page, it shouldn't be mapped or
933ce534fb0SMiklos Szeredi 	 * have any special flags on it
934ce534fb0SMiklos Szeredi 	 */
935ce534fb0SMiklos Szeredi 	if (WARN_ON(page_mapped(oldpage)))
936ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
937ce534fb0SMiklos Szeredi 	if (WARN_ON(page_has_private(oldpage)))
938ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
939ce534fb0SMiklos Szeredi 	if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage)))
940ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
941ce534fb0SMiklos Szeredi 	if (WARN_ON(PageMlocked(oldpage)))
942ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
943ce534fb0SMiklos Szeredi 
944ef6a3c63SMiklos Szeredi 	err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL);
945ce534fb0SMiklos Szeredi 	if (err) {
946ef6a3c63SMiklos Szeredi 		unlock_page(newpage);
947ef6a3c63SMiklos Szeredi 		return err;
948ce534fb0SMiklos Szeredi 	}
949ef6a3c63SMiklos Szeredi 
95009cbfeafSKirill A. Shutemov 	get_page(newpage);
951ce534fb0SMiklos Szeredi 
952ce534fb0SMiklos Szeredi 	if (!(buf->flags & PIPE_BUF_FLAG_LRU))
953ce534fb0SMiklos Szeredi 		lru_cache_add_file(newpage);
954ce534fb0SMiklos Szeredi 
955ce534fb0SMiklos Szeredi 	err = 0;
956dc00809aSMiklos Szeredi 	spin_lock(&cs->req->waitq.lock);
957825d6d33SMiklos Szeredi 	if (test_bit(FR_ABORTED, &cs->req->flags))
958ce534fb0SMiklos Szeredi 		err = -ENOENT;
959ce534fb0SMiklos Szeredi 	else
960ce534fb0SMiklos Szeredi 		*pagep = newpage;
961dc00809aSMiklos Szeredi 	spin_unlock(&cs->req->waitq.lock);
962ce534fb0SMiklos Szeredi 
963ce534fb0SMiklos Szeredi 	if (err) {
964ce534fb0SMiklos Szeredi 		unlock_page(newpage);
96509cbfeafSKirill A. Shutemov 		put_page(newpage);
966ce534fb0SMiklos Szeredi 		return err;
967ce534fb0SMiklos Szeredi 	}
968ce534fb0SMiklos Szeredi 
969ce534fb0SMiklos Szeredi 	unlock_page(oldpage);
97009cbfeafSKirill A. Shutemov 	put_page(oldpage);
971ce534fb0SMiklos Szeredi 	cs->len = 0;
972ce534fb0SMiklos Szeredi 
973ce534fb0SMiklos Szeredi 	return 0;
974ce534fb0SMiklos Szeredi 
975ce534fb0SMiklos Szeredi out_fallback_unlock:
976ce534fb0SMiklos Szeredi 	unlock_page(newpage);
977ce534fb0SMiklos Szeredi out_fallback:
978c55a01d3SMiklos Szeredi 	cs->pg = buf->page;
979c55a01d3SMiklos Szeredi 	cs->offset = buf->offset;
980ce534fb0SMiklos Szeredi 
981dc00809aSMiklos Szeredi 	err = lock_request(cs->req);
982ce534fb0SMiklos Szeredi 	if (err)
983ce534fb0SMiklos Szeredi 		return err;
984ce534fb0SMiklos Szeredi 
985ce534fb0SMiklos Szeredi 	return 1;
986ce534fb0SMiklos Szeredi }
987ce534fb0SMiklos Szeredi 
988c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
989c3021629SMiklos Szeredi 			 unsigned offset, unsigned count)
990c3021629SMiklos Szeredi {
991c3021629SMiklos Szeredi 	struct pipe_buffer *buf;
9920d8e84b0SMiklos Szeredi 	int err;
993c3021629SMiklos Szeredi 
994c3021629SMiklos Szeredi 	if (cs->nr_segs == cs->pipe->buffers)
995c3021629SMiklos Szeredi 		return -EIO;
996c3021629SMiklos Szeredi 
997dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
9980d8e84b0SMiklos Szeredi 	if (err)
9990d8e84b0SMiklos Szeredi 		return err;
10000d8e84b0SMiklos Szeredi 
1001c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
1002c3021629SMiklos Szeredi 
1003c3021629SMiklos Szeredi 	buf = cs->pipebufs;
100409cbfeafSKirill A. Shutemov 	get_page(page);
1005c3021629SMiklos Szeredi 	buf->page = page;
1006c3021629SMiklos Szeredi 	buf->offset = offset;
1007c3021629SMiklos Szeredi 	buf->len = count;
1008c3021629SMiklos Szeredi 
1009c3021629SMiklos Szeredi 	cs->pipebufs++;
1010c3021629SMiklos Szeredi 	cs->nr_segs++;
1011c3021629SMiklos Szeredi 	cs->len = 0;
1012c3021629SMiklos Szeredi 
1013c3021629SMiklos Szeredi 	return 0;
1014c3021629SMiklos Szeredi }
1015c3021629SMiklos Szeredi 
1016334f485dSMiklos Szeredi /*
1017334f485dSMiklos Szeredi  * Copy a page in the request to/from the userspace buffer.  Must be
1018334f485dSMiklos Szeredi  * done atomically
1019334f485dSMiklos Szeredi  */
1020ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
1021334f485dSMiklos Szeredi 			  unsigned offset, unsigned count, int zeroing)
1022334f485dSMiklos Szeredi {
1023ce534fb0SMiklos Szeredi 	int err;
1024ce534fb0SMiklos Szeredi 	struct page *page = *pagep;
1025ce534fb0SMiklos Szeredi 
1026b6777c40SMiklos Szeredi 	if (page && zeroing && count < PAGE_SIZE)
1027b6777c40SMiklos Szeredi 		clear_highpage(page);
1028b6777c40SMiklos Szeredi 
1029334f485dSMiklos Szeredi 	while (count) {
1030c3021629SMiklos Szeredi 		if (cs->write && cs->pipebufs && page) {
1031c3021629SMiklos Szeredi 			return fuse_ref_page(cs, page, offset, count);
1032c3021629SMiklos Szeredi 		} else if (!cs->len) {
1033ce534fb0SMiklos Szeredi 			if (cs->move_pages && page &&
1034ce534fb0SMiklos Szeredi 			    offset == 0 && count == PAGE_SIZE) {
1035ce534fb0SMiklos Szeredi 				err = fuse_try_move_page(cs, pagep);
1036ce534fb0SMiklos Szeredi 				if (err <= 0)
1037ce534fb0SMiklos Szeredi 					return err;
1038ce534fb0SMiklos Szeredi 			} else {
1039ce534fb0SMiklos Szeredi 				err = fuse_copy_fill(cs);
10401729a16cSMiklos Szeredi 				if (err)
1041334f485dSMiklos Szeredi 					return err;
10421729a16cSMiklos Szeredi 			}
1043ce534fb0SMiklos Szeredi 		}
1044334f485dSMiklos Szeredi 		if (page) {
10452408f6efSCong Wang 			void *mapaddr = kmap_atomic(page);
1046334f485dSMiklos Szeredi 			void *buf = mapaddr + offset;
1047334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, &buf, &count);
10482408f6efSCong Wang 			kunmap_atomic(mapaddr);
1049334f485dSMiklos Szeredi 		} else
1050334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, NULL, &count);
1051334f485dSMiklos Szeredi 	}
1052334f485dSMiklos Szeredi 	if (page && !cs->write)
1053334f485dSMiklos Szeredi 		flush_dcache_page(page);
1054334f485dSMiklos Szeredi 	return 0;
1055334f485dSMiklos Szeredi }
1056334f485dSMiklos Szeredi 
1057334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */
1058334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
1059334f485dSMiklos Szeredi 			   int zeroing)
1060334f485dSMiklos Szeredi {
1061334f485dSMiklos Szeredi 	unsigned i;
1062334f485dSMiklos Szeredi 	struct fuse_req *req = cs->req;
1063334f485dSMiklos Szeredi 
1064334f485dSMiklos Szeredi 	for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
1065ce534fb0SMiklos Szeredi 		int err;
106685f40aecSMaxim Patlasov 		unsigned offset = req->page_descs[i].offset;
106785f40aecSMaxim Patlasov 		unsigned count = min(nbytes, req->page_descs[i].length);
1068ce534fb0SMiklos Szeredi 
1069ce534fb0SMiklos Szeredi 		err = fuse_copy_page(cs, &req->pages[i], offset, count,
1070ce534fb0SMiklos Szeredi 				     zeroing);
1071334f485dSMiklos Szeredi 		if (err)
1072334f485dSMiklos Szeredi 			return err;
1073334f485dSMiklos Szeredi 
1074334f485dSMiklos Szeredi 		nbytes -= count;
1075334f485dSMiklos Szeredi 	}
1076334f485dSMiklos Szeredi 	return 0;
1077334f485dSMiklos Szeredi }
1078334f485dSMiklos Szeredi 
1079334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */
1080334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
1081334f485dSMiklos Szeredi {
1082334f485dSMiklos Szeredi 	while (size) {
10831729a16cSMiklos Szeredi 		if (!cs->len) {
10841729a16cSMiklos Szeredi 			int err = fuse_copy_fill(cs);
10851729a16cSMiklos Szeredi 			if (err)
1086334f485dSMiklos Szeredi 				return err;
10871729a16cSMiklos Szeredi 		}
1088334f485dSMiklos Szeredi 		fuse_copy_do(cs, &val, &size);
1089334f485dSMiklos Szeredi 	}
1090334f485dSMiklos Szeredi 	return 0;
1091334f485dSMiklos Szeredi }
1092334f485dSMiklos Szeredi 
1093334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */
1094334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
1095334f485dSMiklos Szeredi 			  unsigned argpages, struct fuse_arg *args,
1096334f485dSMiklos Szeredi 			  int zeroing)
1097334f485dSMiklos Szeredi {
1098334f485dSMiklos Szeredi 	int err = 0;
1099334f485dSMiklos Szeredi 	unsigned i;
1100334f485dSMiklos Szeredi 
1101334f485dSMiklos Szeredi 	for (i = 0; !err && i < numargs; i++)  {
1102334f485dSMiklos Szeredi 		struct fuse_arg *arg = &args[i];
1103334f485dSMiklos Szeredi 		if (i == numargs - 1 && argpages)
1104334f485dSMiklos Szeredi 			err = fuse_copy_pages(cs, arg->size, zeroing);
1105334f485dSMiklos Szeredi 		else
1106334f485dSMiklos Szeredi 			err = fuse_copy_one(cs, arg->value, arg->size);
1107334f485dSMiklos Szeredi 	}
1108334f485dSMiklos Szeredi 	return err;
1109334f485dSMiklos Szeredi }
1110334f485dSMiklos Szeredi 
1111f88996a9SMiklos Szeredi static int forget_pending(struct fuse_iqueue *fiq)
111207e77dcaSMiklos Szeredi {
1113f88996a9SMiklos Szeredi 	return fiq->forget_list_head.next != NULL;
111407e77dcaSMiklos Szeredi }
111507e77dcaSMiklos Szeredi 
1116f88996a9SMiklos Szeredi static int request_pending(struct fuse_iqueue *fiq)
1117a4d27e75SMiklos Szeredi {
1118f88996a9SMiklos Szeredi 	return !list_empty(&fiq->pending) || !list_empty(&fiq->interrupts) ||
1119f88996a9SMiklos Szeredi 		forget_pending(fiq);
1120a4d27e75SMiklos Szeredi }
1121a4d27e75SMiklos Szeredi 
1122334f485dSMiklos Szeredi /*
1123a4d27e75SMiklos Szeredi  * Transfer an interrupt request to userspace
1124a4d27e75SMiklos Szeredi  *
1125a4d27e75SMiklos Szeredi  * Unlike other requests this is assembled on demand, without a need
1126a4d27e75SMiklos Szeredi  * to allocate a separate fuse_req structure.
1127a4d27e75SMiklos Szeredi  *
1128fd22d62eSMiklos Szeredi  * Called with fiq->waitq.lock held, releases it
1129a4d27e75SMiklos Szeredi  */
1130fd22d62eSMiklos Szeredi static int fuse_read_interrupt(struct fuse_iqueue *fiq,
1131fd22d62eSMiklos Szeredi 			       struct fuse_copy_state *cs,
1132c3021629SMiklos Szeredi 			       size_t nbytes, struct fuse_req *req)
1133fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock)
1134a4d27e75SMiklos Szeredi {
1135a4d27e75SMiklos Szeredi 	struct fuse_in_header ih;
1136a4d27e75SMiklos Szeredi 	struct fuse_interrupt_in arg;
1137a4d27e75SMiklos Szeredi 	unsigned reqsize = sizeof(ih) + sizeof(arg);
1138a4d27e75SMiklos Szeredi 	int err;
1139a4d27e75SMiklos Szeredi 
1140a4d27e75SMiklos Szeredi 	list_del_init(&req->intr_entry);
1141a4d27e75SMiklos Szeredi 	memset(&ih, 0, sizeof(ih));
1142a4d27e75SMiklos Szeredi 	memset(&arg, 0, sizeof(arg));
1143a4d27e75SMiklos Szeredi 	ih.len = reqsize;
1144a4d27e75SMiklos Szeredi 	ih.opcode = FUSE_INTERRUPT;
11453a5358d1SKirill Tkhai 	ih.unique = (req->in.h.unique | FUSE_INT_REQ_BIT);
1146a4d27e75SMiklos Szeredi 	arg.unique = req->in.h.unique;
1147a4d27e75SMiklos Szeredi 
11484ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
1149c3021629SMiklos Szeredi 	if (nbytes < reqsize)
1150a4d27e75SMiklos Szeredi 		return -EINVAL;
1151a4d27e75SMiklos Szeredi 
1152c3021629SMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
1153a4d27e75SMiklos Szeredi 	if (!err)
1154c3021629SMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
1155c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
1156a4d27e75SMiklos Szeredi 
1157a4d27e75SMiklos Szeredi 	return err ? err : reqsize;
1158a4d27e75SMiklos Szeredi }
1159a4d27e75SMiklos Szeredi 
1160f88996a9SMiklos Szeredi static struct fuse_forget_link *dequeue_forget(struct fuse_iqueue *fiq,
116102c048b9SMiklos Szeredi 					       unsigned max,
116202c048b9SMiklos Szeredi 					       unsigned *countp)
116307e77dcaSMiklos Szeredi {
1164f88996a9SMiklos Szeredi 	struct fuse_forget_link *head = fiq->forget_list_head.next;
116502c048b9SMiklos Szeredi 	struct fuse_forget_link **newhead = &head;
116602c048b9SMiklos Szeredi 	unsigned count;
116707e77dcaSMiklos Szeredi 
116802c048b9SMiklos Szeredi 	for (count = 0; *newhead != NULL && count < max; count++)
116902c048b9SMiklos Szeredi 		newhead = &(*newhead)->next;
117002c048b9SMiklos Szeredi 
1171f88996a9SMiklos Szeredi 	fiq->forget_list_head.next = *newhead;
117202c048b9SMiklos Szeredi 	*newhead = NULL;
1173f88996a9SMiklos Szeredi 	if (fiq->forget_list_head.next == NULL)
1174f88996a9SMiklos Szeredi 		fiq->forget_list_tail = &fiq->forget_list_head;
117507e77dcaSMiklos Szeredi 
117602c048b9SMiklos Szeredi 	if (countp != NULL)
117702c048b9SMiklos Szeredi 		*countp = count;
117802c048b9SMiklos Szeredi 
117902c048b9SMiklos Szeredi 	return head;
118007e77dcaSMiklos Szeredi }
118107e77dcaSMiklos Szeredi 
1182fd22d62eSMiklos Szeredi static int fuse_read_single_forget(struct fuse_iqueue *fiq,
118307e77dcaSMiklos Szeredi 				   struct fuse_copy_state *cs,
118407e77dcaSMiklos Szeredi 				   size_t nbytes)
1185fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock)
118607e77dcaSMiklos Szeredi {
118707e77dcaSMiklos Szeredi 	int err;
1188f88996a9SMiklos Szeredi 	struct fuse_forget_link *forget = dequeue_forget(fiq, 1, NULL);
118907e77dcaSMiklos Szeredi 	struct fuse_forget_in arg = {
119002c048b9SMiklos Szeredi 		.nlookup = forget->forget_one.nlookup,
119107e77dcaSMiklos Szeredi 	};
119207e77dcaSMiklos Szeredi 	struct fuse_in_header ih = {
119307e77dcaSMiklos Szeredi 		.opcode = FUSE_FORGET,
119402c048b9SMiklos Szeredi 		.nodeid = forget->forget_one.nodeid,
1195f88996a9SMiklos Szeredi 		.unique = fuse_get_unique(fiq),
119607e77dcaSMiklos Szeredi 		.len = sizeof(ih) + sizeof(arg),
119707e77dcaSMiklos Szeredi 	};
119807e77dcaSMiklos Szeredi 
11994ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
120007e77dcaSMiklos Szeredi 	kfree(forget);
120107e77dcaSMiklos Szeredi 	if (nbytes < ih.len)
120207e77dcaSMiklos Szeredi 		return -EINVAL;
120307e77dcaSMiklos Szeredi 
120407e77dcaSMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
120507e77dcaSMiklos Szeredi 	if (!err)
120607e77dcaSMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
120707e77dcaSMiklos Szeredi 	fuse_copy_finish(cs);
120807e77dcaSMiklos Szeredi 
120907e77dcaSMiklos Szeredi 	if (err)
121007e77dcaSMiklos Szeredi 		return err;
121107e77dcaSMiklos Szeredi 
121207e77dcaSMiklos Szeredi 	return ih.len;
121307e77dcaSMiklos Szeredi }
121407e77dcaSMiklos Szeredi 
1215fd22d62eSMiklos Szeredi static int fuse_read_batch_forget(struct fuse_iqueue *fiq,
121602c048b9SMiklos Szeredi 				   struct fuse_copy_state *cs, size_t nbytes)
1217fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock)
121802c048b9SMiklos Szeredi {
121902c048b9SMiklos Szeredi 	int err;
122002c048b9SMiklos Szeredi 	unsigned max_forgets;
122102c048b9SMiklos Szeredi 	unsigned count;
122202c048b9SMiklos Szeredi 	struct fuse_forget_link *head;
122302c048b9SMiklos Szeredi 	struct fuse_batch_forget_in arg = { .count = 0 };
122402c048b9SMiklos Szeredi 	struct fuse_in_header ih = {
122502c048b9SMiklos Szeredi 		.opcode = FUSE_BATCH_FORGET,
1226f88996a9SMiklos Szeredi 		.unique = fuse_get_unique(fiq),
122702c048b9SMiklos Szeredi 		.len = sizeof(ih) + sizeof(arg),
122802c048b9SMiklos Szeredi 	};
122902c048b9SMiklos Szeredi 
123002c048b9SMiklos Szeredi 	if (nbytes < ih.len) {
12314ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
123202c048b9SMiklos Szeredi 		return -EINVAL;
123302c048b9SMiklos Szeredi 	}
123402c048b9SMiklos Szeredi 
123502c048b9SMiklos Szeredi 	max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one);
1236f88996a9SMiklos Szeredi 	head = dequeue_forget(fiq, max_forgets, &count);
12374ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
123802c048b9SMiklos Szeredi 
123902c048b9SMiklos Szeredi 	arg.count = count;
124002c048b9SMiklos Szeredi 	ih.len += count * sizeof(struct fuse_forget_one);
124102c048b9SMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
124202c048b9SMiklos Szeredi 	if (!err)
124302c048b9SMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
124402c048b9SMiklos Szeredi 
124502c048b9SMiklos Szeredi 	while (head) {
124602c048b9SMiklos Szeredi 		struct fuse_forget_link *forget = head;
124702c048b9SMiklos Szeredi 
124802c048b9SMiklos Szeredi 		if (!err) {
124902c048b9SMiklos Szeredi 			err = fuse_copy_one(cs, &forget->forget_one,
125002c048b9SMiklos Szeredi 					    sizeof(forget->forget_one));
125102c048b9SMiklos Szeredi 		}
125202c048b9SMiklos Szeredi 		head = forget->next;
125302c048b9SMiklos Szeredi 		kfree(forget);
125402c048b9SMiklos Szeredi 	}
125502c048b9SMiklos Szeredi 
125602c048b9SMiklos Szeredi 	fuse_copy_finish(cs);
125702c048b9SMiklos Szeredi 
125802c048b9SMiklos Szeredi 	if (err)
125902c048b9SMiklos Szeredi 		return err;
126002c048b9SMiklos Szeredi 
126102c048b9SMiklos Szeredi 	return ih.len;
126202c048b9SMiklos Szeredi }
126302c048b9SMiklos Szeredi 
1264fd22d62eSMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq,
1265fd22d62eSMiklos Szeredi 			    struct fuse_copy_state *cs,
126602c048b9SMiklos Szeredi 			    size_t nbytes)
1267fd22d62eSMiklos Szeredi __releases(fiq->waitq.lock)
126802c048b9SMiklos Szeredi {
1269f88996a9SMiklos Szeredi 	if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL)
1270fd22d62eSMiklos Szeredi 		return fuse_read_single_forget(fiq, cs, nbytes);
127102c048b9SMiklos Szeredi 	else
1272fd22d62eSMiklos Szeredi 		return fuse_read_batch_forget(fiq, cs, nbytes);
127302c048b9SMiklos Szeredi }
127402c048b9SMiklos Szeredi 
1275a4d27e75SMiklos Szeredi /*
1276334f485dSMiklos Szeredi  * Read a single request into the userspace filesystem's buffer.  This
1277334f485dSMiklos Szeredi  * function waits until a request is available, then removes it from
1278334f485dSMiklos Szeredi  * the pending list and copies request data to userspace buffer.  If
1279f9a2842eSMiklos Szeredi  * no reply is needed (FORGET) or request has been aborted or there
1280f9a2842eSMiklos Szeredi  * was an error during the copying then it's finished by calling
1281334f485dSMiklos Szeredi  * request_end().  Otherwise add it to the processing list, and set
1282334f485dSMiklos Szeredi  * the 'sent' flag.
1283334f485dSMiklos Szeredi  */
1284c3696046SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
1285c3021629SMiklos Szeredi 				struct fuse_copy_state *cs, size_t nbytes)
1286334f485dSMiklos Szeredi {
128782cbdcd3SMiklos Szeredi 	ssize_t err;
1288c3696046SMiklos Szeredi 	struct fuse_conn *fc = fud->fc;
1289f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
1290c3696046SMiklos Szeredi 	struct fuse_pqueue *fpq = &fud->pq;
1291334f485dSMiklos Szeredi 	struct fuse_req *req;
1292334f485dSMiklos Szeredi 	struct fuse_in *in;
1293334f485dSMiklos Szeredi 	unsigned reqsize;
1294be2ff42cSKirill Tkhai 	unsigned int hash;
1295334f485dSMiklos Szeredi 
12961d3d752bSMiklos Szeredi  restart:
12974ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
1298e5ac1d1eSJeff Dike 	err = -EAGAIN;
1299e16714d8SMiklos Szeredi 	if ((file->f_flags & O_NONBLOCK) && fiq->connected &&
1300f88996a9SMiklos Szeredi 	    !request_pending(fiq))
1301e5ac1d1eSJeff Dike 		goto err_unlock;
1302e5ac1d1eSJeff Dike 
13035250921bSMiklos Szeredi 	err = wait_event_interruptible_exclusive_locked(fiq->waitq,
13045250921bSMiklos Szeredi 				!fiq->connected || request_pending(fiq));
13055250921bSMiklos Szeredi 	if (err)
13065250921bSMiklos Szeredi 		goto err_unlock;
13075250921bSMiklos Szeredi 
13083b7008b2SSzymon Lukasz 	if (!fiq->connected) {
13093b7008b2SSzymon Lukasz 		err = (fc->aborted && fc->abort_err) ? -ECONNABORTED : -ENODEV;
1310334f485dSMiklos Szeredi 		goto err_unlock;
13113b7008b2SSzymon Lukasz 	}
1312334f485dSMiklos Szeredi 
1313f88996a9SMiklos Szeredi 	if (!list_empty(&fiq->interrupts)) {
1314f88996a9SMiklos Szeredi 		req = list_entry(fiq->interrupts.next, struct fuse_req,
1315a4d27e75SMiklos Szeredi 				 intr_entry);
1316fd22d62eSMiklos Szeredi 		return fuse_read_interrupt(fiq, cs, nbytes, req);
1317a4d27e75SMiklos Szeredi 	}
1318a4d27e75SMiklos Szeredi 
1319f88996a9SMiklos Szeredi 	if (forget_pending(fiq)) {
1320f88996a9SMiklos Szeredi 		if (list_empty(&fiq->pending) || fiq->forget_batch-- > 0)
1321fd22d62eSMiklos Szeredi 			return fuse_read_forget(fc, fiq, cs, nbytes);
132207e77dcaSMiklos Szeredi 
1323f88996a9SMiklos Szeredi 		if (fiq->forget_batch <= -8)
1324f88996a9SMiklos Szeredi 			fiq->forget_batch = 16;
132507e77dcaSMiklos Szeredi 	}
132607e77dcaSMiklos Szeredi 
1327f88996a9SMiklos Szeredi 	req = list_entry(fiq->pending.next, struct fuse_req, list);
132833e14b4dSMiklos Szeredi 	clear_bit(FR_PENDING, &req->flags);
1329ef759258SMiklos Szeredi 	list_del_init(&req->list);
13304ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
13314ce60812SMiklos Szeredi 
1332334f485dSMiklos Szeredi 	in = &req->in;
13331d3d752bSMiklos Szeredi 	reqsize = in->h.len;
13345d6d3a30SMiklos Szeredi 
13351d3d752bSMiklos Szeredi 	/* If request is too large, reply with an error and restart the read */
1336c3021629SMiklos Szeredi 	if (nbytes < reqsize) {
13371d3d752bSMiklos Szeredi 		req->out.h.error = -EIO;
13381d3d752bSMiklos Szeredi 		/* SETXATTR is special, since it may contain too large data */
13391d3d752bSMiklos Szeredi 		if (in->h.opcode == FUSE_SETXATTR)
13401d3d752bSMiklos Szeredi 			req->out.h.error = -E2BIG;
13411d3d752bSMiklos Szeredi 		request_end(fc, req);
13421d3d752bSMiklos Szeredi 		goto restart;
13431d3d752bSMiklos Szeredi 	}
134445a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
134582cbdcd3SMiklos Szeredi 	list_add(&req->list, &fpq->io);
134645a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1347c3021629SMiklos Szeredi 	cs->req = req;
1348c3021629SMiklos Szeredi 	err = fuse_copy_one(cs, &in->h, sizeof(in->h));
1349334f485dSMiklos Szeredi 	if (!err)
1350c3021629SMiklos Szeredi 		err = fuse_copy_args(cs, in->numargs, in->argpages,
1351334f485dSMiklos Szeredi 				     (struct fuse_arg *) in->args, 0);
1352c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
135345a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1354825d6d33SMiklos Szeredi 	clear_bit(FR_LOCKED, &req->flags);
1355e96edd94SMiklos Szeredi 	if (!fpq->connected) {
13563b7008b2SSzymon Lukasz 		err = (fc->aborted && fc->abort_err) ? -ECONNABORTED : -ENODEV;
135782cbdcd3SMiklos Szeredi 		goto out_end;
1358c9c9d7dfSMiklos Szeredi 	}
1359334f485dSMiklos Szeredi 	if (err) {
1360334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
136182cbdcd3SMiklos Szeredi 		goto out_end;
1362334f485dSMiklos Szeredi 	}
1363825d6d33SMiklos Szeredi 	if (!test_bit(FR_ISREPLY, &req->flags)) {
136482cbdcd3SMiklos Szeredi 		err = reqsize;
136582cbdcd3SMiklos Szeredi 		goto out_end;
136682cbdcd3SMiklos Szeredi 	}
1367be2ff42cSKirill Tkhai 	hash = fuse_req_hash(req->in.h.unique);
1368be2ff42cSKirill Tkhai 	list_move_tail(&req->list, &fpq->processing[hash]);
1369bc78abbdSKirill Tkhai 	__fuse_get_request(req);
13708f7bb368SMiklos Szeredi 	set_bit(FR_SENT, &req->flags);
13714c316f2fSMiklos Szeredi 	spin_unlock(&fpq->lock);
13728f7bb368SMiklos Szeredi 	/* matches barrier in request_wait_answer() */
13738f7bb368SMiklos Szeredi 	smp_mb__after_atomic();
1374825d6d33SMiklos Szeredi 	if (test_bit(FR_INTERRUPTED, &req->flags))
1375f88996a9SMiklos Szeredi 		queue_interrupt(fiq, req);
1376bc78abbdSKirill Tkhai 	fuse_put_request(fc, req);
137782cbdcd3SMiklos Szeredi 
1378334f485dSMiklos Szeredi 	return reqsize;
1379334f485dSMiklos Szeredi 
138082cbdcd3SMiklos Szeredi out_end:
138177cd9d48SMiklos Szeredi 	if (!test_bit(FR_PRIVATE, &req->flags))
138282cbdcd3SMiklos Szeredi 		list_del_init(&req->list);
138345a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
138482cbdcd3SMiklos Szeredi 	request_end(fc, req);
138582cbdcd3SMiklos Szeredi 	return err;
138682cbdcd3SMiklos Szeredi 
1387334f485dSMiklos Szeredi  err_unlock:
13884ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
1389334f485dSMiklos Szeredi 	return err;
1390334f485dSMiklos Szeredi }
1391334f485dSMiklos Szeredi 
139294e4fe2cSTom Van Braeckel static int fuse_dev_open(struct inode *inode, struct file *file)
139394e4fe2cSTom Van Braeckel {
139494e4fe2cSTom Van Braeckel 	/*
139594e4fe2cSTom Van Braeckel 	 * The fuse device's file's private_data is used to hold
139694e4fe2cSTom Van Braeckel 	 * the fuse_conn(ection) when it is mounted, and is used to
139794e4fe2cSTom Van Braeckel 	 * keep track of whether the file has been mounted already.
139894e4fe2cSTom Van Braeckel 	 */
139994e4fe2cSTom Van Braeckel 	file->private_data = NULL;
140094e4fe2cSTom Van Braeckel 	return 0;
140194e4fe2cSTom Van Braeckel }
140294e4fe2cSTom Van Braeckel 
1403fbdbaccaSAl Viro static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to)
1404c3021629SMiklos Szeredi {
1405c3021629SMiklos Szeredi 	struct fuse_copy_state cs;
1406c3021629SMiklos Szeredi 	struct file *file = iocb->ki_filp;
1407cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
1408cc080e9eSMiklos Szeredi 
1409cc080e9eSMiklos Szeredi 	if (!fud)
1410c3021629SMiklos Szeredi 		return -EPERM;
1411c3021629SMiklos Szeredi 
1412fbdbaccaSAl Viro 	if (!iter_is_iovec(to))
1413fbdbaccaSAl Viro 		return -EINVAL;
1414c3021629SMiklos Szeredi 
1415dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 1, to);
1416fbdbaccaSAl Viro 
1417c3696046SMiklos Szeredi 	return fuse_dev_do_read(fud, file, &cs, iov_iter_count(to));
1418c3021629SMiklos Szeredi }
1419c3021629SMiklos Szeredi 
1420c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
1421c3021629SMiklos Szeredi 				    struct pipe_inode_info *pipe,
1422c3021629SMiklos Szeredi 				    size_t len, unsigned int flags)
1423c3021629SMiklos Szeredi {
1424d82718e3SAl Viro 	int total, ret;
1425c3021629SMiklos Szeredi 	int page_nr = 0;
1426c3021629SMiklos Szeredi 	struct pipe_buffer *bufs;
1427c3021629SMiklos Szeredi 	struct fuse_copy_state cs;
1428cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(in);
1429cc080e9eSMiklos Szeredi 
1430cc080e9eSMiklos Szeredi 	if (!fud)
1431c3021629SMiklos Szeredi 		return -EPERM;
1432c3021629SMiklos Szeredi 
1433d6d931adSAndrey Ryabinin 	bufs = kvmalloc_array(pipe->buffers, sizeof(struct pipe_buffer),
14346da2ec56SKees Cook 			      GFP_KERNEL);
1435c3021629SMiklos Szeredi 	if (!bufs)
1436c3021629SMiklos Szeredi 		return -ENOMEM;
1437c3021629SMiklos Szeredi 
1438dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 1, NULL);
1439c3021629SMiklos Szeredi 	cs.pipebufs = bufs;
1440c3021629SMiklos Szeredi 	cs.pipe = pipe;
1441c3696046SMiklos Szeredi 	ret = fuse_dev_do_read(fud, in, &cs, len);
1442c3021629SMiklos Szeredi 	if (ret < 0)
1443c3021629SMiklos Szeredi 		goto out;
1444c3021629SMiklos Szeredi 
1445c3021629SMiklos Szeredi 	if (pipe->nrbufs + cs.nr_segs > pipe->buffers) {
1446c3021629SMiklos Szeredi 		ret = -EIO;
1447d82718e3SAl Viro 		goto out;
1448c3021629SMiklos Szeredi 	}
1449c3021629SMiklos Szeredi 
1450d82718e3SAl Viro 	for (ret = total = 0; page_nr < cs.nr_segs; total += ret) {
145128a625cbSMiklos Szeredi 		/*
145228a625cbSMiklos Szeredi 		 * Need to be careful about this.  Having buf->ops in module
145328a625cbSMiklos Szeredi 		 * code can Oops if the buffer persists after module unload.
145428a625cbSMiklos Szeredi 		 */
1455d82718e3SAl Viro 		bufs[page_nr].ops = &nosteal_pipe_buf_ops;
145684588a93SMiklos Szeredi 		bufs[page_nr].flags = 0;
1457d82718e3SAl Viro 		ret = add_to_pipe(pipe, &bufs[page_nr++]);
1458d82718e3SAl Viro 		if (unlikely(ret < 0))
1459d82718e3SAl Viro 			break;
1460c3021629SMiklos Szeredi 	}
1461d82718e3SAl Viro 	if (total)
1462d82718e3SAl Viro 		ret = total;
1463c3021629SMiklos Szeredi out:
1464c3021629SMiklos Szeredi 	for (; page_nr < cs.nr_segs; page_nr++)
146509cbfeafSKirill A. Shutemov 		put_page(bufs[page_nr].page);
1466c3021629SMiklos Szeredi 
1467d6d931adSAndrey Ryabinin 	kvfree(bufs);
1468c3021629SMiklos Szeredi 	return ret;
1469c3021629SMiklos Szeredi }
1470c3021629SMiklos Szeredi 
147195668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size,
147295668a69STejun Heo 			    struct fuse_copy_state *cs)
147395668a69STejun Heo {
147495668a69STejun Heo 	struct fuse_notify_poll_wakeup_out outarg;
1475f6d47a17SMiklos Szeredi 	int err = -EINVAL;
147695668a69STejun Heo 
147795668a69STejun Heo 	if (size != sizeof(outarg))
1478f6d47a17SMiklos Szeredi 		goto err;
147995668a69STejun Heo 
148095668a69STejun Heo 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
148195668a69STejun Heo 	if (err)
1482f6d47a17SMiklos Szeredi 		goto err;
148395668a69STejun Heo 
1484f6d47a17SMiklos Szeredi 	fuse_copy_finish(cs);
148595668a69STejun Heo 	return fuse_notify_poll_wakeup(fc, &outarg);
1486f6d47a17SMiklos Szeredi 
1487f6d47a17SMiklos Szeredi err:
1488f6d47a17SMiklos Szeredi 	fuse_copy_finish(cs);
1489f6d47a17SMiklos Szeredi 	return err;
149095668a69STejun Heo }
149195668a69STejun Heo 
14923b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size,
14933b463ae0SJohn Muir 				   struct fuse_copy_state *cs)
14943b463ae0SJohn Muir {
14953b463ae0SJohn Muir 	struct fuse_notify_inval_inode_out outarg;
14963b463ae0SJohn Muir 	int err = -EINVAL;
14973b463ae0SJohn Muir 
14983b463ae0SJohn Muir 	if (size != sizeof(outarg))
14993b463ae0SJohn Muir 		goto err;
15003b463ae0SJohn Muir 
15013b463ae0SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
15023b463ae0SJohn Muir 	if (err)
15033b463ae0SJohn Muir 		goto err;
15043b463ae0SJohn Muir 	fuse_copy_finish(cs);
15053b463ae0SJohn Muir 
15063b463ae0SJohn Muir 	down_read(&fc->killsb);
15073b463ae0SJohn Muir 	err = -ENOENT;
1508b21dda43SMiklos Szeredi 	if (fc->sb) {
15093b463ae0SJohn Muir 		err = fuse_reverse_inval_inode(fc->sb, outarg.ino,
15103b463ae0SJohn Muir 					       outarg.off, outarg.len);
1511b21dda43SMiklos Szeredi 	}
15123b463ae0SJohn Muir 	up_read(&fc->killsb);
15133b463ae0SJohn Muir 	return err;
15143b463ae0SJohn Muir 
15153b463ae0SJohn Muir err:
15163b463ae0SJohn Muir 	fuse_copy_finish(cs);
15173b463ae0SJohn Muir 	return err;
15183b463ae0SJohn Muir }
15193b463ae0SJohn Muir 
15203b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size,
15213b463ae0SJohn Muir 				   struct fuse_copy_state *cs)
15223b463ae0SJohn Muir {
15233b463ae0SJohn Muir 	struct fuse_notify_inval_entry_out outarg;
1524b2d82ee3SFang Wenqi 	int err = -ENOMEM;
1525b2d82ee3SFang Wenqi 	char *buf;
15263b463ae0SJohn Muir 	struct qstr name;
15273b463ae0SJohn Muir 
1528b2d82ee3SFang Wenqi 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
1529b2d82ee3SFang Wenqi 	if (!buf)
1530b2d82ee3SFang Wenqi 		goto err;
1531b2d82ee3SFang Wenqi 
1532b2d82ee3SFang Wenqi 	err = -EINVAL;
15333b463ae0SJohn Muir 	if (size < sizeof(outarg))
15343b463ae0SJohn Muir 		goto err;
15353b463ae0SJohn Muir 
15363b463ae0SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
15373b463ae0SJohn Muir 	if (err)
15383b463ae0SJohn Muir 		goto err;
15393b463ae0SJohn Muir 
15403b463ae0SJohn Muir 	err = -ENAMETOOLONG;
15413b463ae0SJohn Muir 	if (outarg.namelen > FUSE_NAME_MAX)
15423b463ae0SJohn Muir 		goto err;
15433b463ae0SJohn Muir 
1544c2183d1eSMiklos Szeredi 	err = -EINVAL;
1545c2183d1eSMiklos Szeredi 	if (size != sizeof(outarg) + outarg.namelen + 1)
1546c2183d1eSMiklos Szeredi 		goto err;
1547c2183d1eSMiklos Szeredi 
15483b463ae0SJohn Muir 	name.name = buf;
15493b463ae0SJohn Muir 	name.len = outarg.namelen;
15503b463ae0SJohn Muir 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
15513b463ae0SJohn Muir 	if (err)
15523b463ae0SJohn Muir 		goto err;
15533b463ae0SJohn Muir 	fuse_copy_finish(cs);
15543b463ae0SJohn Muir 	buf[outarg.namelen] = 0;
15553b463ae0SJohn Muir 
15563b463ae0SJohn Muir 	down_read(&fc->killsb);
15573b463ae0SJohn Muir 	err = -ENOENT;
1558b21dda43SMiklos Szeredi 	if (fc->sb)
1559451d0f59SJohn Muir 		err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 0, &name);
1560451d0f59SJohn Muir 	up_read(&fc->killsb);
1561451d0f59SJohn Muir 	kfree(buf);
1562451d0f59SJohn Muir 	return err;
1563451d0f59SJohn Muir 
1564451d0f59SJohn Muir err:
1565451d0f59SJohn Muir 	kfree(buf);
1566451d0f59SJohn Muir 	fuse_copy_finish(cs);
1567451d0f59SJohn Muir 	return err;
1568451d0f59SJohn Muir }
1569451d0f59SJohn Muir 
1570451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size,
1571451d0f59SJohn Muir 			      struct fuse_copy_state *cs)
1572451d0f59SJohn Muir {
1573451d0f59SJohn Muir 	struct fuse_notify_delete_out outarg;
1574451d0f59SJohn Muir 	int err = -ENOMEM;
1575451d0f59SJohn Muir 	char *buf;
1576451d0f59SJohn Muir 	struct qstr name;
1577451d0f59SJohn Muir 
1578451d0f59SJohn Muir 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
1579451d0f59SJohn Muir 	if (!buf)
1580451d0f59SJohn Muir 		goto err;
1581451d0f59SJohn Muir 
1582451d0f59SJohn Muir 	err = -EINVAL;
1583451d0f59SJohn Muir 	if (size < sizeof(outarg))
1584451d0f59SJohn Muir 		goto err;
1585451d0f59SJohn Muir 
1586451d0f59SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
1587451d0f59SJohn Muir 	if (err)
1588451d0f59SJohn Muir 		goto err;
1589451d0f59SJohn Muir 
1590451d0f59SJohn Muir 	err = -ENAMETOOLONG;
1591451d0f59SJohn Muir 	if (outarg.namelen > FUSE_NAME_MAX)
1592451d0f59SJohn Muir 		goto err;
1593451d0f59SJohn Muir 
1594451d0f59SJohn Muir 	err = -EINVAL;
1595451d0f59SJohn Muir 	if (size != sizeof(outarg) + outarg.namelen + 1)
1596451d0f59SJohn Muir 		goto err;
1597451d0f59SJohn Muir 
1598451d0f59SJohn Muir 	name.name = buf;
1599451d0f59SJohn Muir 	name.len = outarg.namelen;
1600451d0f59SJohn Muir 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
1601451d0f59SJohn Muir 	if (err)
1602451d0f59SJohn Muir 		goto err;
1603451d0f59SJohn Muir 	fuse_copy_finish(cs);
1604451d0f59SJohn Muir 	buf[outarg.namelen] = 0;
1605451d0f59SJohn Muir 
1606451d0f59SJohn Muir 	down_read(&fc->killsb);
1607451d0f59SJohn Muir 	err = -ENOENT;
1608451d0f59SJohn Muir 	if (fc->sb)
1609451d0f59SJohn Muir 		err = fuse_reverse_inval_entry(fc->sb, outarg.parent,
1610451d0f59SJohn Muir 					       outarg.child, &name);
16113b463ae0SJohn Muir 	up_read(&fc->killsb);
1612b2d82ee3SFang Wenqi 	kfree(buf);
16133b463ae0SJohn Muir 	return err;
16143b463ae0SJohn Muir 
16153b463ae0SJohn Muir err:
1616b2d82ee3SFang Wenqi 	kfree(buf);
16173b463ae0SJohn Muir 	fuse_copy_finish(cs);
16183b463ae0SJohn Muir 	return err;
16193b463ae0SJohn Muir }
16203b463ae0SJohn Muir 
1621a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
1622a1d75f25SMiklos Szeredi 			     struct fuse_copy_state *cs)
1623a1d75f25SMiklos Szeredi {
1624a1d75f25SMiklos Szeredi 	struct fuse_notify_store_out outarg;
1625a1d75f25SMiklos Szeredi 	struct inode *inode;
1626a1d75f25SMiklos Szeredi 	struct address_space *mapping;
1627a1d75f25SMiklos Szeredi 	u64 nodeid;
1628a1d75f25SMiklos Szeredi 	int err;
1629a1d75f25SMiklos Szeredi 	pgoff_t index;
1630a1d75f25SMiklos Szeredi 	unsigned int offset;
1631a1d75f25SMiklos Szeredi 	unsigned int num;
1632a1d75f25SMiklos Szeredi 	loff_t file_size;
1633a1d75f25SMiklos Szeredi 	loff_t end;
1634a1d75f25SMiklos Szeredi 
1635a1d75f25SMiklos Szeredi 	err = -EINVAL;
1636a1d75f25SMiklos Szeredi 	if (size < sizeof(outarg))
1637a1d75f25SMiklos Szeredi 		goto out_finish;
1638a1d75f25SMiklos Szeredi 
1639a1d75f25SMiklos Szeredi 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
1640a1d75f25SMiklos Szeredi 	if (err)
1641a1d75f25SMiklos Szeredi 		goto out_finish;
1642a1d75f25SMiklos Szeredi 
1643a1d75f25SMiklos Szeredi 	err = -EINVAL;
1644a1d75f25SMiklos Szeredi 	if (size - sizeof(outarg) != outarg.size)
1645a1d75f25SMiklos Szeredi 		goto out_finish;
1646a1d75f25SMiklos Szeredi 
1647a1d75f25SMiklos Szeredi 	nodeid = outarg.nodeid;
1648a1d75f25SMiklos Szeredi 
1649a1d75f25SMiklos Szeredi 	down_read(&fc->killsb);
1650a1d75f25SMiklos Szeredi 
1651a1d75f25SMiklos Szeredi 	err = -ENOENT;
1652a1d75f25SMiklos Szeredi 	if (!fc->sb)
1653a1d75f25SMiklos Szeredi 		goto out_up_killsb;
1654a1d75f25SMiklos Szeredi 
1655a1d75f25SMiklos Szeredi 	inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
1656a1d75f25SMiklos Szeredi 	if (!inode)
1657a1d75f25SMiklos Szeredi 		goto out_up_killsb;
1658a1d75f25SMiklos Szeredi 
1659a1d75f25SMiklos Szeredi 	mapping = inode->i_mapping;
166009cbfeafSKirill A. Shutemov 	index = outarg.offset >> PAGE_SHIFT;
166109cbfeafSKirill A. Shutemov 	offset = outarg.offset & ~PAGE_MASK;
1662a1d75f25SMiklos Szeredi 	file_size = i_size_read(inode);
1663a1d75f25SMiklos Szeredi 	end = outarg.offset + outarg.size;
1664a1d75f25SMiklos Szeredi 	if (end > file_size) {
1665a1d75f25SMiklos Szeredi 		file_size = end;
1666a1d75f25SMiklos Szeredi 		fuse_write_update_size(inode, file_size);
1667a1d75f25SMiklos Szeredi 	}
1668a1d75f25SMiklos Szeredi 
1669a1d75f25SMiklos Szeredi 	num = outarg.size;
1670a1d75f25SMiklos Szeredi 	while (num) {
1671a1d75f25SMiklos Szeredi 		struct page *page;
1672a1d75f25SMiklos Szeredi 		unsigned int this_num;
1673a1d75f25SMiklos Szeredi 
1674a1d75f25SMiklos Szeredi 		err = -ENOMEM;
1675a1d75f25SMiklos Szeredi 		page = find_or_create_page(mapping, index,
1676a1d75f25SMiklos Szeredi 					   mapping_gfp_mask(mapping));
1677a1d75f25SMiklos Szeredi 		if (!page)
1678a1d75f25SMiklos Szeredi 			goto out_iput;
1679a1d75f25SMiklos Szeredi 
168009cbfeafSKirill A. Shutemov 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
1681a1d75f25SMiklos Szeredi 		err = fuse_copy_page(cs, &page, offset, this_num, 0);
1682063ec1e5SMiklos Szeredi 		if (!err && offset == 0 &&
168309cbfeafSKirill A. Shutemov 		    (this_num == PAGE_SIZE || file_size == end))
1684a1d75f25SMiklos Szeredi 			SetPageUptodate(page);
1685a1d75f25SMiklos Szeredi 		unlock_page(page);
168609cbfeafSKirill A. Shutemov 		put_page(page);
1687a1d75f25SMiklos Szeredi 
1688a1d75f25SMiklos Szeredi 		if (err)
1689a1d75f25SMiklos Szeredi 			goto out_iput;
1690a1d75f25SMiklos Szeredi 
1691a1d75f25SMiklos Szeredi 		num -= this_num;
1692a1d75f25SMiklos Szeredi 		offset = 0;
1693a1d75f25SMiklos Szeredi 		index++;
1694a1d75f25SMiklos Szeredi 	}
1695a1d75f25SMiklos Szeredi 
1696a1d75f25SMiklos Szeredi 	err = 0;
1697a1d75f25SMiklos Szeredi 
1698a1d75f25SMiklos Szeredi out_iput:
1699a1d75f25SMiklos Szeredi 	iput(inode);
1700a1d75f25SMiklos Szeredi out_up_killsb:
1701a1d75f25SMiklos Szeredi 	up_read(&fc->killsb);
1702a1d75f25SMiklos Szeredi out_finish:
1703a1d75f25SMiklos Szeredi 	fuse_copy_finish(cs);
1704a1d75f25SMiklos Szeredi 	return err;
1705a1d75f25SMiklos Szeredi }
1706a1d75f25SMiklos Szeredi 
17072d45ba38SMiklos Szeredi static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req)
17082d45ba38SMiklos Szeredi {
1709c6f92f9fSMel Gorman 	release_pages(req->pages, req->num_pages);
17102d45ba38SMiklos Szeredi }
17112d45ba38SMiklos Szeredi 
17122d45ba38SMiklos Szeredi static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
17132d45ba38SMiklos Szeredi 			 struct fuse_notify_retrieve_out *outarg)
17142d45ba38SMiklos Szeredi {
17152d45ba38SMiklos Szeredi 	int err;
17162d45ba38SMiklos Szeredi 	struct address_space *mapping = inode->i_mapping;
17172d45ba38SMiklos Szeredi 	struct fuse_req *req;
17182d45ba38SMiklos Szeredi 	pgoff_t index;
17192d45ba38SMiklos Szeredi 	loff_t file_size;
17202d45ba38SMiklos Szeredi 	unsigned int num;
17212d45ba38SMiklos Szeredi 	unsigned int offset;
17220157443cSGeert Uytterhoeven 	size_t total_len = 0;
17235da784ccSConstantine Shulyupin 	unsigned int num_pages;
17242d45ba38SMiklos Szeredi 
172509cbfeafSKirill A. Shutemov 	offset = outarg->offset & ~PAGE_MASK;
17264d53dc99SMaxim Patlasov 	file_size = i_size_read(inode);
17274d53dc99SMaxim Patlasov 
17284d53dc99SMaxim Patlasov 	num = outarg->size;
17294d53dc99SMaxim Patlasov 	if (outarg->offset > file_size)
17304d53dc99SMaxim Patlasov 		num = 0;
17314d53dc99SMaxim Patlasov 	else if (outarg->offset + num > file_size)
17324d53dc99SMaxim Patlasov 		num = file_size - outarg->offset;
17334d53dc99SMaxim Patlasov 
17344d53dc99SMaxim Patlasov 	num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
17355da784ccSConstantine Shulyupin 	num_pages = min(num_pages, fc->max_pages);
17364d53dc99SMaxim Patlasov 
17374d53dc99SMaxim Patlasov 	req = fuse_get_req(fc, num_pages);
17384d53dc99SMaxim Patlasov 	if (IS_ERR(req))
17394d53dc99SMaxim Patlasov 		return PTR_ERR(req);
17402d45ba38SMiklos Szeredi 
17412d45ba38SMiklos Szeredi 	req->in.h.opcode = FUSE_NOTIFY_REPLY;
17422d45ba38SMiklos Szeredi 	req->in.h.nodeid = outarg->nodeid;
17432d45ba38SMiklos Szeredi 	req->in.numargs = 2;
17442d45ba38SMiklos Szeredi 	req->in.argpages = 1;
17452d45ba38SMiklos Szeredi 	req->end = fuse_retrieve_end;
17462d45ba38SMiklos Szeredi 
174709cbfeafSKirill A. Shutemov 	index = outarg->offset >> PAGE_SHIFT;
17482d45ba38SMiklos Szeredi 
17494d53dc99SMaxim Patlasov 	while (num && req->num_pages < num_pages) {
17502d45ba38SMiklos Szeredi 		struct page *page;
17512d45ba38SMiklos Szeredi 		unsigned int this_num;
17522d45ba38SMiklos Szeredi 
17532d45ba38SMiklos Szeredi 		page = find_get_page(mapping, index);
17542d45ba38SMiklos Szeredi 		if (!page)
17552d45ba38SMiklos Szeredi 			break;
17562d45ba38SMiklos Szeredi 
175709cbfeafSKirill A. Shutemov 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
17582d45ba38SMiklos Szeredi 		req->pages[req->num_pages] = page;
175997e1532eSMiklos Szeredi 		req->page_descs[req->num_pages].offset = offset;
176085f40aecSMaxim Patlasov 		req->page_descs[req->num_pages].length = this_num;
17612d45ba38SMiklos Szeredi 		req->num_pages++;
17622d45ba38SMiklos Szeredi 
1763c9e67d48SMiklos Szeredi 		offset = 0;
17642d45ba38SMiklos Szeredi 		num -= this_num;
17652d45ba38SMiklos Szeredi 		total_len += this_num;
176648706d0aSMiklos Szeredi 		index++;
17672d45ba38SMiklos Szeredi 	}
17682d45ba38SMiklos Szeredi 	req->misc.retrieve_in.offset = outarg->offset;
17692d45ba38SMiklos Szeredi 	req->misc.retrieve_in.size = total_len;
17702d45ba38SMiklos Szeredi 	req->in.args[0].size = sizeof(req->misc.retrieve_in);
17712d45ba38SMiklos Szeredi 	req->in.args[0].value = &req->misc.retrieve_in;
17722d45ba38SMiklos Szeredi 	req->in.args[1].size = total_len;
17732d45ba38SMiklos Szeredi 
17742d45ba38SMiklos Szeredi 	err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique);
17757fabaf30SMiklos Szeredi 	if (err) {
17762d45ba38SMiklos Szeredi 		fuse_retrieve_end(fc, req);
17777fabaf30SMiklos Szeredi 		fuse_put_request(fc, req);
17787fabaf30SMiklos Szeredi 	}
17792d45ba38SMiklos Szeredi 
17802d45ba38SMiklos Szeredi 	return err;
17812d45ba38SMiklos Szeredi }
17822d45ba38SMiklos Szeredi 
17832d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size,
17842d45ba38SMiklos Szeredi 				struct fuse_copy_state *cs)
17852d45ba38SMiklos Szeredi {
17862d45ba38SMiklos Szeredi 	struct fuse_notify_retrieve_out outarg;
17872d45ba38SMiklos Szeredi 	struct inode *inode;
17882d45ba38SMiklos Szeredi 	int err;
17892d45ba38SMiklos Szeredi 
17902d45ba38SMiklos Szeredi 	err = -EINVAL;
17912d45ba38SMiklos Szeredi 	if (size != sizeof(outarg))
17922d45ba38SMiklos Szeredi 		goto copy_finish;
17932d45ba38SMiklos Szeredi 
17942d45ba38SMiklos Szeredi 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
17952d45ba38SMiklos Szeredi 	if (err)
17962d45ba38SMiklos Szeredi 		goto copy_finish;
17972d45ba38SMiklos Szeredi 
17982d45ba38SMiklos Szeredi 	fuse_copy_finish(cs);
17992d45ba38SMiklos Szeredi 
18002d45ba38SMiklos Szeredi 	down_read(&fc->killsb);
18012d45ba38SMiklos Szeredi 	err = -ENOENT;
18022d45ba38SMiklos Szeredi 	if (fc->sb) {
18032d45ba38SMiklos Szeredi 		u64 nodeid = outarg.nodeid;
18042d45ba38SMiklos Szeredi 
18052d45ba38SMiklos Szeredi 		inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
18062d45ba38SMiklos Szeredi 		if (inode) {
18072d45ba38SMiklos Szeredi 			err = fuse_retrieve(fc, inode, &outarg);
18082d45ba38SMiklos Szeredi 			iput(inode);
18092d45ba38SMiklos Szeredi 		}
18102d45ba38SMiklos Szeredi 	}
18112d45ba38SMiklos Szeredi 	up_read(&fc->killsb);
18122d45ba38SMiklos Szeredi 
18132d45ba38SMiklos Szeredi 	return err;
18142d45ba38SMiklos Szeredi 
18152d45ba38SMiklos Szeredi copy_finish:
18162d45ba38SMiklos Szeredi 	fuse_copy_finish(cs);
18172d45ba38SMiklos Szeredi 	return err;
18182d45ba38SMiklos Szeredi }
18192d45ba38SMiklos Szeredi 
18208599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
18218599396bSTejun Heo 		       unsigned int size, struct fuse_copy_state *cs)
18228599396bSTejun Heo {
18230d278362SMiklos Szeredi 	/* Don't try to move pages (yet) */
18240d278362SMiklos Szeredi 	cs->move_pages = 0;
18250d278362SMiklos Szeredi 
18268599396bSTejun Heo 	switch (code) {
182795668a69STejun Heo 	case FUSE_NOTIFY_POLL:
182895668a69STejun Heo 		return fuse_notify_poll(fc, size, cs);
182995668a69STejun Heo 
18303b463ae0SJohn Muir 	case FUSE_NOTIFY_INVAL_INODE:
18313b463ae0SJohn Muir 		return fuse_notify_inval_inode(fc, size, cs);
18323b463ae0SJohn Muir 
18333b463ae0SJohn Muir 	case FUSE_NOTIFY_INVAL_ENTRY:
18343b463ae0SJohn Muir 		return fuse_notify_inval_entry(fc, size, cs);
18353b463ae0SJohn Muir 
1836a1d75f25SMiklos Szeredi 	case FUSE_NOTIFY_STORE:
1837a1d75f25SMiklos Szeredi 		return fuse_notify_store(fc, size, cs);
1838a1d75f25SMiklos Szeredi 
18392d45ba38SMiklos Szeredi 	case FUSE_NOTIFY_RETRIEVE:
18402d45ba38SMiklos Szeredi 		return fuse_notify_retrieve(fc, size, cs);
18412d45ba38SMiklos Szeredi 
1842451d0f59SJohn Muir 	case FUSE_NOTIFY_DELETE:
1843451d0f59SJohn Muir 		return fuse_notify_delete(fc, size, cs);
1844451d0f59SJohn Muir 
18458599396bSTejun Heo 	default:
1846f6d47a17SMiklos Szeredi 		fuse_copy_finish(cs);
18478599396bSTejun Heo 		return -EINVAL;
18488599396bSTejun Heo 	}
18498599396bSTejun Heo }
18508599396bSTejun Heo 
1851334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */
18523a2b5b9cSMiklos Szeredi static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique)
1853334f485dSMiklos Szeredi {
1854be2ff42cSKirill Tkhai 	unsigned int hash = fuse_req_hash(unique);
1855334f485dSMiklos Szeredi 	struct fuse_req *req;
185605726acaSDong Fang 
1857be2ff42cSKirill Tkhai 	list_for_each_entry(req, &fpq->processing[hash], list) {
18583a5358d1SKirill Tkhai 		if (req->in.h.unique == unique)
1859334f485dSMiklos Szeredi 			return req;
1860334f485dSMiklos Szeredi 	}
1861334f485dSMiklos Szeredi 	return NULL;
1862334f485dSMiklos Szeredi }
1863334f485dSMiklos Szeredi 
1864334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
1865334f485dSMiklos Szeredi 			 unsigned nbytes)
1866334f485dSMiklos Szeredi {
1867334f485dSMiklos Szeredi 	unsigned reqsize = sizeof(struct fuse_out_header);
1868334f485dSMiklos Szeredi 
1869334f485dSMiklos Szeredi 	if (out->h.error)
1870334f485dSMiklos Szeredi 		return nbytes != reqsize ? -EINVAL : 0;
1871334f485dSMiklos Szeredi 
1872334f485dSMiklos Szeredi 	reqsize += len_args(out->numargs, out->args);
1873334f485dSMiklos Szeredi 
1874334f485dSMiklos Szeredi 	if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))
1875334f485dSMiklos Szeredi 		return -EINVAL;
1876334f485dSMiklos Szeredi 	else if (reqsize > nbytes) {
1877334f485dSMiklos Szeredi 		struct fuse_arg *lastarg = &out->args[out->numargs-1];
1878334f485dSMiklos Szeredi 		unsigned diffsize = reqsize - nbytes;
1879334f485dSMiklos Szeredi 		if (diffsize > lastarg->size)
1880334f485dSMiklos Szeredi 			return -EINVAL;
1881334f485dSMiklos Szeredi 		lastarg->size -= diffsize;
1882334f485dSMiklos Szeredi 	}
1883334f485dSMiklos Szeredi 	return fuse_copy_args(cs, out->numargs, out->argpages, out->args,
1884334f485dSMiklos Szeredi 			      out->page_zeroing);
1885334f485dSMiklos Szeredi }
1886334f485dSMiklos Szeredi 
1887334f485dSMiklos Szeredi /*
1888334f485dSMiklos Szeredi  * Write a single reply to a request.  First the header is copied from
1889334f485dSMiklos Szeredi  * the write buffer.  The request is then searched on the processing
1890334f485dSMiklos Szeredi  * list by the unique ID found in the header.  If found, then remove
1891334f485dSMiklos Szeredi  * it from the list and copy the rest of the buffer to the request.
1892334f485dSMiklos Szeredi  * The request is finished by calling request_end()
1893334f485dSMiklos Szeredi  */
1894c3696046SMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
1895dd3bb14fSMiklos Szeredi 				 struct fuse_copy_state *cs, size_t nbytes)
1896334f485dSMiklos Szeredi {
1897334f485dSMiklos Szeredi 	int err;
1898c3696046SMiklos Szeredi 	struct fuse_conn *fc = fud->fc;
1899c3696046SMiklos Szeredi 	struct fuse_pqueue *fpq = &fud->pq;
1900334f485dSMiklos Szeredi 	struct fuse_req *req;
1901334f485dSMiklos Szeredi 	struct fuse_out_header oh;
1902334f485dSMiklos Szeredi 
1903334f485dSMiklos Szeredi 	if (nbytes < sizeof(struct fuse_out_header))
1904334f485dSMiklos Szeredi 		return -EINVAL;
1905334f485dSMiklos Szeredi 
1906dd3bb14fSMiklos Szeredi 	err = fuse_copy_one(cs, &oh, sizeof(oh));
1907334f485dSMiklos Szeredi 	if (err)
1908334f485dSMiklos Szeredi 		goto err_finish;
19098599396bSTejun Heo 
1910334f485dSMiklos Szeredi 	err = -EINVAL;
19118599396bSTejun Heo 	if (oh.len != nbytes)
19128599396bSTejun Heo 		goto err_finish;
19138599396bSTejun Heo 
19148599396bSTejun Heo 	/*
19158599396bSTejun Heo 	 * Zero oh.unique indicates unsolicited notification message
19168599396bSTejun Heo 	 * and error contains notification code.
19178599396bSTejun Heo 	 */
19188599396bSTejun Heo 	if (!oh.unique) {
1919dd3bb14fSMiklos Szeredi 		err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs);
19208599396bSTejun Heo 		return err ? err : nbytes;
19218599396bSTejun Heo 	}
19228599396bSTejun Heo 
19238599396bSTejun Heo 	err = -EINVAL;
19248599396bSTejun Heo 	if (oh.error <= -1000 || oh.error > 0)
1925334f485dSMiklos Szeredi 		goto err_finish;
1926334f485dSMiklos Szeredi 
192745a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
192869a53bf2SMiklos Szeredi 	err = -ENOENT;
1929e96edd94SMiklos Szeredi 	if (!fpq->connected)
193045a91cb1SMiklos Szeredi 		goto err_unlock_pq;
193169a53bf2SMiklos Szeredi 
19323a5358d1SKirill Tkhai 	req = request_find(fpq, oh.unique & ~FUSE_INT_REQ_BIT);
1933334f485dSMiklos Szeredi 	if (!req)
193445a91cb1SMiklos Szeredi 		goto err_unlock_pq;
1935334f485dSMiklos Szeredi 
19363a5358d1SKirill Tkhai 	/* Is it an interrupt reply ID? */
19373a5358d1SKirill Tkhai 	if (oh.unique & FUSE_INT_REQ_BIT) {
1938d2d2d4fbSKirill Tkhai 		__fuse_get_request(req);
193945a91cb1SMiklos Szeredi 		spin_unlock(&fpq->lock);
194045a91cb1SMiklos Szeredi 
1941a4d27e75SMiklos Szeredi 		err = -EINVAL;
1942d2d2d4fbSKirill Tkhai 		if (nbytes != sizeof(struct fuse_out_header)) {
1943d2d2d4fbSKirill Tkhai 			fuse_put_request(fc, req);
194446c34a34SMiklos Szeredi 			goto err_finish;
1945d2d2d4fbSKirill Tkhai 		}
1946a4d27e75SMiklos Szeredi 
1947a4d27e75SMiklos Szeredi 		if (oh.error == -ENOSYS)
1948a4d27e75SMiklos Szeredi 			fc->no_interrupt = 1;
1949a4d27e75SMiklos Szeredi 		else if (oh.error == -EAGAIN)
1950f88996a9SMiklos Szeredi 			queue_interrupt(&fc->iq, req);
1951d2d2d4fbSKirill Tkhai 		fuse_put_request(fc, req);
1952a4d27e75SMiklos Szeredi 
1953dd3bb14fSMiklos Szeredi 		fuse_copy_finish(cs);
1954a4d27e75SMiklos Szeredi 		return nbytes;
1955a4d27e75SMiklos Szeredi 	}
1956a4d27e75SMiklos Szeredi 
195733e14b4dSMiklos Szeredi 	clear_bit(FR_SENT, &req->flags);
19583a2b5b9cSMiklos Szeredi 	list_move(&req->list, &fpq->io);
1959334f485dSMiklos Szeredi 	req->out.h = oh;
1960825d6d33SMiklos Szeredi 	set_bit(FR_LOCKED, &req->flags);
196145a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1962dd3bb14fSMiklos Szeredi 	cs->req = req;
1963ce534fb0SMiklos Szeredi 	if (!req->out.page_replace)
1964ce534fb0SMiklos Szeredi 		cs->move_pages = 0;
1965334f485dSMiklos Szeredi 
1966dd3bb14fSMiklos Szeredi 	err = copy_out_args(cs, &req->out, nbytes);
1967dd3bb14fSMiklos Szeredi 	fuse_copy_finish(cs);
1968334f485dSMiklos Szeredi 
196945a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1970825d6d33SMiklos Szeredi 	clear_bit(FR_LOCKED, &req->flags);
1971e96edd94SMiklos Szeredi 	if (!fpq->connected)
1972334f485dSMiklos Szeredi 		err = -ENOENT;
19730d8e84b0SMiklos Szeredi 	else if (err)
1974334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
197577cd9d48SMiklos Szeredi 	if (!test_bit(FR_PRIVATE, &req->flags))
1976f377cb79SMiklos Szeredi 		list_del_init(&req->list);
197745a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
197846c34a34SMiklos Szeredi 
1979334f485dSMiklos Szeredi 	request_end(fc, req);
1980334f485dSMiklos Szeredi 
1981334f485dSMiklos Szeredi 	return err ? err : nbytes;
1982334f485dSMiklos Szeredi 
198345a91cb1SMiklos Szeredi  err_unlock_pq:
198445a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1985334f485dSMiklos Szeredi  err_finish:
1986dd3bb14fSMiklos Szeredi 	fuse_copy_finish(cs);
1987334f485dSMiklos Szeredi 	return err;
1988334f485dSMiklos Szeredi }
1989334f485dSMiklos Szeredi 
1990fbdbaccaSAl Viro static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from)
1991dd3bb14fSMiklos Szeredi {
1992dd3bb14fSMiklos Szeredi 	struct fuse_copy_state cs;
1993cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(iocb->ki_filp);
1994cc080e9eSMiklos Szeredi 
1995cc080e9eSMiklos Szeredi 	if (!fud)
1996dd3bb14fSMiklos Szeredi 		return -EPERM;
1997dd3bb14fSMiklos Szeredi 
1998fbdbaccaSAl Viro 	if (!iter_is_iovec(from))
1999fbdbaccaSAl Viro 		return -EINVAL;
2000dd3bb14fSMiklos Szeredi 
2001dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 0, from);
2002fbdbaccaSAl Viro 
2003c3696046SMiklos Szeredi 	return fuse_dev_do_write(fud, &cs, iov_iter_count(from));
2004dd3bb14fSMiklos Szeredi }
2005dd3bb14fSMiklos Szeredi 
2006dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
2007dd3bb14fSMiklos Szeredi 				     struct file *out, loff_t *ppos,
2008dd3bb14fSMiklos Szeredi 				     size_t len, unsigned int flags)
2009dd3bb14fSMiklos Szeredi {
2010dd3bb14fSMiklos Szeredi 	unsigned nbuf;
2011dd3bb14fSMiklos Szeredi 	unsigned idx;
2012dd3bb14fSMiklos Szeredi 	struct pipe_buffer *bufs;
2013dd3bb14fSMiklos Szeredi 	struct fuse_copy_state cs;
2014cc080e9eSMiklos Szeredi 	struct fuse_dev *fud;
2015dd3bb14fSMiklos Szeredi 	size_t rem;
2016dd3bb14fSMiklos Szeredi 	ssize_t ret;
2017dd3bb14fSMiklos Szeredi 
2018cc080e9eSMiklos Szeredi 	fud = fuse_get_dev(out);
2019cc080e9eSMiklos Szeredi 	if (!fud)
2020dd3bb14fSMiklos Szeredi 		return -EPERM;
2021dd3bb14fSMiklos Szeredi 
2022a2477b0eSAndrey Ryabinin 	pipe_lock(pipe);
2023a2477b0eSAndrey Ryabinin 
202496354535SAndrey Ryabinin 	bufs = kvmalloc_array(pipe->nrbufs, sizeof(struct pipe_buffer),
20256da2ec56SKees Cook 			      GFP_KERNEL);
2026a2477b0eSAndrey Ryabinin 	if (!bufs) {
2027a2477b0eSAndrey Ryabinin 		pipe_unlock(pipe);
2028dd3bb14fSMiklos Szeredi 		return -ENOMEM;
2029a2477b0eSAndrey Ryabinin 	}
2030dd3bb14fSMiklos Szeredi 
2031dd3bb14fSMiklos Szeredi 	nbuf = 0;
2032dd3bb14fSMiklos Szeredi 	rem = 0;
2033dd3bb14fSMiklos Szeredi 	for (idx = 0; idx < pipe->nrbufs && rem < len; idx++)
2034dd3bb14fSMiklos Szeredi 		rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len;
2035dd3bb14fSMiklos Szeredi 
2036dd3bb14fSMiklos Szeredi 	ret = -EINVAL;
2037dd3bb14fSMiklos Szeredi 	if (rem < len) {
2038dd3bb14fSMiklos Szeredi 		pipe_unlock(pipe);
2039dd3bb14fSMiklos Szeredi 		goto out;
2040dd3bb14fSMiklos Szeredi 	}
2041dd3bb14fSMiklos Szeredi 
2042dd3bb14fSMiklos Szeredi 	rem = len;
2043dd3bb14fSMiklos Szeredi 	while (rem) {
2044dd3bb14fSMiklos Szeredi 		struct pipe_buffer *ibuf;
2045dd3bb14fSMiklos Szeredi 		struct pipe_buffer *obuf;
2046dd3bb14fSMiklos Szeredi 
2047dd3bb14fSMiklos Szeredi 		BUG_ON(nbuf >= pipe->buffers);
2048dd3bb14fSMiklos Szeredi 		BUG_ON(!pipe->nrbufs);
2049dd3bb14fSMiklos Szeredi 		ibuf = &pipe->bufs[pipe->curbuf];
2050dd3bb14fSMiklos Szeredi 		obuf = &bufs[nbuf];
2051dd3bb14fSMiklos Szeredi 
2052dd3bb14fSMiklos Szeredi 		if (rem >= ibuf->len) {
2053dd3bb14fSMiklos Szeredi 			*obuf = *ibuf;
2054dd3bb14fSMiklos Szeredi 			ibuf->ops = NULL;
2055dd3bb14fSMiklos Szeredi 			pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1);
2056dd3bb14fSMiklos Szeredi 			pipe->nrbufs--;
2057dd3bb14fSMiklos Szeredi 		} else {
20587bf2d1dfSMiklos Szeredi 			pipe_buf_get(pipe, ibuf);
2059dd3bb14fSMiklos Szeredi 			*obuf = *ibuf;
2060dd3bb14fSMiklos Szeredi 			obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
2061dd3bb14fSMiklos Szeredi 			obuf->len = rem;
2062dd3bb14fSMiklos Szeredi 			ibuf->offset += obuf->len;
2063dd3bb14fSMiklos Szeredi 			ibuf->len -= obuf->len;
2064dd3bb14fSMiklos Szeredi 		}
2065dd3bb14fSMiklos Szeredi 		nbuf++;
2066dd3bb14fSMiklos Szeredi 		rem -= obuf->len;
2067dd3bb14fSMiklos Szeredi 	}
2068dd3bb14fSMiklos Szeredi 	pipe_unlock(pipe);
2069dd3bb14fSMiklos Szeredi 
2070dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 0, NULL);
2071dd3bb14fSMiklos Szeredi 	cs.pipebufs = bufs;
20726c09e94aSAl Viro 	cs.nr_segs = nbuf;
2073dd3bb14fSMiklos Szeredi 	cs.pipe = pipe;
2074dd3bb14fSMiklos Szeredi 
2075ce534fb0SMiklos Szeredi 	if (flags & SPLICE_F_MOVE)
2076ce534fb0SMiklos Szeredi 		cs.move_pages = 1;
2077ce534fb0SMiklos Szeredi 
2078c3696046SMiklos Szeredi 	ret = fuse_dev_do_write(fud, &cs, len);
2079dd3bb14fSMiklos Szeredi 
20809509941eSJann Horn 	pipe_lock(pipe);
2081a779638cSMiklos Szeredi 	for (idx = 0; idx < nbuf; idx++)
2082a779638cSMiklos Szeredi 		pipe_buf_release(pipe, &bufs[idx]);
20839509941eSJann Horn 	pipe_unlock(pipe);
2084a779638cSMiklos Szeredi 
2085dd3bb14fSMiklos Szeredi out:
2086d6d931adSAndrey Ryabinin 	kvfree(bufs);
2087dd3bb14fSMiklos Szeredi 	return ret;
2088dd3bb14fSMiklos Szeredi }
2089dd3bb14fSMiklos Szeredi 
2090076ccb76SAl Viro static __poll_t fuse_dev_poll(struct file *file, poll_table *wait)
2091334f485dSMiklos Szeredi {
2092a9a08845SLinus Torvalds 	__poll_t mask = EPOLLOUT | EPOLLWRNORM;
2093f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq;
2094cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2095cc080e9eSMiklos Szeredi 
2096cc080e9eSMiklos Szeredi 	if (!fud)
2097a9a08845SLinus Torvalds 		return EPOLLERR;
2098334f485dSMiklos Szeredi 
2099cc080e9eSMiklos Szeredi 	fiq = &fud->fc->iq;
2100f88996a9SMiklos Szeredi 	poll_wait(file, &fiq->waitq, wait);
2101334f485dSMiklos Szeredi 
21024ce60812SMiklos Szeredi 	spin_lock(&fiq->waitq.lock);
2103e16714d8SMiklos Szeredi 	if (!fiq->connected)
2104a9a08845SLinus Torvalds 		mask = EPOLLERR;
2105f88996a9SMiklos Szeredi 	else if (request_pending(fiq))
2106a9a08845SLinus Torvalds 		mask |= EPOLLIN | EPOLLRDNORM;
21074ce60812SMiklos Szeredi 	spin_unlock(&fiq->waitq.lock);
2108334f485dSMiklos Szeredi 
2109334f485dSMiklos Szeredi 	return mask;
2110334f485dSMiklos Szeredi }
2111334f485dSMiklos Szeredi 
211234061750SKirill Tkhai /* Abort all requests on the given list (pending or processing) */
2113334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head)
2114334f485dSMiklos Szeredi {
2115334f485dSMiklos Szeredi 	while (!list_empty(head)) {
2116334f485dSMiklos Szeredi 		struct fuse_req *req;
2117334f485dSMiklos Szeredi 		req = list_entry(head->next, struct fuse_req, list);
2118334f485dSMiklos Szeredi 		req->out.h.error = -ECONNABORTED;
211933e14b4dSMiklos Szeredi 		clear_bit(FR_SENT, &req->flags);
2120f377cb79SMiklos Szeredi 		list_del_init(&req->list);
2121334f485dSMiklos Szeredi 		request_end(fc, req);
2122334f485dSMiklos Szeredi 	}
2123334f485dSMiklos Szeredi }
2124334f485dSMiklos Szeredi 
2125357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc)
2126357ccf2bSBryan Green {
2127357ccf2bSBryan Green 	struct rb_node *p;
2128357ccf2bSBryan Green 
2129357ccf2bSBryan Green 	p = rb_first(&fc->polled_files);
2130357ccf2bSBryan Green 
2131357ccf2bSBryan Green 	while (p) {
2132357ccf2bSBryan Green 		struct fuse_file *ff;
2133357ccf2bSBryan Green 		ff = rb_entry(p, struct fuse_file, polled_node);
2134357ccf2bSBryan Green 		wake_up_interruptible_all(&ff->poll_wait);
2135357ccf2bSBryan Green 
2136357ccf2bSBryan Green 		p = rb_next(p);
2137357ccf2bSBryan Green 	}
2138357ccf2bSBryan Green }
2139357ccf2bSBryan Green 
214069a53bf2SMiklos Szeredi /*
214169a53bf2SMiklos Szeredi  * Abort all requests.
214269a53bf2SMiklos Szeredi  *
2143b716d425SMiklos Szeredi  * Emergency exit in case of a malicious or accidental deadlock, or just a hung
2144b716d425SMiklos Szeredi  * filesystem.
214569a53bf2SMiklos Szeredi  *
2146b716d425SMiklos Szeredi  * The same effect is usually achievable through killing the filesystem daemon
2147b716d425SMiklos Szeredi  * and all users of the filesystem.  The exception is the combination of an
2148b716d425SMiklos Szeredi  * asynchronous request and the tricky deadlock (see
2149b716d425SMiklos Szeredi  * Documentation/filesystems/fuse.txt).
215069a53bf2SMiklos Szeredi  *
2151b716d425SMiklos Szeredi  * Aborting requests under I/O goes as follows: 1: Separate out unlocked
2152b716d425SMiklos Szeredi  * requests, they should be finished off immediately.  Locked requests will be
2153b716d425SMiklos Szeredi  * finished after unlock; see unlock_request(). 2: Finish off the unlocked
2154b716d425SMiklos Szeredi  * requests.  It is possible that some request will finish before we can.  This
2155b716d425SMiklos Szeredi  * is OK, the request will in that case be removed from the list before we touch
2156b716d425SMiklos Szeredi  * it.
215769a53bf2SMiklos Szeredi  */
21583b7008b2SSzymon Lukasz void fuse_abort_conn(struct fuse_conn *fc, bool is_abort)
215969a53bf2SMiklos Szeredi {
2160f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
2161f88996a9SMiklos Szeredi 
2162d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
216369a53bf2SMiklos Szeredi 	if (fc->connected) {
2164c3696046SMiklos Szeredi 		struct fuse_dev *fud;
2165b716d425SMiklos Szeredi 		struct fuse_req *req, *next;
216675f3ee4cSMiklos Szeredi 		LIST_HEAD(to_end);
2167be2ff42cSKirill Tkhai 		unsigned int i;
2168b716d425SMiklos Szeredi 
216963825b4eSKirill Tkhai 		/* Background queuing checks fc->connected under bg_lock */
217063825b4eSKirill Tkhai 		spin_lock(&fc->bg_lock);
217169a53bf2SMiklos Szeredi 		fc->connected = 0;
217263825b4eSKirill Tkhai 		spin_unlock(&fc->bg_lock);
217363825b4eSKirill Tkhai 
21743b7008b2SSzymon Lukasz 		fc->aborted = is_abort;
21759759bd51SMiklos Szeredi 		fuse_set_initialized(fc);
2176c3696046SMiklos Szeredi 		list_for_each_entry(fud, &fc->devices, entry) {
2177c3696046SMiklos Szeredi 			struct fuse_pqueue *fpq = &fud->pq;
2178c3696046SMiklos Szeredi 
217945a91cb1SMiklos Szeredi 			spin_lock(&fpq->lock);
2180e96edd94SMiklos Szeredi 			fpq->connected = 0;
21813a2b5b9cSMiklos Szeredi 			list_for_each_entry_safe(req, next, &fpq->io, list) {
2182b716d425SMiklos Szeredi 				req->out.h.error = -ECONNABORTED;
2183b716d425SMiklos Szeredi 				spin_lock(&req->waitq.lock);
2184b716d425SMiklos Szeredi 				set_bit(FR_ABORTED, &req->flags);
218577cd9d48SMiklos Szeredi 				if (!test_bit(FR_LOCKED, &req->flags)) {
218677cd9d48SMiklos Szeredi 					set_bit(FR_PRIVATE, &req->flags);
218787114373SMiklos Szeredi 					__fuse_get_request(req);
218875f3ee4cSMiklos Szeredi 					list_move(&req->list, &to_end);
218977cd9d48SMiklos Szeredi 				}
2190b716d425SMiklos Szeredi 				spin_unlock(&req->waitq.lock);
2191b716d425SMiklos Szeredi 			}
2192be2ff42cSKirill Tkhai 			for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
2193be2ff42cSKirill Tkhai 				list_splice_tail_init(&fpq->processing[i],
2194be2ff42cSKirill Tkhai 						      &to_end);
219545a91cb1SMiklos Szeredi 			spin_unlock(&fpq->lock);
2196c3696046SMiklos Szeredi 		}
2197ae2dffa3SKirill Tkhai 		spin_lock(&fc->bg_lock);
2198ae2dffa3SKirill Tkhai 		fc->blocked = 0;
219941f98274SMiklos Szeredi 		fc->max_background = UINT_MAX;
220041f98274SMiklos Szeredi 		flush_bg_queue(fc);
2201ae2dffa3SKirill Tkhai 		spin_unlock(&fc->bg_lock);
22028c91189aSMiklos Szeredi 
22034ce60812SMiklos Szeredi 		spin_lock(&fiq->waitq.lock);
22048c91189aSMiklos Szeredi 		fiq->connected = 0;
220575f3ee4cSMiklos Szeredi 		list_for_each_entry(req, &fiq->pending, list)
2206a8a86d78STahsin Erdogan 			clear_bit(FR_PENDING, &req->flags);
220775f3ee4cSMiklos Szeredi 		list_splice_tail_init(&fiq->pending, &to_end);
22088c91189aSMiklos Szeredi 		while (forget_pending(fiq))
22098c91189aSMiklos Szeredi 			kfree(dequeue_forget(fiq, 1, NULL));
22104ce60812SMiklos Szeredi 		wake_up_all_locked(&fiq->waitq);
22114ce60812SMiklos Szeredi 		spin_unlock(&fiq->waitq.lock);
22128c91189aSMiklos Szeredi 		kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
2213ee314a87SMiklos Szeredi 		end_polls(fc);
2214ee314a87SMiklos Szeredi 		wake_up_all(&fc->blocked_waitq);
2215ee314a87SMiklos Szeredi 		spin_unlock(&fc->lock);
22168c91189aSMiklos Szeredi 
221775f3ee4cSMiklos Szeredi 		end_requests(fc, &to_end);
2218ee314a87SMiklos Szeredi 	} else {
2219d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
222069a53bf2SMiklos Szeredi 	}
2221ee314a87SMiklos Szeredi }
222208cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn);
222369a53bf2SMiklos Szeredi 
2224b8f95e5dSMiklos Szeredi void fuse_wait_aborted(struct fuse_conn *fc)
2225b8f95e5dSMiklos Szeredi {
22262d84a2d1SMiklos Szeredi 	/* matches implicit memory barrier in fuse_drop_waiting() */
22272d84a2d1SMiklos Szeredi 	smp_mb();
2228b8f95e5dSMiklos Szeredi 	wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
2229b8f95e5dSMiklos Szeredi }
2230b8f95e5dSMiklos Szeredi 
223108cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file)
2232334f485dSMiklos Szeredi {
2233cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2234cc080e9eSMiklos Szeredi 
2235cc080e9eSMiklos Szeredi 	if (fud) {
2236cc080e9eSMiklos Szeredi 		struct fuse_conn *fc = fud->fc;
2237c3696046SMiklos Szeredi 		struct fuse_pqueue *fpq = &fud->pq;
223845ff350bSMiklos Szeredi 		LIST_HEAD(to_end);
2239be2ff42cSKirill Tkhai 		unsigned int i;
2240cc080e9eSMiklos Szeredi 
224145ff350bSMiklos Szeredi 		spin_lock(&fpq->lock);
2242c3696046SMiklos Szeredi 		WARN_ON(!list_empty(&fpq->io));
2243be2ff42cSKirill Tkhai 		for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
2244be2ff42cSKirill Tkhai 			list_splice_init(&fpq->processing[i], &to_end);
224545ff350bSMiklos Szeredi 		spin_unlock(&fpq->lock);
224645ff350bSMiklos Szeredi 
224745ff350bSMiklos Szeredi 		end_requests(fc, &to_end);
224845ff350bSMiklos Szeredi 
2249c3696046SMiklos Szeredi 		/* Are we the last open device? */
2250c3696046SMiklos Szeredi 		if (atomic_dec_and_test(&fc->dev_count)) {
2251f88996a9SMiklos Szeredi 			WARN_ON(fc->iq.fasync != NULL);
22523b7008b2SSzymon Lukasz 			fuse_abort_conn(fc, false);
2253c3696046SMiklos Szeredi 		}
2254cc080e9eSMiklos Szeredi 		fuse_dev_free(fud);
2255385a17bfSJeff Dike 	}
2256334f485dSMiklos Szeredi 	return 0;
2257334f485dSMiklos Szeredi }
225808cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release);
2259334f485dSMiklos Szeredi 
2260385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on)
2261385a17bfSJeff Dike {
2262cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2263cc080e9eSMiklos Szeredi 
2264cc080e9eSMiklos Szeredi 	if (!fud)
2265a87046d8SMiklos Szeredi 		return -EPERM;
2266385a17bfSJeff Dike 
2267385a17bfSJeff Dike 	/* No locking - fasync_helper does its own locking */
2268cc080e9eSMiklos Szeredi 	return fasync_helper(fd, file, on, &fud->fc->iq.fasync);
2269385a17bfSJeff Dike }
2270385a17bfSJeff Dike 
227100c570f4SMiklos Szeredi static int fuse_device_clone(struct fuse_conn *fc, struct file *new)
227200c570f4SMiklos Szeredi {
2273cc080e9eSMiklos Szeredi 	struct fuse_dev *fud;
2274cc080e9eSMiklos Szeredi 
227500c570f4SMiklos Szeredi 	if (new->private_data)
227600c570f4SMiklos Szeredi 		return -EINVAL;
227700c570f4SMiklos Szeredi 
2278cc080e9eSMiklos Szeredi 	fud = fuse_dev_alloc(fc);
2279cc080e9eSMiklos Szeredi 	if (!fud)
2280cc080e9eSMiklos Szeredi 		return -ENOMEM;
2281cc080e9eSMiklos Szeredi 
2282cc080e9eSMiklos Szeredi 	new->private_data = fud;
2283c3696046SMiklos Szeredi 	atomic_inc(&fc->dev_count);
228400c570f4SMiklos Szeredi 
228500c570f4SMiklos Szeredi 	return 0;
228600c570f4SMiklos Szeredi }
228700c570f4SMiklos Szeredi 
228800c570f4SMiklos Szeredi static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
228900c570f4SMiklos Szeredi 			   unsigned long arg)
229000c570f4SMiklos Szeredi {
229100c570f4SMiklos Szeredi 	int err = -ENOTTY;
229200c570f4SMiklos Szeredi 
229300c570f4SMiklos Szeredi 	if (cmd == FUSE_DEV_IOC_CLONE) {
229400c570f4SMiklos Szeredi 		int oldfd;
229500c570f4SMiklos Szeredi 
229600c570f4SMiklos Szeredi 		err = -EFAULT;
229700c570f4SMiklos Szeredi 		if (!get_user(oldfd, (__u32 __user *) arg)) {
229800c570f4SMiklos Szeredi 			struct file *old = fget(oldfd);
229900c570f4SMiklos Szeredi 
230000c570f4SMiklos Szeredi 			err = -EINVAL;
230100c570f4SMiklos Szeredi 			if (old) {
23028ed1f0e2SJann Horn 				struct fuse_dev *fud = NULL;
23038ed1f0e2SJann Horn 
23048ed1f0e2SJann Horn 				/*
23058ed1f0e2SJann Horn 				 * Check against file->f_op because CUSE
23068ed1f0e2SJann Horn 				 * uses the same ioctl handler.
23078ed1f0e2SJann Horn 				 */
23088ed1f0e2SJann Horn 				if (old->f_op == file->f_op &&
23098ed1f0e2SJann Horn 				    old->f_cred->user_ns == file->f_cred->user_ns)
23108ed1f0e2SJann Horn 					fud = fuse_get_dev(old);
231100c570f4SMiklos Szeredi 
2312cc080e9eSMiklos Szeredi 				if (fud) {
231300c570f4SMiklos Szeredi 					mutex_lock(&fuse_mutex);
2314cc080e9eSMiklos Szeredi 					err = fuse_device_clone(fud->fc, file);
231500c570f4SMiklos Szeredi 					mutex_unlock(&fuse_mutex);
231600c570f4SMiklos Szeredi 				}
231700c570f4SMiklos Szeredi 				fput(old);
231800c570f4SMiklos Szeredi 			}
231900c570f4SMiklos Szeredi 		}
232000c570f4SMiklos Szeredi 	}
232100c570f4SMiklos Szeredi 	return err;
232200c570f4SMiklos Szeredi }
232300c570f4SMiklos Szeredi 
23244b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = {
2325334f485dSMiklos Szeredi 	.owner		= THIS_MODULE,
232694e4fe2cSTom Van Braeckel 	.open		= fuse_dev_open,
2327334f485dSMiklos Szeredi 	.llseek		= no_llseek,
2328fbdbaccaSAl Viro 	.read_iter	= fuse_dev_read,
2329c3021629SMiklos Szeredi 	.splice_read	= fuse_dev_splice_read,
2330fbdbaccaSAl Viro 	.write_iter	= fuse_dev_write,
2331dd3bb14fSMiklos Szeredi 	.splice_write	= fuse_dev_splice_write,
2332334f485dSMiklos Szeredi 	.poll		= fuse_dev_poll,
2333334f485dSMiklos Szeredi 	.release	= fuse_dev_release,
2334385a17bfSJeff Dike 	.fasync		= fuse_dev_fasync,
233500c570f4SMiklos Szeredi 	.unlocked_ioctl = fuse_dev_ioctl,
233600c570f4SMiklos Szeredi 	.compat_ioctl   = fuse_dev_ioctl,
2337334f485dSMiklos Szeredi };
233808cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations);
2339334f485dSMiklos Szeredi 
2340334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = {
2341334f485dSMiklos Szeredi 	.minor = FUSE_MINOR,
2342334f485dSMiklos Szeredi 	.name  = "fuse",
2343334f485dSMiklos Szeredi 	.fops = &fuse_dev_operations,
2344334f485dSMiklos Szeredi };
2345334f485dSMiklos Szeredi 
2346334f485dSMiklos Szeredi int __init fuse_dev_init(void)
2347334f485dSMiklos Szeredi {
2348334f485dSMiklos Szeredi 	int err = -ENOMEM;
2349334f485dSMiklos Szeredi 	fuse_req_cachep = kmem_cache_create("fuse_request",
2350334f485dSMiklos Szeredi 					    sizeof(struct fuse_req),
235120c2df83SPaul Mundt 					    0, 0, NULL);
2352334f485dSMiklos Szeredi 	if (!fuse_req_cachep)
2353334f485dSMiklos Szeredi 		goto out;
2354334f485dSMiklos Szeredi 
2355334f485dSMiklos Szeredi 	err = misc_register(&fuse_miscdevice);
2356334f485dSMiklos Szeredi 	if (err)
2357334f485dSMiklos Szeredi 		goto out_cache_clean;
2358334f485dSMiklos Szeredi 
2359334f485dSMiklos Szeredi 	return 0;
2360334f485dSMiklos Szeredi 
2361334f485dSMiklos Szeredi  out_cache_clean:
2362334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
2363334f485dSMiklos Szeredi  out:
2364334f485dSMiklos Szeredi 	return err;
2365334f485dSMiklos Szeredi }
2366334f485dSMiklos Szeredi 
2367334f485dSMiklos Szeredi void fuse_dev_cleanup(void)
2368334f485dSMiklos Szeredi {
2369334f485dSMiklos Szeredi 	misc_deregister(&fuse_miscdevice);
2370334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
2371334f485dSMiklos Szeredi }
2372