xref: /openbmc/linux/fs/fuse/dev.c (revision 80ef0867)
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 
43fcee216bSMax Reitz static void fuse_request_init(struct fuse_mount *fm, struct fuse_req *req)
44334f485dSMiklos Szeredi {
45334f485dSMiklos Szeredi 	INIT_LIST_HEAD(&req->list);
46a4d27e75SMiklos Szeredi 	INIT_LIST_HEAD(&req->intr_entry);
47334f485dSMiklos Szeredi 	init_waitqueue_head(&req->waitq);
48ec99f6d3SElena Reshetova 	refcount_set(&req->count, 1);
4933e14b4dSMiklos Szeredi 	__set_bit(FR_PENDING, &req->flags);
50fcee216bSMax Reitz 	req->fm = fm;
51334f485dSMiklos Szeredi }
52334f485dSMiklos Szeredi 
53fcee216bSMax Reitz static struct fuse_req *fuse_request_alloc(struct fuse_mount *fm, gfp_t flags)
54334f485dSMiklos Szeredi {
558a7aa286SMiklos Szeredi 	struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags);
567213394cSMiklos Szeredi 	if (req)
57fcee216bSMax Reitz 		fuse_request_init(fm, req);
584250c066SMaxim Patlasov 
59334f485dSMiklos Szeredi 	return req;
60334f485dSMiklos Szeredi }
614250c066SMaxim Patlasov 
6266abc359SMiklos Szeredi static void fuse_request_free(struct fuse_req *req)
63e52a8250SMiklos Szeredi {
64334f485dSMiklos Szeredi 	kmem_cache_free(fuse_req_cachep, req);
65334f485dSMiklos Szeredi }
66334f485dSMiklos Szeredi 
6766abc359SMiklos Szeredi static void __fuse_get_request(struct fuse_req *req)
68334f485dSMiklos Szeredi {
69ec99f6d3SElena Reshetova 	refcount_inc(&req->count);
70334f485dSMiklos Szeredi }
71334f485dSMiklos Szeredi 
72334f485dSMiklos Szeredi /* Must be called with > 1 refcount */
73334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req)
74334f485dSMiklos Szeredi {
75ec99f6d3SElena Reshetova 	refcount_dec(&req->count);
76334f485dSMiklos Szeredi }
77334f485dSMiklos Szeredi 
789759bd51SMiklos Szeredi void fuse_set_initialized(struct fuse_conn *fc)
799759bd51SMiklos Szeredi {
809759bd51SMiklos Szeredi 	/* Make sure stores before this are seen on another CPU */
819759bd51SMiklos Szeredi 	smp_wmb();
829759bd51SMiklos Szeredi 	fc->initialized = 1;
839759bd51SMiklos Szeredi }
849759bd51SMiklos Szeredi 
850aada884SMaxim Patlasov static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
860aada884SMaxim Patlasov {
870aada884SMaxim Patlasov 	return !fc->initialized || (for_background && fc->blocked);
880aada884SMaxim Patlasov }
890aada884SMaxim Patlasov 
90b8f95e5dSMiklos Szeredi static void fuse_drop_waiting(struct fuse_conn *fc)
91b8f95e5dSMiklos Szeredi {
922d84a2d1SMiklos Szeredi 	/*
932d84a2d1SMiklos Szeredi 	 * lockess check of fc->connected is okay, because atomic_dec_and_test()
942d84a2d1SMiklos Szeredi 	 * provides a memory barrier mached with the one in fuse_wait_aborted()
952d84a2d1SMiklos Szeredi 	 * to ensure no wake-up is missed.
962d84a2d1SMiklos Szeredi 	 */
972d84a2d1SMiklos Szeredi 	if (atomic_dec_and_test(&fc->num_waiting) &&
982d84a2d1SMiklos Szeredi 	    !READ_ONCE(fc->connected)) {
99b8f95e5dSMiklos Szeredi 		/* wake up aborters */
100b8f95e5dSMiklos Szeredi 		wake_up_all(&fc->blocked_waitq);
101b8f95e5dSMiklos Szeredi 	}
102b8f95e5dSMiklos Szeredi }
103b8f95e5dSMiklos Szeredi 
1048f622e94SMax Reitz static void fuse_put_request(struct fuse_req *req);
10566abc359SMiklos Szeredi 
106fcee216bSMax Reitz static struct fuse_req *fuse_get_req(struct fuse_mount *fm, bool for_background)
107334f485dSMiklos Szeredi {
108fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
10908a53cdcSMiklos Szeredi 	struct fuse_req *req;
1100aada884SMaxim Patlasov 	int err;
1110aada884SMaxim Patlasov 	atomic_inc(&fc->num_waiting);
1120aada884SMaxim Patlasov 
1130aada884SMaxim Patlasov 	if (fuse_block_alloc(fc, for_background)) {
1149bc5dddaSMiklos Szeredi 		err = -EINTR;
1157d3a07fcSAl Viro 		if (wait_event_killable_exclusive(fc->blocked_waitq,
1167d3a07fcSAl Viro 				!fuse_block_alloc(fc, for_background)))
1179bc5dddaSMiklos Szeredi 			goto out;
1180aada884SMaxim Patlasov 	}
1199759bd51SMiklos Szeredi 	/* Matches smp_wmb() in fuse_set_initialized() */
1209759bd51SMiklos Szeredi 	smp_rmb();
12108a53cdcSMiklos Szeredi 
12251eb01e7SMiklos Szeredi 	err = -ENOTCONN;
12351eb01e7SMiklos Szeredi 	if (!fc->connected)
12451eb01e7SMiklos Szeredi 		goto out;
12551eb01e7SMiklos Szeredi 
126de155226SMiklos Szeredi 	err = -ECONNREFUSED;
127de155226SMiklos Szeredi 	if (fc->conn_error)
128de155226SMiklos Szeredi 		goto out;
129de155226SMiklos Szeredi 
130fcee216bSMax Reitz 	req = fuse_request_alloc(fm, GFP_KERNEL);
1319bc5dddaSMiklos Szeredi 	err = -ENOMEM;
132722d2beaSMaxim Patlasov 	if (!req) {
133722d2beaSMaxim Patlasov 		if (for_background)
134722d2beaSMaxim Patlasov 			wake_up(&fc->blocked_waitq);
1359bc5dddaSMiklos Szeredi 		goto out;
136722d2beaSMaxim Patlasov 	}
137334f485dSMiklos Szeredi 
1388cb08329SEric W. Biederman 	req->in.h.uid = from_kuid(fc->user_ns, current_fsuid());
1398cb08329SEric W. Biederman 	req->in.h.gid = from_kgid(fc->user_ns, current_fsgid());
140c9582eb0SEric W. Biederman 	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
141c9582eb0SEric W. Biederman 
142825d6d33SMiklos Szeredi 	__set_bit(FR_WAITING, &req->flags);
143825d6d33SMiklos Szeredi 	if (for_background)
144825d6d33SMiklos Szeredi 		__set_bit(FR_BACKGROUND, &req->flags);
145825d6d33SMiklos Szeredi 
146c9582eb0SEric W. Biederman 	if (unlikely(req->in.h.uid == ((uid_t)-1) ||
147c9582eb0SEric W. Biederman 		     req->in.h.gid == ((gid_t)-1))) {
1488f622e94SMax Reitz 		fuse_put_request(req);
149c9582eb0SEric W. Biederman 		return ERR_PTR(-EOVERFLOW);
150c9582eb0SEric W. Biederman 	}
151334f485dSMiklos Szeredi 	return req;
1529bc5dddaSMiklos Szeredi 
1539bc5dddaSMiklos Szeredi  out:
154b8f95e5dSMiklos Szeredi 	fuse_drop_waiting(fc);
1559bc5dddaSMiklos Szeredi 	return ERR_PTR(err);
156334f485dSMiklos Szeredi }
1578b41e671SMaxim Patlasov 
1588f622e94SMax Reitz static void fuse_put_request(struct fuse_req *req)
159334f485dSMiklos Szeredi {
160fcee216bSMax Reitz 	struct fuse_conn *fc = req->fm->fc;
1618f622e94SMax Reitz 
162ec99f6d3SElena Reshetova 	if (refcount_dec_and_test(&req->count)) {
163825d6d33SMiklos Szeredi 		if (test_bit(FR_BACKGROUND, &req->flags)) {
164722d2beaSMaxim Patlasov 			/*
165722d2beaSMaxim Patlasov 			 * We get here in the unlikely case that a background
166722d2beaSMaxim Patlasov 			 * request was allocated but not sent
167722d2beaSMaxim Patlasov 			 */
168ae2dffa3SKirill Tkhai 			spin_lock(&fc->bg_lock);
169722d2beaSMaxim Patlasov 			if (!fc->blocked)
170722d2beaSMaxim Patlasov 				wake_up(&fc->blocked_waitq);
171ae2dffa3SKirill Tkhai 			spin_unlock(&fc->bg_lock);
172722d2beaSMaxim Patlasov 		}
173722d2beaSMaxim Patlasov 
174825d6d33SMiklos Szeredi 		if (test_bit(FR_WAITING, &req->flags)) {
175825d6d33SMiklos Szeredi 			__clear_bit(FR_WAITING, &req->flags);
176b8f95e5dSMiklos Szeredi 			fuse_drop_waiting(fc);
17773e0e738SMiklos Szeredi 		}
17833649c91SMiklos Szeredi 
179ce1d5a49SMiklos Szeredi 		fuse_request_free(req);
1807128ec2aSMiklos Szeredi 	}
1817128ec2aSMiklos Szeredi }
1827128ec2aSMiklos Szeredi 
18314d46d7aSStefan Hajnoczi unsigned int fuse_len_args(unsigned int numargs, struct fuse_arg *args)
184d12def1bSMiklos Szeredi {
185d12def1bSMiklos Szeredi 	unsigned nbytes = 0;
186d12def1bSMiklos Szeredi 	unsigned i;
187d12def1bSMiklos Szeredi 
188d12def1bSMiklos Szeredi 	for (i = 0; i < numargs; i++)
189d12def1bSMiklos Szeredi 		nbytes += args[i].size;
190d12def1bSMiklos Szeredi 
191d12def1bSMiklos Szeredi 	return nbytes;
192d12def1bSMiklos Szeredi }
19314d46d7aSStefan Hajnoczi EXPORT_SYMBOL_GPL(fuse_len_args);
194d12def1bSMiklos Szeredi 
19579d96effSStefan Hajnoczi u64 fuse_get_unique(struct fuse_iqueue *fiq)
196d12def1bSMiklos Szeredi {
197c59fd85eSKirill Tkhai 	fiq->reqctr += FUSE_REQ_ID_STEP;
198c59fd85eSKirill Tkhai 	return fiq->reqctr;
199d12def1bSMiklos Szeredi }
20079d96effSStefan Hajnoczi EXPORT_SYMBOL_GPL(fuse_get_unique);
201d12def1bSMiklos Szeredi 
202be2ff42cSKirill Tkhai static unsigned int fuse_req_hash(u64 unique)
203be2ff42cSKirill Tkhai {
204be2ff42cSKirill Tkhai 	return hash_long(unique & ~FUSE_INT_REQ_BIT, FUSE_PQ_HASH_BITS);
205be2ff42cSKirill Tkhai }
206be2ff42cSKirill Tkhai 
207ae3aad77SStefan Hajnoczi /**
208ae3aad77SStefan Hajnoczi  * A new request is available, wake fiq->waitq
209ae3aad77SStefan Hajnoczi  */
210ae3aad77SStefan Hajnoczi static void fuse_dev_wake_and_unlock(struct fuse_iqueue *fiq)
211ae3aad77SStefan Hajnoczi __releases(fiq->lock)
212ae3aad77SStefan Hajnoczi {
213ae3aad77SStefan Hajnoczi 	wake_up(&fiq->waitq);
214ae3aad77SStefan Hajnoczi 	kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
215ae3aad77SStefan Hajnoczi 	spin_unlock(&fiq->lock);
216ae3aad77SStefan Hajnoczi }
217ae3aad77SStefan Hajnoczi 
218ae3aad77SStefan Hajnoczi const struct fuse_iqueue_ops fuse_dev_fiq_ops = {
219ae3aad77SStefan Hajnoczi 	.wake_forget_and_unlock		= fuse_dev_wake_and_unlock,
220ae3aad77SStefan Hajnoczi 	.wake_interrupt_and_unlock	= fuse_dev_wake_and_unlock,
221ae3aad77SStefan Hajnoczi 	.wake_pending_and_unlock	= fuse_dev_wake_and_unlock,
222ae3aad77SStefan Hajnoczi };
223ae3aad77SStefan Hajnoczi EXPORT_SYMBOL_GPL(fuse_dev_fiq_ops);
224ae3aad77SStefan Hajnoczi 
225ae3aad77SStefan Hajnoczi static void queue_request_and_unlock(struct fuse_iqueue *fiq,
226ae3aad77SStefan Hajnoczi 				     struct fuse_req *req)
227ae3aad77SStefan Hajnoczi __releases(fiq->lock)
228d12def1bSMiklos Szeredi {
229d12def1bSMiklos Szeredi 	req->in.h.len = sizeof(struct fuse_in_header) +
23014d46d7aSStefan Hajnoczi 		fuse_len_args(req->args->in_numargs,
231d4993774SMiklos Szeredi 			      (struct fuse_arg *) req->args->in_args);
232f88996a9SMiklos Szeredi 	list_add_tail(&req->list, &fiq->pending);
233ae3aad77SStefan Hajnoczi 	fiq->ops->wake_pending_and_unlock(fiq);
234d12def1bSMiklos Szeredi }
235d12def1bSMiklos Szeredi 
23607e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
23707e77dcaSMiklos Szeredi 		       u64 nodeid, u64 nlookup)
23807e77dcaSMiklos Szeredi {
239f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
240f88996a9SMiklos Szeredi 
24102c048b9SMiklos Szeredi 	forget->forget_one.nodeid = nodeid;
24202c048b9SMiklos Szeredi 	forget->forget_one.nlookup = nlookup;
24307e77dcaSMiklos Szeredi 
24476e43c8cSEric Biggers 	spin_lock(&fiq->lock);
245e16714d8SMiklos Szeredi 	if (fiq->connected) {
246f88996a9SMiklos Szeredi 		fiq->forget_list_tail->next = forget;
247f88996a9SMiklos Szeredi 		fiq->forget_list_tail = forget;
248ae3aad77SStefan Hajnoczi 		fiq->ops->wake_forget_and_unlock(fiq);
2495dfcc87fSMiklos Szeredi 	} else {
2505dfcc87fSMiklos Szeredi 		kfree(forget);
25176e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
25207e77dcaSMiklos Szeredi 	}
253ae3aad77SStefan Hajnoczi }
25407e77dcaSMiklos Szeredi 
255d12def1bSMiklos Szeredi static void flush_bg_queue(struct fuse_conn *fc)
256d12def1bSMiklos Szeredi {
257e287179aSKirill Tkhai 	struct fuse_iqueue *fiq = &fc->iq;
258e287179aSKirill Tkhai 
2597a6d3c8bSCsaba Henk 	while (fc->active_background < fc->max_background &&
260d12def1bSMiklos Szeredi 	       !list_empty(&fc->bg_queue)) {
261d12def1bSMiklos Szeredi 		struct fuse_req *req;
262d12def1bSMiklos Szeredi 
263e287179aSKirill Tkhai 		req = list_first_entry(&fc->bg_queue, struct fuse_req, list);
264d12def1bSMiklos Szeredi 		list_del(&req->list);
265d12def1bSMiklos Szeredi 		fc->active_background++;
26676e43c8cSEric Biggers 		spin_lock(&fiq->lock);
267f88996a9SMiklos Szeredi 		req->in.h.unique = fuse_get_unique(fiq);
268ae3aad77SStefan Hajnoczi 		queue_request_and_unlock(fiq, req);
269d12def1bSMiklos Szeredi 	}
270d12def1bSMiklos Szeredi }
271d12def1bSMiklos Szeredi 
2726dbbcb12SMiklos Szeredi /*
273334f485dSMiklos Szeredi  * This function is called when a request is finished.  Either a reply
274f9a2842eSMiklos Szeredi  * has arrived or it was aborted (and not yet sent) or some error
275f43b155aSMiklos Szeredi  * occurred during communication with userspace, or the device file
27651eb01e7SMiklos Szeredi  * was closed.  The requester thread is woken up (if still waiting),
27751eb01e7SMiklos Szeredi  * the 'end' callback is called if given, else the reference to the
27851eb01e7SMiklos Szeredi  * request is released
279334f485dSMiklos Szeredi  */
2808f622e94SMax Reitz void fuse_request_end(struct fuse_req *req)
281334f485dSMiklos Szeredi {
282fcee216bSMax Reitz 	struct fuse_mount *fm = req->fm;
283fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
2844ce60812SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
285365ae710SMiklos Szeredi 
286efe2800fSMiklos Szeredi 	if (test_and_set_bit(FR_FINISHED, &req->flags))
287b8f95e5dSMiklos Szeredi 		goto put_request;
2882b319d1fSMiklos Szeredi 
289217316a6SKirill Tkhai 	/*
290217316a6SKirill Tkhai 	 * test_and_set_bit() implies smp_mb() between bit
291217316a6SKirill Tkhai 	 * changing and below intr_entry check. Pairs with
292217316a6SKirill Tkhai 	 * smp_mb() from queue_interrupt().
293217316a6SKirill Tkhai 	 */
294217316a6SKirill Tkhai 	if (!list_empty(&req->intr_entry)) {
29576e43c8cSEric Biggers 		spin_lock(&fiq->lock);
2960d8e84b0SMiklos Szeredi 		list_del_init(&req->intr_entry);
29776e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
298217316a6SKirill Tkhai 	}
29933e14b4dSMiklos Szeredi 	WARN_ON(test_bit(FR_PENDING, &req->flags));
30033e14b4dSMiklos Szeredi 	WARN_ON(test_bit(FR_SENT, &req->flags));
301825d6d33SMiklos Szeredi 	if (test_bit(FR_BACKGROUND, &req->flags)) {
302ae2dffa3SKirill Tkhai 		spin_lock(&fc->bg_lock);
303825d6d33SMiklos Szeredi 		clear_bit(FR_BACKGROUND, &req->flags);
304908a572bSMiklos Szeredi 		if (fc->num_background == fc->max_background) {
30551eb01e7SMiklos Szeredi 			fc->blocked = 0;
306722d2beaSMaxim Patlasov 			wake_up(&fc->blocked_waitq);
307908a572bSMiklos Szeredi 		} else if (!fc->blocked) {
308908a572bSMiklos Szeredi 			/*
309908a572bSMiklos Szeredi 			 * Wake up next waiter, if any.  It's okay to use
310908a572bSMiklos Szeredi 			 * waitqueue_active(), as we've already synced up
311908a572bSMiklos Szeredi 			 * fc->blocked with waiters with the wake_up() call
312908a572bSMiklos Szeredi 			 * above.
313908a572bSMiklos Szeredi 			 */
314908a572bSMiklos Szeredi 			if (waitqueue_active(&fc->blocked_waitq))
315908a572bSMiklos Szeredi 				wake_up(&fc->blocked_waitq);
316908a572bSMiklos Szeredi 		}
317722d2beaSMaxim Patlasov 
318fcee216bSMax Reitz 		if (fc->num_background == fc->congestion_threshold && fm->sb) {
319fcee216bSMax Reitz 			clear_bdi_congested(fm->sb->s_bdi, BLK_RW_SYNC);
320fcee216bSMax Reitz 			clear_bdi_congested(fm->sb->s_bdi, BLK_RW_ASYNC);
321f92b99b9SMiklos Szeredi 		}
32251eb01e7SMiklos Szeredi 		fc->num_background--;
323d12def1bSMiklos Szeredi 		fc->active_background--;
324d12def1bSMiklos Szeredi 		flush_bg_queue(fc);
325ae2dffa3SKirill Tkhai 		spin_unlock(&fc->bg_lock);
3265e0fed71SKirill Tkhai 	} else {
3275e0fed71SKirill Tkhai 		/* Wake up waiter sleeping in request_wait_answer() */
32851eb01e7SMiklos Szeredi 		wake_up(&req->waitq);
3295e0fed71SKirill Tkhai 	}
3305e0fed71SKirill Tkhai 
3313e8cb8b2SMiklos Szeredi 	if (test_bit(FR_ASYNC, &req->flags))
332fcee216bSMax Reitz 		req->args->end(fm, req->args, req->out.h.error);
333b8f95e5dSMiklos Szeredi put_request:
3348f622e94SMax Reitz 	fuse_put_request(req);
335334f485dSMiklos Szeredi }
33604ec5af0SStefan Hajnoczi EXPORT_SYMBOL_GPL(fuse_request_end);
337334f485dSMiklos Szeredi 
3388f622e94SMax Reitz static int queue_interrupt(struct fuse_req *req)
339a4d27e75SMiklos Szeredi {
340fcee216bSMax Reitz 	struct fuse_iqueue *fiq = &req->fm->fc->iq;
3418f622e94SMax Reitz 
34276e43c8cSEric Biggers 	spin_lock(&fiq->lock);
343b782911bSKirill Tkhai 	/* Check for we've sent request to interrupt this req */
344b782911bSKirill Tkhai 	if (unlikely(!test_bit(FR_INTERRUPTED, &req->flags))) {
34576e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
346b782911bSKirill Tkhai 		return -EINVAL;
347b782911bSKirill Tkhai 	}
348b782911bSKirill Tkhai 
349217316a6SKirill Tkhai 	if (list_empty(&req->intr_entry)) {
350217316a6SKirill Tkhai 		list_add_tail(&req->intr_entry, &fiq->interrupts);
351217316a6SKirill Tkhai 		/*
352217316a6SKirill Tkhai 		 * Pairs with smp_mb() implied by test_and_set_bit()
35375d89258SKirill Tkhai 		 * from fuse_request_end().
354217316a6SKirill Tkhai 		 */
355217316a6SKirill Tkhai 		smp_mb();
3566ba4d272SSahitya Tummala 		if (test_bit(FR_FINISHED, &req->flags)) {
357217316a6SKirill Tkhai 			list_del_init(&req->intr_entry);
35876e43c8cSEric Biggers 			spin_unlock(&fiq->lock);
359b782911bSKirill Tkhai 			return 0;
3606ba4d272SSahitya Tummala 		}
361ae3aad77SStefan Hajnoczi 		fiq->ops->wake_interrupt_and_unlock(fiq);
362ae3aad77SStefan Hajnoczi 	} else {
36376e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
364ae3aad77SStefan Hajnoczi 	}
365b782911bSKirill Tkhai 	return 0;
366a4d27e75SMiklos Szeredi }
367a4d27e75SMiklos Szeredi 
3688f622e94SMax Reitz static void request_wait_answer(struct fuse_req *req)
369334f485dSMiklos Szeredi {
370fcee216bSMax Reitz 	struct fuse_conn *fc = req->fm->fc;
3714ce60812SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
372c4775267SMiklos Szeredi 	int err;
373c4775267SMiklos Szeredi 
374a4d27e75SMiklos Szeredi 	if (!fc->no_interrupt) {
375a4d27e75SMiklos Szeredi 		/* Any signal may interrupt this */
376c4775267SMiklos Szeredi 		err = wait_event_interruptible(req->waitq,
37733e14b4dSMiklos Szeredi 					test_bit(FR_FINISHED, &req->flags));
378c4775267SMiklos Szeredi 		if (!err)
379334f485dSMiklos Szeredi 			return;
380334f485dSMiklos Szeredi 
381825d6d33SMiklos Szeredi 		set_bit(FR_INTERRUPTED, &req->flags);
3828f7bb368SMiklos Szeredi 		/* matches barrier in fuse_dev_do_read() */
3838f7bb368SMiklos Szeredi 		smp_mb__after_atomic();
38433e14b4dSMiklos Szeredi 		if (test_bit(FR_SENT, &req->flags))
3858f622e94SMax Reitz 			queue_interrupt(req);
386a4d27e75SMiklos Szeredi 	}
387a4d27e75SMiklos Szeredi 
388825d6d33SMiklos Szeredi 	if (!test_bit(FR_FORCE, &req->flags)) {
389a4d27e75SMiklos Szeredi 		/* Only fatal signals may interrupt this */
3907d3a07fcSAl Viro 		err = wait_event_killable(req->waitq,
39133e14b4dSMiklos Szeredi 					test_bit(FR_FINISHED, &req->flags));
392c4775267SMiklos Szeredi 		if (!err)
393a4d27e75SMiklos Szeredi 			return;
394a4d27e75SMiklos Szeredi 
39576e43c8cSEric Biggers 		spin_lock(&fiq->lock);
396a131de0aSMiklos Szeredi 		/* Request is not yet in userspace, bail out */
39733e14b4dSMiklos Szeredi 		if (test_bit(FR_PENDING, &req->flags)) {
398a131de0aSMiklos Szeredi 			list_del(&req->list);
39976e43c8cSEric Biggers 			spin_unlock(&fiq->lock);
400a131de0aSMiklos Szeredi 			__fuse_put_request(req);
401334f485dSMiklos Szeredi 			req->out.h.error = -EINTR;
402a131de0aSMiklos Szeredi 			return;
403a131de0aSMiklos Szeredi 		}
40476e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
405a131de0aSMiklos Szeredi 	}
406a131de0aSMiklos Szeredi 
407a131de0aSMiklos Szeredi 	/*
408a131de0aSMiklos Szeredi 	 * Either request is already in userspace, or it was forced.
409a131de0aSMiklos Szeredi 	 * Wait it out.
410a131de0aSMiklos Szeredi 	 */
41133e14b4dSMiklos Szeredi 	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
412334f485dSMiklos Szeredi }
413334f485dSMiklos Szeredi 
4148f622e94SMax Reitz static void __fuse_request_send(struct fuse_req *req)
415334f485dSMiklos Szeredi {
416fcee216bSMax Reitz 	struct fuse_iqueue *fiq = &req->fm->fc->iq;
417e16714d8SMiklos Szeredi 
418825d6d33SMiklos Szeredi 	BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
41976e43c8cSEric Biggers 	spin_lock(&fiq->lock);
420e16714d8SMiklos Szeredi 	if (!fiq->connected) {
42176e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
422334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
423c4775267SMiklos Szeredi 	} else {
424f88996a9SMiklos Szeredi 		req->in.h.unique = fuse_get_unique(fiq);
425334f485dSMiklos Szeredi 		/* acquire extra reference, since request is still needed
42604ec5af0SStefan Hajnoczi 		   after fuse_request_end() */
427334f485dSMiklos Szeredi 		__fuse_get_request(req);
428ae3aad77SStefan Hajnoczi 		queue_request_and_unlock(fiq, req);
429334f485dSMiklos Szeredi 
4308f622e94SMax Reitz 		request_wait_answer(req);
43104ec5af0SStefan Hajnoczi 		/* Pairs with smp_wmb() in fuse_request_end() */
432c4775267SMiklos Szeredi 		smp_rmb();
433334f485dSMiklos Szeredi 	}
434334f485dSMiklos Szeredi }
4356a4e922cSEric Wong 
43621f62174SMiklos Szeredi static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args)
43721f62174SMiklos Szeredi {
438d5b48543SMiklos Szeredi 	if (fc->minor < 4 && args->opcode == FUSE_STATFS)
439d5b48543SMiklos Szeredi 		args->out_args[0].size = FUSE_COMPAT_STATFS_SIZE;
44021f62174SMiklos Szeredi 
44121f62174SMiklos Szeredi 	if (fc->minor < 9) {
442d5b48543SMiklos Szeredi 		switch (args->opcode) {
44321f62174SMiklos Szeredi 		case FUSE_LOOKUP:
44421f62174SMiklos Szeredi 		case FUSE_CREATE:
44521f62174SMiklos Szeredi 		case FUSE_MKNOD:
44621f62174SMiklos Szeredi 		case FUSE_MKDIR:
44721f62174SMiklos Szeredi 		case FUSE_SYMLINK:
44821f62174SMiklos Szeredi 		case FUSE_LINK:
449d5b48543SMiklos Szeredi 			args->out_args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
45021f62174SMiklos Szeredi 			break;
45121f62174SMiklos Szeredi 		case FUSE_GETATTR:
45221f62174SMiklos Szeredi 		case FUSE_SETATTR:
453d5b48543SMiklos Szeredi 			args->out_args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
45421f62174SMiklos Szeredi 			break;
45521f62174SMiklos Szeredi 		}
45621f62174SMiklos Szeredi 	}
45721f62174SMiklos Szeredi 	if (fc->minor < 12) {
458d5b48543SMiklos Szeredi 		switch (args->opcode) {
45921f62174SMiklos Szeredi 		case FUSE_CREATE:
460d5b48543SMiklos Szeredi 			args->in_args[0].size = sizeof(struct fuse_open_in);
46121f62174SMiklos Szeredi 			break;
46221f62174SMiklos Szeredi 		case FUSE_MKNOD:
463d5b48543SMiklos Szeredi 			args->in_args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE;
46421f62174SMiklos Szeredi 			break;
46521f62174SMiklos Szeredi 		}
46621f62174SMiklos Szeredi 	}
46721f62174SMiklos Szeredi }
46821f62174SMiklos Szeredi 
4698f622e94SMax Reitz static void fuse_force_creds(struct fuse_req *req)
470e413754bSMiklos Szeredi {
471fcee216bSMax Reitz 	struct fuse_conn *fc = req->fm->fc;
4728f622e94SMax Reitz 
473e413754bSMiklos Szeredi 	req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
474e413754bSMiklos Szeredi 	req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid());
475e413754bSMiklos Szeredi 	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
476e413754bSMiklos Szeredi }
477e413754bSMiklos Szeredi 
4785addcd5dSYueHaibing static void fuse_args_to_req(struct fuse_req *req, struct fuse_args *args)
47968583165SMiklos Szeredi {
48068583165SMiklos Szeredi 	req->in.h.opcode = args->opcode;
48168583165SMiklos Szeredi 	req->in.h.nodeid = args->nodeid;
482d4993774SMiklos Szeredi 	req->args = args;
4833e8cb8b2SMiklos Szeredi 	if (args->end)
4843e8cb8b2SMiklos Szeredi 		__set_bit(FR_ASYNC, &req->flags);
48568583165SMiklos Szeredi }
48668583165SMiklos Szeredi 
487fcee216bSMax Reitz ssize_t fuse_simple_request(struct fuse_mount *fm, struct fuse_args *args)
4887078187aSMiklos Szeredi {
489fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
4907078187aSMiklos Szeredi 	struct fuse_req *req;
4917078187aSMiklos Szeredi 	ssize_t ret;
4927078187aSMiklos Szeredi 
493c500ebaaSMiklos Szeredi 	if (args->force) {
494e413754bSMiklos Szeredi 		atomic_inc(&fc->num_waiting);
495fcee216bSMax Reitz 		req = fuse_request_alloc(fm, GFP_KERNEL | __GFP_NOFAIL);
496e413754bSMiklos Szeredi 
497e413754bSMiklos Szeredi 		if (!args->nocreds)
4988f622e94SMax Reitz 			fuse_force_creds(req);
499e413754bSMiklos Szeredi 
500e413754bSMiklos Szeredi 		__set_bit(FR_WAITING, &req->flags);
501c500ebaaSMiklos Szeredi 		__set_bit(FR_FORCE, &req->flags);
502c500ebaaSMiklos Szeredi 	} else {
503e413754bSMiklos Szeredi 		WARN_ON(args->nocreds);
504fcee216bSMax Reitz 		req = fuse_get_req(fm, false);
5057078187aSMiklos Szeredi 		if (IS_ERR(req))
5067078187aSMiklos Szeredi 			return PTR_ERR(req);
507c500ebaaSMiklos Szeredi 	}
5087078187aSMiklos Szeredi 
50921f62174SMiklos Szeredi 	/* Needs to be done after fuse_get_req() so that fc->minor is valid */
51021f62174SMiklos Szeredi 	fuse_adjust_compat(fc, args);
51168583165SMiklos Szeredi 	fuse_args_to_req(req, args);
51221f62174SMiklos Szeredi 
513454a7613SMiklos Szeredi 	if (!args->noreply)
514454a7613SMiklos Szeredi 		__set_bit(FR_ISREPLY, &req->flags);
5158f622e94SMax Reitz 	__fuse_request_send(req);
5167078187aSMiklos Szeredi 	ret = req->out.h.error;
517d5b48543SMiklos Szeredi 	if (!ret && args->out_argvar) {
518093f38a2SMiklos Szeredi 		BUG_ON(args->out_numargs == 0);
519d4993774SMiklos Szeredi 		ret = args->out_args[args->out_numargs - 1].size;
5207078187aSMiklos Szeredi 	}
5218f622e94SMax Reitz 	fuse_put_request(req);
5227078187aSMiklos Szeredi 
5237078187aSMiklos Szeredi 	return ret;
5247078187aSMiklos Szeredi }
5257078187aSMiklos Szeredi 
5268f622e94SMax Reitz static bool fuse_request_queue_background(struct fuse_req *req)
527334f485dSMiklos Szeredi {
528fcee216bSMax Reitz 	struct fuse_mount *fm = req->fm;
529fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
53063825b4eSKirill Tkhai 	bool queued = false;
53163825b4eSKirill Tkhai 
53263825b4eSKirill Tkhai 	WARN_ON(!test_bit(FR_BACKGROUND, &req->flags));
533825d6d33SMiklos Szeredi 	if (!test_bit(FR_WAITING, &req->flags)) {
534825d6d33SMiklos Szeredi 		__set_bit(FR_WAITING, &req->flags);
5355437f241SMiklos Szeredi 		atomic_inc(&fc->num_waiting);
5365437f241SMiklos Szeredi 	}
537825d6d33SMiklos Szeredi 	__set_bit(FR_ISREPLY, &req->flags);
538ae2dffa3SKirill Tkhai 	spin_lock(&fc->bg_lock);
53963825b4eSKirill Tkhai 	if (likely(fc->connected)) {
54051eb01e7SMiklos Szeredi 		fc->num_background++;
5417a6d3c8bSCsaba Henk 		if (fc->num_background == fc->max_background)
54251eb01e7SMiklos Szeredi 			fc->blocked = 1;
543fcee216bSMax Reitz 		if (fc->num_background == fc->congestion_threshold && fm->sb) {
544fcee216bSMax Reitz 			set_bdi_congested(fm->sb->s_bdi, BLK_RW_SYNC);
545fcee216bSMax Reitz 			set_bdi_congested(fm->sb->s_bdi, BLK_RW_ASYNC);
546f92b99b9SMiklos Szeredi 		}
547d12def1bSMiklos Szeredi 		list_add_tail(&req->list, &fc->bg_queue);
548d12def1bSMiklos Szeredi 		flush_bg_queue(fc);
54963825b4eSKirill Tkhai 		queued = true;
55063825b4eSKirill Tkhai 	}
551ae2dffa3SKirill Tkhai 	spin_unlock(&fc->bg_lock);
55263825b4eSKirill Tkhai 
55363825b4eSKirill Tkhai 	return queued;
554d12def1bSMiklos Szeredi }
55551eb01e7SMiklos Szeredi 
556fcee216bSMax Reitz int fuse_simple_background(struct fuse_mount *fm, struct fuse_args *args,
55712597287SMiklos Szeredi 			    gfp_t gfp_flags)
55812597287SMiklos Szeredi {
55912597287SMiklos Szeredi 	struct fuse_req *req;
56012597287SMiklos Szeredi 
56112597287SMiklos Szeredi 	if (args->force) {
56212597287SMiklos Szeredi 		WARN_ON(!args->nocreds);
563fcee216bSMax Reitz 		req = fuse_request_alloc(fm, gfp_flags);
56412597287SMiklos Szeredi 		if (!req)
56512597287SMiklos Szeredi 			return -ENOMEM;
56612597287SMiklos Szeredi 		__set_bit(FR_BACKGROUND, &req->flags);
56712597287SMiklos Szeredi 	} else {
56812597287SMiklos Szeredi 		WARN_ON(args->nocreds);
569fcee216bSMax Reitz 		req = fuse_get_req(fm, true);
57012597287SMiklos Szeredi 		if (IS_ERR(req))
57112597287SMiklos Szeredi 			return PTR_ERR(req);
57212597287SMiklos Szeredi 	}
57312597287SMiklos Szeredi 
57412597287SMiklos Szeredi 	fuse_args_to_req(req, args);
57512597287SMiklos Szeredi 
5768f622e94SMax Reitz 	if (!fuse_request_queue_background(req)) {
5778f622e94SMax Reitz 		fuse_put_request(req);
57812597287SMiklos Szeredi 		return -ENOTCONN;
57912597287SMiklos Szeredi 	}
58012597287SMiklos Szeredi 
58112597287SMiklos Szeredi 	return 0;
58212597287SMiklos Szeredi }
58312597287SMiklos Szeredi EXPORT_SYMBOL_GPL(fuse_simple_background);
58412597287SMiklos Szeredi 
585fcee216bSMax Reitz static int fuse_simple_notify_reply(struct fuse_mount *fm,
58675b399ddSMiklos Szeredi 				    struct fuse_args *args, u64 unique)
5872d45ba38SMiklos Szeredi {
58875b399ddSMiklos Szeredi 	struct fuse_req *req;
589fcee216bSMax Reitz 	struct fuse_iqueue *fiq = &fm->fc->iq;
59075b399ddSMiklos Szeredi 	int err = 0;
59175b399ddSMiklos Szeredi 
592fcee216bSMax Reitz 	req = fuse_get_req(fm, false);
59375b399ddSMiklos Szeredi 	if (IS_ERR(req))
59475b399ddSMiklos Szeredi 		return PTR_ERR(req);
5952d45ba38SMiklos Szeredi 
596825d6d33SMiklos Szeredi 	__clear_bit(FR_ISREPLY, &req->flags);
5972d45ba38SMiklos Szeredi 	req->in.h.unique = unique;
59875b399ddSMiklos Szeredi 
59975b399ddSMiklos Szeredi 	fuse_args_to_req(req, args);
60075b399ddSMiklos Szeredi 
60176e43c8cSEric Biggers 	spin_lock(&fiq->lock);
602e16714d8SMiklos Szeredi 	if (fiq->connected) {
603ae3aad77SStefan Hajnoczi 		queue_request_and_unlock(fiq, req);
60475b399ddSMiklos Szeredi 	} else {
60575b399ddSMiklos Szeredi 		err = -ENODEV;
60675b399ddSMiklos Szeredi 		spin_unlock(&fiq->lock);
6078f622e94SMax Reitz 		fuse_put_request(req);
6082d45ba38SMiklos Szeredi 	}
6092d45ba38SMiklos Szeredi 
6102d45ba38SMiklos Szeredi 	return err;
6112d45ba38SMiklos Szeredi }
6122d45ba38SMiklos Szeredi 
6133be5a52bSMiklos Szeredi /*
614334f485dSMiklos Szeredi  * Lock the request.  Up to the next unlock_request() there mustn't be
615334f485dSMiklos Szeredi  * anything that could cause a page-fault.  If the request was already
616f9a2842eSMiklos Szeredi  * aborted bail out.
617334f485dSMiklos Szeredi  */
618dc00809aSMiklos Szeredi static int lock_request(struct fuse_req *req)
619334f485dSMiklos Szeredi {
620334f485dSMiklos Szeredi 	int err = 0;
621334f485dSMiklos Szeredi 	if (req) {
622dc00809aSMiklos Szeredi 		spin_lock(&req->waitq.lock);
623825d6d33SMiklos Szeredi 		if (test_bit(FR_ABORTED, &req->flags))
624334f485dSMiklos Szeredi 			err = -ENOENT;
625334f485dSMiklos Szeredi 		else
626825d6d33SMiklos Szeredi 			set_bit(FR_LOCKED, &req->flags);
627dc00809aSMiklos Szeredi 		spin_unlock(&req->waitq.lock);
628334f485dSMiklos Szeredi 	}
629334f485dSMiklos Szeredi 	return err;
630334f485dSMiklos Szeredi }
631334f485dSMiklos Szeredi 
632334f485dSMiklos Szeredi /*
6330d8e84b0SMiklos Szeredi  * Unlock request.  If it was aborted while locked, caller is responsible
6340d8e84b0SMiklos Szeredi  * for unlocking and ending the request.
635334f485dSMiklos Szeredi  */
636dc00809aSMiklos Szeredi static int unlock_request(struct fuse_req *req)
637334f485dSMiklos Szeredi {
6380d8e84b0SMiklos Szeredi 	int err = 0;
639334f485dSMiklos Szeredi 	if (req) {
640dc00809aSMiklos Szeredi 		spin_lock(&req->waitq.lock);
641825d6d33SMiklos Szeredi 		if (test_bit(FR_ABORTED, &req->flags))
6420d8e84b0SMiklos Szeredi 			err = -ENOENT;
6430d8e84b0SMiklos Szeredi 		else
644825d6d33SMiklos Szeredi 			clear_bit(FR_LOCKED, &req->flags);
645dc00809aSMiklos Szeredi 		spin_unlock(&req->waitq.lock);
646334f485dSMiklos Szeredi 	}
6470d8e84b0SMiklos Szeredi 	return err;
648334f485dSMiklos Szeredi }
649334f485dSMiklos Szeredi 
650334f485dSMiklos Szeredi struct fuse_copy_state {
651334f485dSMiklos Szeredi 	int write;
652334f485dSMiklos Szeredi 	struct fuse_req *req;
6536c09e94aSAl Viro 	struct iov_iter *iter;
654dd3bb14fSMiklos Szeredi 	struct pipe_buffer *pipebufs;
655dd3bb14fSMiklos Szeredi 	struct pipe_buffer *currbuf;
656dd3bb14fSMiklos Szeredi 	struct pipe_inode_info *pipe;
657334f485dSMiklos Szeredi 	unsigned long nr_segs;
658334f485dSMiklos Szeredi 	struct page *pg;
659334f485dSMiklos Szeredi 	unsigned len;
660c55a01d3SMiklos Szeredi 	unsigned offset;
661ce534fb0SMiklos Szeredi 	unsigned move_pages:1;
662334f485dSMiklos Szeredi };
663334f485dSMiklos Szeredi 
664dc00809aSMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, int write,
6656c09e94aSAl Viro 			   struct iov_iter *iter)
666334f485dSMiklos Szeredi {
667334f485dSMiklos Szeredi 	memset(cs, 0, sizeof(*cs));
668334f485dSMiklos Szeredi 	cs->write = write;
6696c09e94aSAl Viro 	cs->iter = iter;
670334f485dSMiklos Szeredi }
671334f485dSMiklos Szeredi 
672334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */
6738bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs)
674334f485dSMiklos Szeredi {
675dd3bb14fSMiklos Szeredi 	if (cs->currbuf) {
676dd3bb14fSMiklos Szeredi 		struct pipe_buffer *buf = cs->currbuf;
677dd3bb14fSMiklos Szeredi 
678c55a01d3SMiklos Szeredi 		if (cs->write)
679c3021629SMiklos Szeredi 			buf->len = PAGE_SIZE - cs->len;
680dd3bb14fSMiklos Szeredi 		cs->currbuf = NULL;
681c55a01d3SMiklos Szeredi 	} else if (cs->pg) {
682334f485dSMiklos Szeredi 		if (cs->write) {
683334f485dSMiklos Szeredi 			flush_dcache_page(cs->pg);
684334f485dSMiklos Szeredi 			set_page_dirty_lock(cs->pg);
685334f485dSMiklos Szeredi 		}
686334f485dSMiklos Szeredi 		put_page(cs->pg);
687334f485dSMiklos Szeredi 	}
688c55a01d3SMiklos Szeredi 	cs->pg = NULL;
689334f485dSMiklos Szeredi }
690334f485dSMiklos Szeredi 
691334f485dSMiklos Szeredi /*
692334f485dSMiklos Szeredi  * Get another pagefull of userspace buffer, and map it to kernel
693334f485dSMiklos Szeredi  * address space, and lock request
694334f485dSMiklos Szeredi  */
695334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs)
696334f485dSMiklos Szeredi {
697c55a01d3SMiklos Szeredi 	struct page *page;
698334f485dSMiklos Szeredi 	int err;
699334f485dSMiklos Szeredi 
700dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
7010d8e84b0SMiklos Szeredi 	if (err)
7020d8e84b0SMiklos Szeredi 		return err;
7030d8e84b0SMiklos Szeredi 
704334f485dSMiklos Szeredi 	fuse_copy_finish(cs);
705dd3bb14fSMiklos Szeredi 	if (cs->pipebufs) {
706dd3bb14fSMiklos Szeredi 		struct pipe_buffer *buf = cs->pipebufs;
707dd3bb14fSMiklos Szeredi 
708c3021629SMiklos Szeredi 		if (!cs->write) {
709fba597dbSMiklos Szeredi 			err = pipe_buf_confirm(cs->pipe, buf);
710dd3bb14fSMiklos Szeredi 			if (err)
711dd3bb14fSMiklos Szeredi 				return err;
712dd3bb14fSMiklos Szeredi 
713dd3bb14fSMiklos Szeredi 			BUG_ON(!cs->nr_segs);
714dd3bb14fSMiklos Szeredi 			cs->currbuf = buf;
715c55a01d3SMiklos Szeredi 			cs->pg = buf->page;
716c55a01d3SMiklos Szeredi 			cs->offset = buf->offset;
717dd3bb14fSMiklos Szeredi 			cs->len = buf->len;
718dd3bb14fSMiklos Szeredi 			cs->pipebufs++;
719dd3bb14fSMiklos Szeredi 			cs->nr_segs--;
720dd3bb14fSMiklos Szeredi 		} else {
7216718b6f8SDavid Howells 			if (cs->nr_segs >= cs->pipe->max_usage)
722c3021629SMiklos Szeredi 				return -EIO;
723c3021629SMiklos Szeredi 
724c3021629SMiklos Szeredi 			page = alloc_page(GFP_HIGHUSER);
725c3021629SMiklos Szeredi 			if (!page)
726c3021629SMiklos Szeredi 				return -ENOMEM;
727c3021629SMiklos Szeredi 
728c3021629SMiklos Szeredi 			buf->page = page;
729c3021629SMiklos Szeredi 			buf->offset = 0;
730c3021629SMiklos Szeredi 			buf->len = 0;
731c3021629SMiklos Szeredi 
732c3021629SMiklos Szeredi 			cs->currbuf = buf;
733c55a01d3SMiklos Szeredi 			cs->pg = page;
734c55a01d3SMiklos Szeredi 			cs->offset = 0;
735c3021629SMiklos Szeredi 			cs->len = PAGE_SIZE;
736c3021629SMiklos Szeredi 			cs->pipebufs++;
737c3021629SMiklos Szeredi 			cs->nr_segs++;
738c3021629SMiklos Szeredi 		}
739c3021629SMiklos Szeredi 	} else {
7406c09e94aSAl Viro 		size_t off;
7416c09e94aSAl Viro 		err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off);
742334f485dSMiklos Szeredi 		if (err < 0)
743334f485dSMiklos Szeredi 			return err;
7446c09e94aSAl Viro 		BUG_ON(!err);
7456c09e94aSAl Viro 		cs->len = err;
7466c09e94aSAl Viro 		cs->offset = off;
747c55a01d3SMiklos Szeredi 		cs->pg = page;
7486c09e94aSAl Viro 		iov_iter_advance(cs->iter, err);
749dd3bb14fSMiklos Szeredi 	}
750334f485dSMiklos Szeredi 
751dc00809aSMiklos Szeredi 	return lock_request(cs->req);
752334f485dSMiklos Szeredi }
753334f485dSMiklos Szeredi 
754334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */
7558bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
756334f485dSMiklos Szeredi {
757334f485dSMiklos Szeredi 	unsigned ncpy = min(*size, cs->len);
758334f485dSMiklos Szeredi 	if (val) {
759c55a01d3SMiklos Szeredi 		void *pgaddr = kmap_atomic(cs->pg);
760c55a01d3SMiklos Szeredi 		void *buf = pgaddr + cs->offset;
761c55a01d3SMiklos Szeredi 
762334f485dSMiklos Szeredi 		if (cs->write)
763c55a01d3SMiklos Szeredi 			memcpy(buf, *val, ncpy);
764334f485dSMiklos Szeredi 		else
765c55a01d3SMiklos Szeredi 			memcpy(*val, buf, ncpy);
766c55a01d3SMiklos Szeredi 
767c55a01d3SMiklos Szeredi 		kunmap_atomic(pgaddr);
768334f485dSMiklos Szeredi 		*val += ncpy;
769334f485dSMiklos Szeredi 	}
770334f485dSMiklos Szeredi 	*size -= ncpy;
771334f485dSMiklos Szeredi 	cs->len -= ncpy;
772c55a01d3SMiklos Szeredi 	cs->offset += ncpy;
773334f485dSMiklos Szeredi 	return ncpy;
774334f485dSMiklos Szeredi }
775334f485dSMiklos Szeredi 
776ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page)
777ce534fb0SMiklos Szeredi {
778ce534fb0SMiklos Szeredi 	if (page_mapcount(page) ||
779ce534fb0SMiklos Szeredi 	    page->mapping != NULL ||
780ce534fb0SMiklos Szeredi 	    (page->flags & PAGE_FLAGS_CHECK_AT_PREP &
781ce534fb0SMiklos Szeredi 	     ~(1 << PG_locked |
782ce534fb0SMiklos Szeredi 	       1 << PG_referenced |
783ce534fb0SMiklos Szeredi 	       1 << PG_uptodate |
784ce534fb0SMiklos Szeredi 	       1 << PG_lru |
785ce534fb0SMiklos Szeredi 	       1 << PG_active |
786b89ecd60SMiklos Szeredi 	       1 << PG_workingset |
787a5005c3cSMiklos Szeredi 	       1 << PG_reclaim |
788a5005c3cSMiklos Szeredi 	       1 << PG_waiters))) {
78900589386SMiklos Szeredi 		dump_page(page, "fuse: trying to steal weird page");
790ce534fb0SMiklos Szeredi 		return 1;
791ce534fb0SMiklos Szeredi 	}
792ce534fb0SMiklos Szeredi 	return 0;
793ce534fb0SMiklos Szeredi }
794ce534fb0SMiklos Szeredi 
795ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
796ce534fb0SMiklos Szeredi {
797ce534fb0SMiklos Szeredi 	int err;
798ce534fb0SMiklos Szeredi 	struct page *oldpage = *pagep;
799ce534fb0SMiklos Szeredi 	struct page *newpage;
800ce534fb0SMiklos Szeredi 	struct pipe_buffer *buf = cs->pipebufs;
801ce534fb0SMiklos Szeredi 
802d78092e4SMiklos Szeredi 	get_page(oldpage);
803dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
8040d8e84b0SMiklos Szeredi 	if (err)
805d78092e4SMiklos Szeredi 		goto out_put_old;
8060d8e84b0SMiklos Szeredi 
807ce534fb0SMiklos Szeredi 	fuse_copy_finish(cs);
808ce534fb0SMiklos Szeredi 
809fba597dbSMiklos Szeredi 	err = pipe_buf_confirm(cs->pipe, buf);
810ce534fb0SMiklos Szeredi 	if (err)
811d78092e4SMiklos Szeredi 		goto out_put_old;
812ce534fb0SMiklos Szeredi 
813ce534fb0SMiklos Szeredi 	BUG_ON(!cs->nr_segs);
814ce534fb0SMiklos Szeredi 	cs->currbuf = buf;
815ce534fb0SMiklos Szeredi 	cs->len = buf->len;
816ce534fb0SMiklos Szeredi 	cs->pipebufs++;
817ce534fb0SMiklos Szeredi 	cs->nr_segs--;
818ce534fb0SMiklos Szeredi 
819ce534fb0SMiklos Szeredi 	if (cs->len != PAGE_SIZE)
820ce534fb0SMiklos Szeredi 		goto out_fallback;
821ce534fb0SMiklos Szeredi 
822c928f642SChristoph Hellwig 	if (!pipe_buf_try_steal(cs->pipe, buf))
823ce534fb0SMiklos Szeredi 		goto out_fallback;
824ce534fb0SMiklos Szeredi 
825ce534fb0SMiklos Szeredi 	newpage = buf->page;
826ce534fb0SMiklos Szeredi 
827aa991b3bSMiklos Szeredi 	if (!PageUptodate(newpage))
828aa991b3bSMiklos Szeredi 		SetPageUptodate(newpage);
829ce534fb0SMiklos Szeredi 
830ce534fb0SMiklos Szeredi 	ClearPageMappedToDisk(newpage);
831ce534fb0SMiklos Szeredi 
832ce534fb0SMiklos Szeredi 	if (fuse_check_page(newpage) != 0)
833ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
834ce534fb0SMiklos Szeredi 
835ce534fb0SMiklos Szeredi 	/*
836ce534fb0SMiklos Szeredi 	 * This is a new and locked page, it shouldn't be mapped or
837ce534fb0SMiklos Szeredi 	 * have any special flags on it
838ce534fb0SMiklos Szeredi 	 */
839ce534fb0SMiklos Szeredi 	if (WARN_ON(page_mapped(oldpage)))
840ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
841ce534fb0SMiklos Szeredi 	if (WARN_ON(page_has_private(oldpage)))
842ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
843ce534fb0SMiklos Szeredi 	if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage)))
844ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
845ce534fb0SMiklos Szeredi 	if (WARN_ON(PageMlocked(oldpage)))
846ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
847ce534fb0SMiklos Szeredi 
8481f7ef657SBaolin Wang 	replace_page_cache_page(oldpage, newpage);
849ef6a3c63SMiklos Szeredi 
85009cbfeafSKirill A. Shutemov 	get_page(newpage);
851ce534fb0SMiklos Szeredi 
852ce534fb0SMiklos Szeredi 	if (!(buf->flags & PIPE_BUF_FLAG_LRU))
8536058eaecSJohannes Weiner 		lru_cache_add(newpage);
854ce534fb0SMiklos Szeredi 
855ce534fb0SMiklos Szeredi 	err = 0;
856dc00809aSMiklos Szeredi 	spin_lock(&cs->req->waitq.lock);
857825d6d33SMiklos Szeredi 	if (test_bit(FR_ABORTED, &cs->req->flags))
858ce534fb0SMiklos Szeredi 		err = -ENOENT;
859ce534fb0SMiklos Szeredi 	else
860ce534fb0SMiklos Szeredi 		*pagep = newpage;
861dc00809aSMiklos Szeredi 	spin_unlock(&cs->req->waitq.lock);
862ce534fb0SMiklos Szeredi 
863ce534fb0SMiklos Szeredi 	if (err) {
864ce534fb0SMiklos Szeredi 		unlock_page(newpage);
86509cbfeafSKirill A. Shutemov 		put_page(newpage);
866d78092e4SMiklos Szeredi 		goto out_put_old;
867ce534fb0SMiklos Szeredi 	}
868ce534fb0SMiklos Szeredi 
869ce534fb0SMiklos Szeredi 	unlock_page(oldpage);
870d78092e4SMiklos Szeredi 	/* Drop ref for ap->pages[] array */
87109cbfeafSKirill A. Shutemov 	put_page(oldpage);
872ce534fb0SMiklos Szeredi 	cs->len = 0;
873ce534fb0SMiklos Szeredi 
874d78092e4SMiklos Szeredi 	err = 0;
875d78092e4SMiklos Szeredi out_put_old:
876d78092e4SMiklos Szeredi 	/* Drop ref obtained in this function */
877d78092e4SMiklos Szeredi 	put_page(oldpage);
878d78092e4SMiklos Szeredi 	return err;
879ce534fb0SMiklos Szeredi 
880ce534fb0SMiklos Szeredi out_fallback_unlock:
881ce534fb0SMiklos Szeredi 	unlock_page(newpage);
882ce534fb0SMiklos Szeredi out_fallback:
883c55a01d3SMiklos Szeredi 	cs->pg = buf->page;
884c55a01d3SMiklos Szeredi 	cs->offset = buf->offset;
885ce534fb0SMiklos Szeredi 
886dc00809aSMiklos Szeredi 	err = lock_request(cs->req);
887d78092e4SMiklos Szeredi 	if (!err)
888d78092e4SMiklos Szeredi 		err = 1;
889ce534fb0SMiklos Szeredi 
890d78092e4SMiklos Szeredi 	goto out_put_old;
891ce534fb0SMiklos Szeredi }
892ce534fb0SMiklos Szeredi 
893c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
894c3021629SMiklos Szeredi 			 unsigned offset, unsigned count)
895c3021629SMiklos Szeredi {
896c3021629SMiklos Szeredi 	struct pipe_buffer *buf;
8970d8e84b0SMiklos Szeredi 	int err;
898c3021629SMiklos Szeredi 
8996718b6f8SDavid Howells 	if (cs->nr_segs >= cs->pipe->max_usage)
900c3021629SMiklos Szeredi 		return -EIO;
901c3021629SMiklos Szeredi 
902d78092e4SMiklos Szeredi 	get_page(page);
903dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
904d78092e4SMiklos Szeredi 	if (err) {
905d78092e4SMiklos Szeredi 		put_page(page);
9060d8e84b0SMiklos Szeredi 		return err;
907d78092e4SMiklos Szeredi 	}
9080d8e84b0SMiklos Szeredi 
909c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
910c3021629SMiklos Szeredi 
911c3021629SMiklos Szeredi 	buf = cs->pipebufs;
912c3021629SMiklos Szeredi 	buf->page = page;
913c3021629SMiklos Szeredi 	buf->offset = offset;
914c3021629SMiklos Szeredi 	buf->len = count;
915c3021629SMiklos Szeredi 
916c3021629SMiklos Szeredi 	cs->pipebufs++;
917c3021629SMiklos Szeredi 	cs->nr_segs++;
918c3021629SMiklos Szeredi 	cs->len = 0;
919c3021629SMiklos Szeredi 
920c3021629SMiklos Szeredi 	return 0;
921c3021629SMiklos Szeredi }
922c3021629SMiklos Szeredi 
923334f485dSMiklos Szeredi /*
924334f485dSMiklos Szeredi  * Copy a page in the request to/from the userspace buffer.  Must be
925334f485dSMiklos Szeredi  * done atomically
926334f485dSMiklos Szeredi  */
927ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
928334f485dSMiklos Szeredi 			  unsigned offset, unsigned count, int zeroing)
929334f485dSMiklos Szeredi {
930ce534fb0SMiklos Szeredi 	int err;
931ce534fb0SMiklos Szeredi 	struct page *page = *pagep;
932ce534fb0SMiklos Szeredi 
933b6777c40SMiklos Szeredi 	if (page && zeroing && count < PAGE_SIZE)
934b6777c40SMiklos Szeredi 		clear_highpage(page);
935b6777c40SMiklos Szeredi 
936334f485dSMiklos Szeredi 	while (count) {
937c3021629SMiklos Szeredi 		if (cs->write && cs->pipebufs && page) {
938c3021629SMiklos Szeredi 			return fuse_ref_page(cs, page, offset, count);
939c3021629SMiklos Szeredi 		} else if (!cs->len) {
940ce534fb0SMiklos Szeredi 			if (cs->move_pages && page &&
941ce534fb0SMiklos Szeredi 			    offset == 0 && count == PAGE_SIZE) {
942ce534fb0SMiklos Szeredi 				err = fuse_try_move_page(cs, pagep);
943ce534fb0SMiklos Szeredi 				if (err <= 0)
944ce534fb0SMiklos Szeredi 					return err;
945ce534fb0SMiklos Szeredi 			} else {
946ce534fb0SMiklos Szeredi 				err = fuse_copy_fill(cs);
9471729a16cSMiklos Szeredi 				if (err)
948334f485dSMiklos Szeredi 					return err;
9491729a16cSMiklos Szeredi 			}
950ce534fb0SMiklos Szeredi 		}
951334f485dSMiklos Szeredi 		if (page) {
9522408f6efSCong Wang 			void *mapaddr = kmap_atomic(page);
953334f485dSMiklos Szeredi 			void *buf = mapaddr + offset;
954334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, &buf, &count);
9552408f6efSCong Wang 			kunmap_atomic(mapaddr);
956334f485dSMiklos Szeredi 		} else
957334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, NULL, &count);
958334f485dSMiklos Szeredi 	}
959334f485dSMiklos Szeredi 	if (page && !cs->write)
960334f485dSMiklos Szeredi 		flush_dcache_page(page);
961334f485dSMiklos Szeredi 	return 0;
962334f485dSMiklos Szeredi }
963334f485dSMiklos Szeredi 
964334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */
965334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
966334f485dSMiklos Szeredi 			   int zeroing)
967334f485dSMiklos Szeredi {
968334f485dSMiklos Szeredi 	unsigned i;
969334f485dSMiklos Szeredi 	struct fuse_req *req = cs->req;
97005ea48ccSMiklos Szeredi 	struct fuse_args_pages *ap = container_of(req->args, typeof(*ap), args);
971334f485dSMiklos Szeredi 
97205ea48ccSMiklos Szeredi 
97305ea48ccSMiklos Szeredi 	for (i = 0; i < ap->num_pages && (nbytes || zeroing); i++) {
974ce534fb0SMiklos Szeredi 		int err;
97505ea48ccSMiklos Szeredi 		unsigned int offset = ap->descs[i].offset;
97605ea48ccSMiklos Szeredi 		unsigned int count = min(nbytes, ap->descs[i].length);
977ce534fb0SMiklos Szeredi 
97805ea48ccSMiklos Szeredi 		err = fuse_copy_page(cs, &ap->pages[i], offset, count, zeroing);
979334f485dSMiklos Szeredi 		if (err)
980334f485dSMiklos Szeredi 			return err;
981334f485dSMiklos Szeredi 
982334f485dSMiklos Szeredi 		nbytes -= count;
983334f485dSMiklos Szeredi 	}
984334f485dSMiklos Szeredi 	return 0;
985334f485dSMiklos Szeredi }
986334f485dSMiklos Szeredi 
987334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */
988334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
989334f485dSMiklos Szeredi {
990334f485dSMiklos Szeredi 	while (size) {
9911729a16cSMiklos Szeredi 		if (!cs->len) {
9921729a16cSMiklos Szeredi 			int err = fuse_copy_fill(cs);
9931729a16cSMiklos Szeredi 			if (err)
994334f485dSMiklos Szeredi 				return err;
9951729a16cSMiklos Szeredi 		}
996334f485dSMiklos Szeredi 		fuse_copy_do(cs, &val, &size);
997334f485dSMiklos Szeredi 	}
998334f485dSMiklos Szeredi 	return 0;
999334f485dSMiklos Szeredi }
1000334f485dSMiklos Szeredi 
1001334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */
1002334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
1003334f485dSMiklos Szeredi 			  unsigned argpages, struct fuse_arg *args,
1004334f485dSMiklos Szeredi 			  int zeroing)
1005334f485dSMiklos Szeredi {
1006334f485dSMiklos Szeredi 	int err = 0;
1007334f485dSMiklos Szeredi 	unsigned i;
1008334f485dSMiklos Szeredi 
1009334f485dSMiklos Szeredi 	for (i = 0; !err && i < numargs; i++)  {
1010334f485dSMiklos Szeredi 		struct fuse_arg *arg = &args[i];
1011334f485dSMiklos Szeredi 		if (i == numargs - 1 && argpages)
1012334f485dSMiklos Szeredi 			err = fuse_copy_pages(cs, arg->size, zeroing);
1013334f485dSMiklos Szeredi 		else
1014334f485dSMiklos Szeredi 			err = fuse_copy_one(cs, arg->value, arg->size);
1015334f485dSMiklos Szeredi 	}
1016334f485dSMiklos Szeredi 	return err;
1017334f485dSMiklos Szeredi }
1018334f485dSMiklos Szeredi 
1019f88996a9SMiklos Szeredi static int forget_pending(struct fuse_iqueue *fiq)
102007e77dcaSMiklos Szeredi {
1021f88996a9SMiklos Szeredi 	return fiq->forget_list_head.next != NULL;
102207e77dcaSMiklos Szeredi }
102307e77dcaSMiklos Szeredi 
1024f88996a9SMiklos Szeredi static int request_pending(struct fuse_iqueue *fiq)
1025a4d27e75SMiklos Szeredi {
1026f88996a9SMiklos Szeredi 	return !list_empty(&fiq->pending) || !list_empty(&fiq->interrupts) ||
1027f88996a9SMiklos Szeredi 		forget_pending(fiq);
1028a4d27e75SMiklos Szeredi }
1029a4d27e75SMiklos Szeredi 
1030334f485dSMiklos Szeredi /*
1031a4d27e75SMiklos Szeredi  * Transfer an interrupt request to userspace
1032a4d27e75SMiklos Szeredi  *
1033a4d27e75SMiklos Szeredi  * Unlike other requests this is assembled on demand, without a need
1034a4d27e75SMiklos Szeredi  * to allocate a separate fuse_req structure.
1035a4d27e75SMiklos Szeredi  *
103676e43c8cSEric Biggers  * Called with fiq->lock held, releases it
1037a4d27e75SMiklos Szeredi  */
1038fd22d62eSMiklos Szeredi static int fuse_read_interrupt(struct fuse_iqueue *fiq,
1039fd22d62eSMiklos Szeredi 			       struct fuse_copy_state *cs,
1040c3021629SMiklos Szeredi 			       size_t nbytes, struct fuse_req *req)
104176e43c8cSEric Biggers __releases(fiq->lock)
1042a4d27e75SMiklos Szeredi {
1043a4d27e75SMiklos Szeredi 	struct fuse_in_header ih;
1044a4d27e75SMiklos Szeredi 	struct fuse_interrupt_in arg;
1045a4d27e75SMiklos Szeredi 	unsigned reqsize = sizeof(ih) + sizeof(arg);
1046a4d27e75SMiklos Szeredi 	int err;
1047a4d27e75SMiklos Szeredi 
1048a4d27e75SMiklos Szeredi 	list_del_init(&req->intr_entry);
1049a4d27e75SMiklos Szeredi 	memset(&ih, 0, sizeof(ih));
1050a4d27e75SMiklos Szeredi 	memset(&arg, 0, sizeof(arg));
1051a4d27e75SMiklos Szeredi 	ih.len = reqsize;
1052a4d27e75SMiklos Szeredi 	ih.opcode = FUSE_INTERRUPT;
10533a5358d1SKirill Tkhai 	ih.unique = (req->in.h.unique | FUSE_INT_REQ_BIT);
1054a4d27e75SMiklos Szeredi 	arg.unique = req->in.h.unique;
1055a4d27e75SMiklos Szeredi 
105676e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
1057c3021629SMiklos Szeredi 	if (nbytes < reqsize)
1058a4d27e75SMiklos Szeredi 		return -EINVAL;
1059a4d27e75SMiklos Szeredi 
1060c3021629SMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
1061a4d27e75SMiklos Szeredi 	if (!err)
1062c3021629SMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
1063c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
1064a4d27e75SMiklos Szeredi 
1065a4d27e75SMiklos Szeredi 	return err ? err : reqsize;
1066a4d27e75SMiklos Szeredi }
1067a4d27e75SMiklos Szeredi 
10684388c5aaSVivek Goyal struct fuse_forget_link *fuse_dequeue_forget(struct fuse_iqueue *fiq,
10694388c5aaSVivek Goyal 					     unsigned int max,
10704388c5aaSVivek Goyal 					     unsigned int *countp)
107107e77dcaSMiklos Szeredi {
1072f88996a9SMiklos Szeredi 	struct fuse_forget_link *head = fiq->forget_list_head.next;
107302c048b9SMiklos Szeredi 	struct fuse_forget_link **newhead = &head;
107402c048b9SMiklos Szeredi 	unsigned count;
107507e77dcaSMiklos Szeredi 
107602c048b9SMiklos Szeredi 	for (count = 0; *newhead != NULL && count < max; count++)
107702c048b9SMiklos Szeredi 		newhead = &(*newhead)->next;
107802c048b9SMiklos Szeredi 
1079f88996a9SMiklos Szeredi 	fiq->forget_list_head.next = *newhead;
108002c048b9SMiklos Szeredi 	*newhead = NULL;
1081f88996a9SMiklos Szeredi 	if (fiq->forget_list_head.next == NULL)
1082f88996a9SMiklos Szeredi 		fiq->forget_list_tail = &fiq->forget_list_head;
108307e77dcaSMiklos Szeredi 
108402c048b9SMiklos Szeredi 	if (countp != NULL)
108502c048b9SMiklos Szeredi 		*countp = count;
108602c048b9SMiklos Szeredi 
108702c048b9SMiklos Szeredi 	return head;
108807e77dcaSMiklos Szeredi }
10894388c5aaSVivek Goyal EXPORT_SYMBOL(fuse_dequeue_forget);
109007e77dcaSMiklos Szeredi 
1091fd22d62eSMiklos Szeredi static int fuse_read_single_forget(struct fuse_iqueue *fiq,
109207e77dcaSMiklos Szeredi 				   struct fuse_copy_state *cs,
109307e77dcaSMiklos Szeredi 				   size_t nbytes)
109476e43c8cSEric Biggers __releases(fiq->lock)
109507e77dcaSMiklos Szeredi {
109607e77dcaSMiklos Szeredi 	int err;
10974388c5aaSVivek Goyal 	struct fuse_forget_link *forget = fuse_dequeue_forget(fiq, 1, NULL);
109807e77dcaSMiklos Szeredi 	struct fuse_forget_in arg = {
109902c048b9SMiklos Szeredi 		.nlookup = forget->forget_one.nlookup,
110007e77dcaSMiklos Szeredi 	};
110107e77dcaSMiklos Szeredi 	struct fuse_in_header ih = {
110207e77dcaSMiklos Szeredi 		.opcode = FUSE_FORGET,
110302c048b9SMiklos Szeredi 		.nodeid = forget->forget_one.nodeid,
1104f88996a9SMiklos Szeredi 		.unique = fuse_get_unique(fiq),
110507e77dcaSMiklos Szeredi 		.len = sizeof(ih) + sizeof(arg),
110607e77dcaSMiklos Szeredi 	};
110707e77dcaSMiklos Szeredi 
110876e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
110907e77dcaSMiklos Szeredi 	kfree(forget);
111007e77dcaSMiklos Szeredi 	if (nbytes < ih.len)
111107e77dcaSMiklos Szeredi 		return -EINVAL;
111207e77dcaSMiklos Szeredi 
111307e77dcaSMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
111407e77dcaSMiklos Szeredi 	if (!err)
111507e77dcaSMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
111607e77dcaSMiklos Szeredi 	fuse_copy_finish(cs);
111707e77dcaSMiklos Szeredi 
111807e77dcaSMiklos Szeredi 	if (err)
111907e77dcaSMiklos Szeredi 		return err;
112007e77dcaSMiklos Szeredi 
112107e77dcaSMiklos Szeredi 	return ih.len;
112207e77dcaSMiklos Szeredi }
112307e77dcaSMiklos Szeredi 
1124fd22d62eSMiklos Szeredi static int fuse_read_batch_forget(struct fuse_iqueue *fiq,
112502c048b9SMiklos Szeredi 				   struct fuse_copy_state *cs, size_t nbytes)
112676e43c8cSEric Biggers __releases(fiq->lock)
112702c048b9SMiklos Szeredi {
112802c048b9SMiklos Szeredi 	int err;
112902c048b9SMiklos Szeredi 	unsigned max_forgets;
113002c048b9SMiklos Szeredi 	unsigned count;
113102c048b9SMiklos Szeredi 	struct fuse_forget_link *head;
113202c048b9SMiklos Szeredi 	struct fuse_batch_forget_in arg = { .count = 0 };
113302c048b9SMiklos Szeredi 	struct fuse_in_header ih = {
113402c048b9SMiklos Szeredi 		.opcode = FUSE_BATCH_FORGET,
1135f88996a9SMiklos Szeredi 		.unique = fuse_get_unique(fiq),
113602c048b9SMiklos Szeredi 		.len = sizeof(ih) + sizeof(arg),
113702c048b9SMiklos Szeredi 	};
113802c048b9SMiklos Szeredi 
113902c048b9SMiklos Szeredi 	if (nbytes < ih.len) {
114076e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
114102c048b9SMiklos Szeredi 		return -EINVAL;
114202c048b9SMiklos Szeredi 	}
114302c048b9SMiklos Szeredi 
114402c048b9SMiklos Szeredi 	max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one);
11454388c5aaSVivek Goyal 	head = fuse_dequeue_forget(fiq, max_forgets, &count);
114676e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
114702c048b9SMiklos Szeredi 
114802c048b9SMiklos Szeredi 	arg.count = count;
114902c048b9SMiklos Szeredi 	ih.len += count * sizeof(struct fuse_forget_one);
115002c048b9SMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
115102c048b9SMiklos Szeredi 	if (!err)
115202c048b9SMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
115302c048b9SMiklos Szeredi 
115402c048b9SMiklos Szeredi 	while (head) {
115502c048b9SMiklos Szeredi 		struct fuse_forget_link *forget = head;
115602c048b9SMiklos Szeredi 
115702c048b9SMiklos Szeredi 		if (!err) {
115802c048b9SMiklos Szeredi 			err = fuse_copy_one(cs, &forget->forget_one,
115902c048b9SMiklos Szeredi 					    sizeof(forget->forget_one));
116002c048b9SMiklos Szeredi 		}
116102c048b9SMiklos Szeredi 		head = forget->next;
116202c048b9SMiklos Szeredi 		kfree(forget);
116302c048b9SMiklos Szeredi 	}
116402c048b9SMiklos Szeredi 
116502c048b9SMiklos Szeredi 	fuse_copy_finish(cs);
116602c048b9SMiklos Szeredi 
116702c048b9SMiklos Szeredi 	if (err)
116802c048b9SMiklos Szeredi 		return err;
116902c048b9SMiklos Szeredi 
117002c048b9SMiklos Szeredi 	return ih.len;
117102c048b9SMiklos Szeredi }
117202c048b9SMiklos Szeredi 
1173fd22d62eSMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq,
1174fd22d62eSMiklos Szeredi 			    struct fuse_copy_state *cs,
117502c048b9SMiklos Szeredi 			    size_t nbytes)
117676e43c8cSEric Biggers __releases(fiq->lock)
117702c048b9SMiklos Szeredi {
1178f88996a9SMiklos Szeredi 	if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL)
1179fd22d62eSMiklos Szeredi 		return fuse_read_single_forget(fiq, cs, nbytes);
118002c048b9SMiklos Szeredi 	else
1181fd22d62eSMiklos Szeredi 		return fuse_read_batch_forget(fiq, cs, nbytes);
118202c048b9SMiklos Szeredi }
118302c048b9SMiklos Szeredi 
1184a4d27e75SMiklos Szeredi /*
1185334f485dSMiklos Szeredi  * Read a single request into the userspace filesystem's buffer.  This
1186334f485dSMiklos Szeredi  * function waits until a request is available, then removes it from
1187334f485dSMiklos Szeredi  * the pending list and copies request data to userspace buffer.  If
1188f9a2842eSMiklos Szeredi  * no reply is needed (FORGET) or request has been aborted or there
1189f9a2842eSMiklos Szeredi  * was an error during the copying then it's finished by calling
119004ec5af0SStefan Hajnoczi  * fuse_request_end().  Otherwise add it to the processing list, and set
1191334f485dSMiklos Szeredi  * the 'sent' flag.
1192334f485dSMiklos Szeredi  */
1193c3696046SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
1194c3021629SMiklos Szeredi 				struct fuse_copy_state *cs, size_t nbytes)
1195334f485dSMiklos Szeredi {
119682cbdcd3SMiklos Szeredi 	ssize_t err;
1197c3696046SMiklos Szeredi 	struct fuse_conn *fc = fud->fc;
1198f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
1199c3696046SMiklos Szeredi 	struct fuse_pqueue *fpq = &fud->pq;
1200334f485dSMiklos Szeredi 	struct fuse_req *req;
1201d4993774SMiklos Szeredi 	struct fuse_args *args;
1202334f485dSMiklos Szeredi 	unsigned reqsize;
1203be2ff42cSKirill Tkhai 	unsigned int hash;
1204334f485dSMiklos Szeredi 
12051fb027d7SKirill Smelkov 	/*
12061fb027d7SKirill Smelkov 	 * Require sane minimum read buffer - that has capacity for fixed part
12071fb027d7SKirill Smelkov 	 * of any request header + negotiated max_write room for data.
12081fb027d7SKirill Smelkov 	 *
12091fb027d7SKirill Smelkov 	 * Historically libfuse reserves 4K for fixed header room, but e.g.
12101fb027d7SKirill Smelkov 	 * GlusterFS reserves only 80 bytes
12111fb027d7SKirill Smelkov 	 *
12121fb027d7SKirill Smelkov 	 *	= `sizeof(fuse_in_header) + sizeof(fuse_write_in)`
12131fb027d7SKirill Smelkov 	 *
12141fb027d7SKirill Smelkov 	 * which is the absolute minimum any sane filesystem should be using
12151fb027d7SKirill Smelkov 	 * for header room.
12161fb027d7SKirill Smelkov 	 */
12171fb027d7SKirill Smelkov 	if (nbytes < max_t(size_t, FUSE_MIN_READ_BUFFER,
12181fb027d7SKirill Smelkov 			   sizeof(struct fuse_in_header) +
12191fb027d7SKirill Smelkov 			   sizeof(struct fuse_write_in) +
12201fb027d7SKirill Smelkov 			   fc->max_write))
12211fb027d7SKirill Smelkov 		return -EINVAL;
12221fb027d7SKirill Smelkov 
12231d3d752bSMiklos Szeredi  restart:
122476e43c8cSEric Biggers 	for (;;) {
122576e43c8cSEric Biggers 		spin_lock(&fiq->lock);
122676e43c8cSEric Biggers 		if (!fiq->connected || request_pending(fiq))
122776e43c8cSEric Biggers 			break;
122876e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
1229e5ac1d1eSJeff Dike 
123076e43c8cSEric Biggers 		if (file->f_flags & O_NONBLOCK)
123176e43c8cSEric Biggers 			return -EAGAIN;
123276e43c8cSEric Biggers 		err = wait_event_interruptible_exclusive(fiq->waitq,
12335250921bSMiklos Szeredi 				!fiq->connected || request_pending(fiq));
12345250921bSMiklos Szeredi 		if (err)
123576e43c8cSEric Biggers 			return err;
123676e43c8cSEric Biggers 	}
12375250921bSMiklos Szeredi 
12383b7008b2SSzymon Lukasz 	if (!fiq->connected) {
1239eb98e3bdSMiklos Szeredi 		err = fc->aborted ? -ECONNABORTED : -ENODEV;
1240334f485dSMiklos Szeredi 		goto err_unlock;
12413b7008b2SSzymon Lukasz 	}
1242334f485dSMiklos Szeredi 
1243f88996a9SMiklos Szeredi 	if (!list_empty(&fiq->interrupts)) {
1244f88996a9SMiklos Szeredi 		req = list_entry(fiq->interrupts.next, struct fuse_req,
1245a4d27e75SMiklos Szeredi 				 intr_entry);
1246fd22d62eSMiklos Szeredi 		return fuse_read_interrupt(fiq, cs, nbytes, req);
1247a4d27e75SMiklos Szeredi 	}
1248a4d27e75SMiklos Szeredi 
1249f88996a9SMiklos Szeredi 	if (forget_pending(fiq)) {
1250f88996a9SMiklos Szeredi 		if (list_empty(&fiq->pending) || fiq->forget_batch-- > 0)
1251fd22d62eSMiklos Szeredi 			return fuse_read_forget(fc, fiq, cs, nbytes);
125207e77dcaSMiklos Szeredi 
1253f88996a9SMiklos Szeredi 		if (fiq->forget_batch <= -8)
1254f88996a9SMiklos Szeredi 			fiq->forget_batch = 16;
125507e77dcaSMiklos Szeredi 	}
125607e77dcaSMiklos Szeredi 
1257f88996a9SMiklos Szeredi 	req = list_entry(fiq->pending.next, struct fuse_req, list);
125833e14b4dSMiklos Szeredi 	clear_bit(FR_PENDING, &req->flags);
1259ef759258SMiklos Szeredi 	list_del_init(&req->list);
126076e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
12614ce60812SMiklos Szeredi 
1262d4993774SMiklos Szeredi 	args = req->args;
1263d4993774SMiklos Szeredi 	reqsize = req->in.h.len;
12645d6d3a30SMiklos Szeredi 
12651d3d752bSMiklos Szeredi 	/* If request is too large, reply with an error and restart the read */
1266c3021629SMiklos Szeredi 	if (nbytes < reqsize) {
12671d3d752bSMiklos Szeredi 		req->out.h.error = -EIO;
12681d3d752bSMiklos Szeredi 		/* SETXATTR is special, since it may contain too large data */
1269d4993774SMiklos Szeredi 		if (args->opcode == FUSE_SETXATTR)
12701d3d752bSMiklos Szeredi 			req->out.h.error = -E2BIG;
12718f622e94SMax Reitz 		fuse_request_end(req);
12721d3d752bSMiklos Szeredi 		goto restart;
12731d3d752bSMiklos Szeredi 	}
127445a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1275*80ef0867SMiklos Szeredi 	/*
1276*80ef0867SMiklos Szeredi 	 *  Must not put request on fpq->io queue after having been shut down by
1277*80ef0867SMiklos Szeredi 	 *  fuse_abort_conn()
1278*80ef0867SMiklos Szeredi 	 */
1279*80ef0867SMiklos Szeredi 	if (!fpq->connected) {
1280*80ef0867SMiklos Szeredi 		req->out.h.error = err = -ECONNABORTED;
1281*80ef0867SMiklos Szeredi 		goto out_end;
1282*80ef0867SMiklos Szeredi 
1283*80ef0867SMiklos Szeredi 	}
128482cbdcd3SMiklos Szeredi 	list_add(&req->list, &fpq->io);
128545a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1286c3021629SMiklos Szeredi 	cs->req = req;
1287d4993774SMiklos Szeredi 	err = fuse_copy_one(cs, &req->in.h, sizeof(req->in.h));
1288334f485dSMiklos Szeredi 	if (!err)
1289d4993774SMiklos Szeredi 		err = fuse_copy_args(cs, args->in_numargs, args->in_pages,
1290d4993774SMiklos Szeredi 				     (struct fuse_arg *) args->in_args, 0);
1291c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
129245a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1293825d6d33SMiklos Szeredi 	clear_bit(FR_LOCKED, &req->flags);
1294e96edd94SMiklos Szeredi 	if (!fpq->connected) {
1295eb98e3bdSMiklos Szeredi 		err = fc->aborted ? -ECONNABORTED : -ENODEV;
129682cbdcd3SMiklos Szeredi 		goto out_end;
1297c9c9d7dfSMiklos Szeredi 	}
1298334f485dSMiklos Szeredi 	if (err) {
1299334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
130082cbdcd3SMiklos Szeredi 		goto out_end;
1301334f485dSMiklos Szeredi 	}
1302825d6d33SMiklos Szeredi 	if (!test_bit(FR_ISREPLY, &req->flags)) {
130382cbdcd3SMiklos Szeredi 		err = reqsize;
130482cbdcd3SMiklos Szeredi 		goto out_end;
130582cbdcd3SMiklos Szeredi 	}
1306be2ff42cSKirill Tkhai 	hash = fuse_req_hash(req->in.h.unique);
1307be2ff42cSKirill Tkhai 	list_move_tail(&req->list, &fpq->processing[hash]);
1308bc78abbdSKirill Tkhai 	__fuse_get_request(req);
13098f7bb368SMiklos Szeredi 	set_bit(FR_SENT, &req->flags);
13104c316f2fSMiklos Szeredi 	spin_unlock(&fpq->lock);
13118f7bb368SMiklos Szeredi 	/* matches barrier in request_wait_answer() */
13128f7bb368SMiklos Szeredi 	smp_mb__after_atomic();
1313825d6d33SMiklos Szeredi 	if (test_bit(FR_INTERRUPTED, &req->flags))
13148f622e94SMax Reitz 		queue_interrupt(req);
13158f622e94SMax Reitz 	fuse_put_request(req);
131682cbdcd3SMiklos Szeredi 
1317334f485dSMiklos Szeredi 	return reqsize;
1318334f485dSMiklos Szeredi 
131982cbdcd3SMiklos Szeredi out_end:
132077cd9d48SMiklos Szeredi 	if (!test_bit(FR_PRIVATE, &req->flags))
132182cbdcd3SMiklos Szeredi 		list_del_init(&req->list);
132245a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
13238f622e94SMax Reitz 	fuse_request_end(req);
132482cbdcd3SMiklos Szeredi 	return err;
132582cbdcd3SMiklos Szeredi 
1326334f485dSMiklos Szeredi  err_unlock:
132776e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
1328334f485dSMiklos Szeredi 	return err;
1329334f485dSMiklos Szeredi }
1330334f485dSMiklos Szeredi 
133194e4fe2cSTom Van Braeckel static int fuse_dev_open(struct inode *inode, struct file *file)
133294e4fe2cSTom Van Braeckel {
133394e4fe2cSTom Van Braeckel 	/*
133494e4fe2cSTom Van Braeckel 	 * The fuse device's file's private_data is used to hold
133594e4fe2cSTom Van Braeckel 	 * the fuse_conn(ection) when it is mounted, and is used to
133694e4fe2cSTom Van Braeckel 	 * keep track of whether the file has been mounted already.
133794e4fe2cSTom Van Braeckel 	 */
133894e4fe2cSTom Van Braeckel 	file->private_data = NULL;
133994e4fe2cSTom Van Braeckel 	return 0;
134094e4fe2cSTom Van Braeckel }
134194e4fe2cSTom Van Braeckel 
1342fbdbaccaSAl Viro static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to)
1343c3021629SMiklos Szeredi {
1344c3021629SMiklos Szeredi 	struct fuse_copy_state cs;
1345c3021629SMiklos Szeredi 	struct file *file = iocb->ki_filp;
1346cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
1347cc080e9eSMiklos Szeredi 
1348cc080e9eSMiklos Szeredi 	if (!fud)
1349c3021629SMiklos Szeredi 		return -EPERM;
1350c3021629SMiklos Szeredi 
1351fbdbaccaSAl Viro 	if (!iter_is_iovec(to))
1352fbdbaccaSAl Viro 		return -EINVAL;
1353c3021629SMiklos Szeredi 
1354dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 1, to);
1355fbdbaccaSAl Viro 
1356c3696046SMiklos Szeredi 	return fuse_dev_do_read(fud, file, &cs, iov_iter_count(to));
1357c3021629SMiklos Szeredi }
1358c3021629SMiklos Szeredi 
1359c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
1360c3021629SMiklos Szeredi 				    struct pipe_inode_info *pipe,
1361c3021629SMiklos Szeredi 				    size_t len, unsigned int flags)
1362c3021629SMiklos Szeredi {
1363d82718e3SAl Viro 	int total, ret;
1364c3021629SMiklos Szeredi 	int page_nr = 0;
1365c3021629SMiklos Szeredi 	struct pipe_buffer *bufs;
1366c3021629SMiklos Szeredi 	struct fuse_copy_state cs;
1367cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(in);
1368cc080e9eSMiklos Szeredi 
1369cc080e9eSMiklos Szeredi 	if (!fud)
1370c3021629SMiklos Szeredi 		return -EPERM;
1371c3021629SMiklos Szeredi 
13726718b6f8SDavid Howells 	bufs = kvmalloc_array(pipe->max_usage, sizeof(struct pipe_buffer),
13736da2ec56SKees Cook 			      GFP_KERNEL);
1374c3021629SMiklos Szeredi 	if (!bufs)
1375c3021629SMiklos Szeredi 		return -ENOMEM;
1376c3021629SMiklos Szeredi 
1377dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 1, NULL);
1378c3021629SMiklos Szeredi 	cs.pipebufs = bufs;
1379c3021629SMiklos Szeredi 	cs.pipe = pipe;
1380c3696046SMiklos Szeredi 	ret = fuse_dev_do_read(fud, in, &cs, len);
1381c3021629SMiklos Szeredi 	if (ret < 0)
1382c3021629SMiklos Szeredi 		goto out;
1383c3021629SMiklos Szeredi 
13846718b6f8SDavid Howells 	if (pipe_occupancy(pipe->head, pipe->tail) + cs.nr_segs > pipe->max_usage) {
1385c3021629SMiklos Szeredi 		ret = -EIO;
1386d82718e3SAl Viro 		goto out;
1387c3021629SMiklos Szeredi 	}
1388c3021629SMiklos Szeredi 
1389d82718e3SAl Viro 	for (ret = total = 0; page_nr < cs.nr_segs; total += ret) {
139028a625cbSMiklos Szeredi 		/*
139128a625cbSMiklos Szeredi 		 * Need to be careful about this.  Having buf->ops in module
139228a625cbSMiklos Szeredi 		 * code can Oops if the buffer persists after module unload.
139328a625cbSMiklos Szeredi 		 */
1394d82718e3SAl Viro 		bufs[page_nr].ops = &nosteal_pipe_buf_ops;
139584588a93SMiklos Szeredi 		bufs[page_nr].flags = 0;
1396d82718e3SAl Viro 		ret = add_to_pipe(pipe, &bufs[page_nr++]);
1397d82718e3SAl Viro 		if (unlikely(ret < 0))
1398d82718e3SAl Viro 			break;
1399c3021629SMiklos Szeredi 	}
1400d82718e3SAl Viro 	if (total)
1401d82718e3SAl Viro 		ret = total;
1402c3021629SMiklos Szeredi out:
1403c3021629SMiklos Szeredi 	for (; page_nr < cs.nr_segs; page_nr++)
140409cbfeafSKirill A. Shutemov 		put_page(bufs[page_nr].page);
1405c3021629SMiklos Szeredi 
1406d6d931adSAndrey Ryabinin 	kvfree(bufs);
1407c3021629SMiklos Szeredi 	return ret;
1408c3021629SMiklos Szeredi }
1409c3021629SMiklos Szeredi 
141095668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size,
141195668a69STejun Heo 			    struct fuse_copy_state *cs)
141295668a69STejun Heo {
141395668a69STejun Heo 	struct fuse_notify_poll_wakeup_out outarg;
1414f6d47a17SMiklos Szeredi 	int err = -EINVAL;
141595668a69STejun Heo 
141695668a69STejun Heo 	if (size != sizeof(outarg))
1417f6d47a17SMiklos Szeredi 		goto err;
141895668a69STejun Heo 
141995668a69STejun Heo 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
142095668a69STejun Heo 	if (err)
1421f6d47a17SMiklos Szeredi 		goto err;
142295668a69STejun Heo 
1423f6d47a17SMiklos Szeredi 	fuse_copy_finish(cs);
142495668a69STejun Heo 	return fuse_notify_poll_wakeup(fc, &outarg);
1425f6d47a17SMiklos Szeredi 
1426f6d47a17SMiklos Szeredi err:
1427f6d47a17SMiklos Szeredi 	fuse_copy_finish(cs);
1428f6d47a17SMiklos Szeredi 	return err;
142995668a69STejun Heo }
143095668a69STejun Heo 
14313b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size,
14323b463ae0SJohn Muir 				   struct fuse_copy_state *cs)
14333b463ae0SJohn Muir {
14343b463ae0SJohn Muir 	struct fuse_notify_inval_inode_out outarg;
14353b463ae0SJohn Muir 	int err = -EINVAL;
14363b463ae0SJohn Muir 
14373b463ae0SJohn Muir 	if (size != sizeof(outarg))
14383b463ae0SJohn Muir 		goto err;
14393b463ae0SJohn Muir 
14403b463ae0SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
14413b463ae0SJohn Muir 	if (err)
14423b463ae0SJohn Muir 		goto err;
14433b463ae0SJohn Muir 	fuse_copy_finish(cs);
14443b463ae0SJohn Muir 
14453b463ae0SJohn Muir 	down_read(&fc->killsb);
1446fcee216bSMax Reitz 	err = fuse_reverse_inval_inode(fc, outarg.ino,
14473b463ae0SJohn Muir 				       outarg.off, outarg.len);
14483b463ae0SJohn Muir 	up_read(&fc->killsb);
14493b463ae0SJohn Muir 	return err;
14503b463ae0SJohn Muir 
14513b463ae0SJohn Muir err:
14523b463ae0SJohn Muir 	fuse_copy_finish(cs);
14533b463ae0SJohn Muir 	return err;
14543b463ae0SJohn Muir }
14553b463ae0SJohn Muir 
14563b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size,
14573b463ae0SJohn Muir 				   struct fuse_copy_state *cs)
14583b463ae0SJohn Muir {
14593b463ae0SJohn Muir 	struct fuse_notify_inval_entry_out outarg;
1460b2d82ee3SFang Wenqi 	int err = -ENOMEM;
1461b2d82ee3SFang Wenqi 	char *buf;
14623b463ae0SJohn Muir 	struct qstr name;
14633b463ae0SJohn Muir 
1464b2d82ee3SFang Wenqi 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
1465b2d82ee3SFang Wenqi 	if (!buf)
1466b2d82ee3SFang Wenqi 		goto err;
1467b2d82ee3SFang Wenqi 
1468b2d82ee3SFang Wenqi 	err = -EINVAL;
14693b463ae0SJohn Muir 	if (size < sizeof(outarg))
14703b463ae0SJohn Muir 		goto err;
14713b463ae0SJohn Muir 
14723b463ae0SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
14733b463ae0SJohn Muir 	if (err)
14743b463ae0SJohn Muir 		goto err;
14753b463ae0SJohn Muir 
14763b463ae0SJohn Muir 	err = -ENAMETOOLONG;
14773b463ae0SJohn Muir 	if (outarg.namelen > FUSE_NAME_MAX)
14783b463ae0SJohn Muir 		goto err;
14793b463ae0SJohn Muir 
1480c2183d1eSMiklos Szeredi 	err = -EINVAL;
1481c2183d1eSMiklos Szeredi 	if (size != sizeof(outarg) + outarg.namelen + 1)
1482c2183d1eSMiklos Szeredi 		goto err;
1483c2183d1eSMiklos Szeredi 
14843b463ae0SJohn Muir 	name.name = buf;
14853b463ae0SJohn Muir 	name.len = outarg.namelen;
14863b463ae0SJohn Muir 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
14873b463ae0SJohn Muir 	if (err)
14883b463ae0SJohn Muir 		goto err;
14893b463ae0SJohn Muir 	fuse_copy_finish(cs);
14903b463ae0SJohn Muir 	buf[outarg.namelen] = 0;
14913b463ae0SJohn Muir 
14923b463ae0SJohn Muir 	down_read(&fc->killsb);
1493fcee216bSMax Reitz 	err = fuse_reverse_inval_entry(fc, outarg.parent, 0, &name);
1494451d0f59SJohn Muir 	up_read(&fc->killsb);
1495451d0f59SJohn Muir 	kfree(buf);
1496451d0f59SJohn Muir 	return err;
1497451d0f59SJohn Muir 
1498451d0f59SJohn Muir err:
1499451d0f59SJohn Muir 	kfree(buf);
1500451d0f59SJohn Muir 	fuse_copy_finish(cs);
1501451d0f59SJohn Muir 	return err;
1502451d0f59SJohn Muir }
1503451d0f59SJohn Muir 
1504451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size,
1505451d0f59SJohn Muir 			      struct fuse_copy_state *cs)
1506451d0f59SJohn Muir {
1507451d0f59SJohn Muir 	struct fuse_notify_delete_out outarg;
1508451d0f59SJohn Muir 	int err = -ENOMEM;
1509451d0f59SJohn Muir 	char *buf;
1510451d0f59SJohn Muir 	struct qstr name;
1511451d0f59SJohn Muir 
1512451d0f59SJohn Muir 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
1513451d0f59SJohn Muir 	if (!buf)
1514451d0f59SJohn Muir 		goto err;
1515451d0f59SJohn Muir 
1516451d0f59SJohn Muir 	err = -EINVAL;
1517451d0f59SJohn Muir 	if (size < sizeof(outarg))
1518451d0f59SJohn Muir 		goto err;
1519451d0f59SJohn Muir 
1520451d0f59SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
1521451d0f59SJohn Muir 	if (err)
1522451d0f59SJohn Muir 		goto err;
1523451d0f59SJohn Muir 
1524451d0f59SJohn Muir 	err = -ENAMETOOLONG;
1525451d0f59SJohn Muir 	if (outarg.namelen > FUSE_NAME_MAX)
1526451d0f59SJohn Muir 		goto err;
1527451d0f59SJohn Muir 
1528451d0f59SJohn Muir 	err = -EINVAL;
1529451d0f59SJohn Muir 	if (size != sizeof(outarg) + outarg.namelen + 1)
1530451d0f59SJohn Muir 		goto err;
1531451d0f59SJohn Muir 
1532451d0f59SJohn Muir 	name.name = buf;
1533451d0f59SJohn Muir 	name.len = outarg.namelen;
1534451d0f59SJohn Muir 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
1535451d0f59SJohn Muir 	if (err)
1536451d0f59SJohn Muir 		goto err;
1537451d0f59SJohn Muir 	fuse_copy_finish(cs);
1538451d0f59SJohn Muir 	buf[outarg.namelen] = 0;
1539451d0f59SJohn Muir 
1540451d0f59SJohn Muir 	down_read(&fc->killsb);
1541fcee216bSMax Reitz 	err = fuse_reverse_inval_entry(fc, outarg.parent, outarg.child, &name);
15423b463ae0SJohn Muir 	up_read(&fc->killsb);
1543b2d82ee3SFang Wenqi 	kfree(buf);
15443b463ae0SJohn Muir 	return err;
15453b463ae0SJohn Muir 
15463b463ae0SJohn Muir err:
1547b2d82ee3SFang Wenqi 	kfree(buf);
15483b463ae0SJohn Muir 	fuse_copy_finish(cs);
15493b463ae0SJohn Muir 	return err;
15503b463ae0SJohn Muir }
15513b463ae0SJohn Muir 
1552a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
1553a1d75f25SMiklos Szeredi 			     struct fuse_copy_state *cs)
1554a1d75f25SMiklos Szeredi {
1555a1d75f25SMiklos Szeredi 	struct fuse_notify_store_out outarg;
1556a1d75f25SMiklos Szeredi 	struct inode *inode;
1557a1d75f25SMiklos Szeredi 	struct address_space *mapping;
1558a1d75f25SMiklos Szeredi 	u64 nodeid;
1559a1d75f25SMiklos Szeredi 	int err;
1560a1d75f25SMiklos Szeredi 	pgoff_t index;
1561a1d75f25SMiklos Szeredi 	unsigned int offset;
1562a1d75f25SMiklos Szeredi 	unsigned int num;
1563a1d75f25SMiklos Szeredi 	loff_t file_size;
1564a1d75f25SMiklos Szeredi 	loff_t end;
1565a1d75f25SMiklos Szeredi 
1566a1d75f25SMiklos Szeredi 	err = -EINVAL;
1567a1d75f25SMiklos Szeredi 	if (size < sizeof(outarg))
1568a1d75f25SMiklos Szeredi 		goto out_finish;
1569a1d75f25SMiklos Szeredi 
1570a1d75f25SMiklos Szeredi 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
1571a1d75f25SMiklos Szeredi 	if (err)
1572a1d75f25SMiklos Szeredi 		goto out_finish;
1573a1d75f25SMiklos Szeredi 
1574a1d75f25SMiklos Szeredi 	err = -EINVAL;
1575a1d75f25SMiklos Szeredi 	if (size - sizeof(outarg) != outarg.size)
1576a1d75f25SMiklos Szeredi 		goto out_finish;
1577a1d75f25SMiklos Szeredi 
1578a1d75f25SMiklos Szeredi 	nodeid = outarg.nodeid;
1579a1d75f25SMiklos Szeredi 
1580a1d75f25SMiklos Szeredi 	down_read(&fc->killsb);
1581a1d75f25SMiklos Szeredi 
1582a1d75f25SMiklos Szeredi 	err = -ENOENT;
1583fcee216bSMax Reitz 	inode = fuse_ilookup(fc, nodeid,  NULL);
1584a1d75f25SMiklos Szeredi 	if (!inode)
1585a1d75f25SMiklos Szeredi 		goto out_up_killsb;
1586a1d75f25SMiklos Szeredi 
1587a1d75f25SMiklos Szeredi 	mapping = inode->i_mapping;
158809cbfeafSKirill A. Shutemov 	index = outarg.offset >> PAGE_SHIFT;
158909cbfeafSKirill A. Shutemov 	offset = outarg.offset & ~PAGE_MASK;
1590a1d75f25SMiklos Szeredi 	file_size = i_size_read(inode);
1591a1d75f25SMiklos Szeredi 	end = outarg.offset + outarg.size;
1592a1d75f25SMiklos Szeredi 	if (end > file_size) {
1593a1d75f25SMiklos Szeredi 		file_size = end;
1594a1d75f25SMiklos Szeredi 		fuse_write_update_size(inode, file_size);
1595a1d75f25SMiklos Szeredi 	}
1596a1d75f25SMiklos Szeredi 
1597a1d75f25SMiklos Szeredi 	num = outarg.size;
1598a1d75f25SMiklos Szeredi 	while (num) {
1599a1d75f25SMiklos Szeredi 		struct page *page;
1600a1d75f25SMiklos Szeredi 		unsigned int this_num;
1601a1d75f25SMiklos Szeredi 
1602a1d75f25SMiklos Szeredi 		err = -ENOMEM;
1603a1d75f25SMiklos Szeredi 		page = find_or_create_page(mapping, index,
1604a1d75f25SMiklos Szeredi 					   mapping_gfp_mask(mapping));
1605a1d75f25SMiklos Szeredi 		if (!page)
1606a1d75f25SMiklos Szeredi 			goto out_iput;
1607a1d75f25SMiklos Szeredi 
160809cbfeafSKirill A. Shutemov 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
1609a1d75f25SMiklos Szeredi 		err = fuse_copy_page(cs, &page, offset, this_num, 0);
1610063ec1e5SMiklos Szeredi 		if (!err && offset == 0 &&
161109cbfeafSKirill A. Shutemov 		    (this_num == PAGE_SIZE || file_size == end))
1612a1d75f25SMiklos Szeredi 			SetPageUptodate(page);
1613a1d75f25SMiklos Szeredi 		unlock_page(page);
161409cbfeafSKirill A. Shutemov 		put_page(page);
1615a1d75f25SMiklos Szeredi 
1616a1d75f25SMiklos Szeredi 		if (err)
1617a1d75f25SMiklos Szeredi 			goto out_iput;
1618a1d75f25SMiklos Szeredi 
1619a1d75f25SMiklos Szeredi 		num -= this_num;
1620a1d75f25SMiklos Szeredi 		offset = 0;
1621a1d75f25SMiklos Szeredi 		index++;
1622a1d75f25SMiklos Szeredi 	}
1623a1d75f25SMiklos Szeredi 
1624a1d75f25SMiklos Szeredi 	err = 0;
1625a1d75f25SMiklos Szeredi 
1626a1d75f25SMiklos Szeredi out_iput:
1627a1d75f25SMiklos Szeredi 	iput(inode);
1628a1d75f25SMiklos Szeredi out_up_killsb:
1629a1d75f25SMiklos Szeredi 	up_read(&fc->killsb);
1630a1d75f25SMiklos Szeredi out_finish:
1631a1d75f25SMiklos Szeredi 	fuse_copy_finish(cs);
1632a1d75f25SMiklos Szeredi 	return err;
1633a1d75f25SMiklos Szeredi }
1634a1d75f25SMiklos Szeredi 
163575b399ddSMiklos Szeredi struct fuse_retrieve_args {
163675b399ddSMiklos Szeredi 	struct fuse_args_pages ap;
163775b399ddSMiklos Szeredi 	struct fuse_notify_retrieve_in inarg;
163875b399ddSMiklos Szeredi };
163975b399ddSMiklos Szeredi 
1640fcee216bSMax Reitz static void fuse_retrieve_end(struct fuse_mount *fm, struct fuse_args *args,
164175b399ddSMiklos Szeredi 			      int error)
16422d45ba38SMiklos Szeredi {
164375b399ddSMiklos Szeredi 	struct fuse_retrieve_args *ra =
164475b399ddSMiklos Szeredi 		container_of(args, typeof(*ra), ap.args);
164575b399ddSMiklos Szeredi 
164675b399ddSMiklos Szeredi 	release_pages(ra->ap.pages, ra->ap.num_pages);
164775b399ddSMiklos Szeredi 	kfree(ra);
16482d45ba38SMiklos Szeredi }
16492d45ba38SMiklos Szeredi 
1650fcee216bSMax Reitz static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
16512d45ba38SMiklos Szeredi 			 struct fuse_notify_retrieve_out *outarg)
16522d45ba38SMiklos Szeredi {
16532d45ba38SMiklos Szeredi 	int err;
16542d45ba38SMiklos Szeredi 	struct address_space *mapping = inode->i_mapping;
16552d45ba38SMiklos Szeredi 	pgoff_t index;
16562d45ba38SMiklos Szeredi 	loff_t file_size;
16572d45ba38SMiklos Szeredi 	unsigned int num;
16582d45ba38SMiklos Szeredi 	unsigned int offset;
16590157443cSGeert Uytterhoeven 	size_t total_len = 0;
16605da784ccSConstantine Shulyupin 	unsigned int num_pages;
1661fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
166275b399ddSMiklos Szeredi 	struct fuse_retrieve_args *ra;
166375b399ddSMiklos Szeredi 	size_t args_size = sizeof(*ra);
166475b399ddSMiklos Szeredi 	struct fuse_args_pages *ap;
166575b399ddSMiklos Szeredi 	struct fuse_args *args;
16662d45ba38SMiklos Szeredi 
166709cbfeafSKirill A. Shutemov 	offset = outarg->offset & ~PAGE_MASK;
16684d53dc99SMaxim Patlasov 	file_size = i_size_read(inode);
16694d53dc99SMaxim Patlasov 
16707640682eSKirill Smelkov 	num = min(outarg->size, fc->max_write);
16714d53dc99SMaxim Patlasov 	if (outarg->offset > file_size)
16724d53dc99SMaxim Patlasov 		num = 0;
16734d53dc99SMaxim Patlasov 	else if (outarg->offset + num > file_size)
16744d53dc99SMaxim Patlasov 		num = file_size - outarg->offset;
16754d53dc99SMaxim Patlasov 
16764d53dc99SMaxim Patlasov 	num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
16775da784ccSConstantine Shulyupin 	num_pages = min(num_pages, fc->max_pages);
16784d53dc99SMaxim Patlasov 
167975b399ddSMiklos Szeredi 	args_size += num_pages * (sizeof(ap->pages[0]) + sizeof(ap->descs[0]));
16802d45ba38SMiklos Szeredi 
168175b399ddSMiklos Szeredi 	ra = kzalloc(args_size, GFP_KERNEL);
168275b399ddSMiklos Szeredi 	if (!ra)
168375b399ddSMiklos Szeredi 		return -ENOMEM;
168475b399ddSMiklos Szeredi 
168575b399ddSMiklos Szeredi 	ap = &ra->ap;
168675b399ddSMiklos Szeredi 	ap->pages = (void *) (ra + 1);
168775b399ddSMiklos Szeredi 	ap->descs = (void *) (ap->pages + num_pages);
168875b399ddSMiklos Szeredi 
168975b399ddSMiklos Szeredi 	args = &ap->args;
169075b399ddSMiklos Szeredi 	args->nodeid = outarg->nodeid;
169175b399ddSMiklos Szeredi 	args->opcode = FUSE_NOTIFY_REPLY;
169275b399ddSMiklos Szeredi 	args->in_numargs = 2;
169375b399ddSMiklos Szeredi 	args->in_pages = true;
169475b399ddSMiklos Szeredi 	args->end = fuse_retrieve_end;
16952d45ba38SMiklos Szeredi 
169609cbfeafSKirill A. Shutemov 	index = outarg->offset >> PAGE_SHIFT;
16972d45ba38SMiklos Szeredi 
169875b399ddSMiklos Szeredi 	while (num && ap->num_pages < num_pages) {
16992d45ba38SMiklos Szeredi 		struct page *page;
17002d45ba38SMiklos Szeredi 		unsigned int this_num;
17012d45ba38SMiklos Szeredi 
17022d45ba38SMiklos Szeredi 		page = find_get_page(mapping, index);
17032d45ba38SMiklos Szeredi 		if (!page)
17042d45ba38SMiklos Szeredi 			break;
17052d45ba38SMiklos Szeredi 
170609cbfeafSKirill A. Shutemov 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
170775b399ddSMiklos Szeredi 		ap->pages[ap->num_pages] = page;
170875b399ddSMiklos Szeredi 		ap->descs[ap->num_pages].offset = offset;
170975b399ddSMiklos Szeredi 		ap->descs[ap->num_pages].length = this_num;
171075b399ddSMiklos Szeredi 		ap->num_pages++;
17112d45ba38SMiklos Szeredi 
1712c9e67d48SMiklos Szeredi 		offset = 0;
17132d45ba38SMiklos Szeredi 		num -= this_num;
17142d45ba38SMiklos Szeredi 		total_len += this_num;
171548706d0aSMiklos Szeredi 		index++;
17162d45ba38SMiklos Szeredi 	}
171775b399ddSMiklos Szeredi 	ra->inarg.offset = outarg->offset;
171875b399ddSMiklos Szeredi 	ra->inarg.size = total_len;
171975b399ddSMiklos Szeredi 	args->in_args[0].size = sizeof(ra->inarg);
172075b399ddSMiklos Szeredi 	args->in_args[0].value = &ra->inarg;
172175b399ddSMiklos Szeredi 	args->in_args[1].size = total_len;
17222d45ba38SMiklos Szeredi 
1723fcee216bSMax Reitz 	err = fuse_simple_notify_reply(fm, args, outarg->notify_unique);
172475b399ddSMiklos Szeredi 	if (err)
1725fcee216bSMax Reitz 		fuse_retrieve_end(fm, args, err);
17262d45ba38SMiklos Szeredi 
17272d45ba38SMiklos Szeredi 	return err;
17282d45ba38SMiklos Szeredi }
17292d45ba38SMiklos Szeredi 
17302d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size,
17312d45ba38SMiklos Szeredi 				struct fuse_copy_state *cs)
17322d45ba38SMiklos Szeredi {
17332d45ba38SMiklos Szeredi 	struct fuse_notify_retrieve_out outarg;
1734fcee216bSMax Reitz 	struct fuse_mount *fm;
17352d45ba38SMiklos Szeredi 	struct inode *inode;
1736fcee216bSMax Reitz 	u64 nodeid;
17372d45ba38SMiklos Szeredi 	int err;
17382d45ba38SMiklos Szeredi 
17392d45ba38SMiklos Szeredi 	err = -EINVAL;
17402d45ba38SMiklos Szeredi 	if (size != sizeof(outarg))
17412d45ba38SMiklos Szeredi 		goto copy_finish;
17422d45ba38SMiklos Szeredi 
17432d45ba38SMiklos Szeredi 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
17442d45ba38SMiklos Szeredi 	if (err)
17452d45ba38SMiklos Szeredi 		goto copy_finish;
17462d45ba38SMiklos Szeredi 
17472d45ba38SMiklos Szeredi 	fuse_copy_finish(cs);
17482d45ba38SMiklos Szeredi 
17492d45ba38SMiklos Szeredi 	down_read(&fc->killsb);
17502d45ba38SMiklos Szeredi 	err = -ENOENT;
1751fcee216bSMax Reitz 	nodeid = outarg.nodeid;
17522d45ba38SMiklos Szeredi 
1753fcee216bSMax Reitz 	inode = fuse_ilookup(fc, nodeid, &fm);
17542d45ba38SMiklos Szeredi 	if (inode) {
1755fcee216bSMax Reitz 		err = fuse_retrieve(fm, inode, &outarg);
17562d45ba38SMiklos Szeredi 		iput(inode);
17572d45ba38SMiklos Szeredi 	}
17582d45ba38SMiklos Szeredi 	up_read(&fc->killsb);
17592d45ba38SMiklos Szeredi 
17602d45ba38SMiklos Szeredi 	return err;
17612d45ba38SMiklos Szeredi 
17622d45ba38SMiklos Szeredi copy_finish:
17632d45ba38SMiklos Szeredi 	fuse_copy_finish(cs);
17642d45ba38SMiklos Szeredi 	return err;
17652d45ba38SMiklos Szeredi }
17662d45ba38SMiklos Szeredi 
17678599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
17688599396bSTejun Heo 		       unsigned int size, struct fuse_copy_state *cs)
17698599396bSTejun Heo {
17700d278362SMiklos Szeredi 	/* Don't try to move pages (yet) */
17710d278362SMiklos Szeredi 	cs->move_pages = 0;
17720d278362SMiklos Szeredi 
17738599396bSTejun Heo 	switch (code) {
177495668a69STejun Heo 	case FUSE_NOTIFY_POLL:
177595668a69STejun Heo 		return fuse_notify_poll(fc, size, cs);
177695668a69STejun Heo 
17773b463ae0SJohn Muir 	case FUSE_NOTIFY_INVAL_INODE:
17783b463ae0SJohn Muir 		return fuse_notify_inval_inode(fc, size, cs);
17793b463ae0SJohn Muir 
17803b463ae0SJohn Muir 	case FUSE_NOTIFY_INVAL_ENTRY:
17813b463ae0SJohn Muir 		return fuse_notify_inval_entry(fc, size, cs);
17823b463ae0SJohn Muir 
1783a1d75f25SMiklos Szeredi 	case FUSE_NOTIFY_STORE:
1784a1d75f25SMiklos Szeredi 		return fuse_notify_store(fc, size, cs);
1785a1d75f25SMiklos Szeredi 
17862d45ba38SMiklos Szeredi 	case FUSE_NOTIFY_RETRIEVE:
17872d45ba38SMiklos Szeredi 		return fuse_notify_retrieve(fc, size, cs);
17882d45ba38SMiklos Szeredi 
1789451d0f59SJohn Muir 	case FUSE_NOTIFY_DELETE:
1790451d0f59SJohn Muir 		return fuse_notify_delete(fc, size, cs);
1791451d0f59SJohn Muir 
17928599396bSTejun Heo 	default:
1793f6d47a17SMiklos Szeredi 		fuse_copy_finish(cs);
17948599396bSTejun Heo 		return -EINVAL;
17958599396bSTejun Heo 	}
17968599396bSTejun Heo }
17978599396bSTejun Heo 
1798334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */
17993a2b5b9cSMiklos Szeredi static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique)
1800334f485dSMiklos Szeredi {
1801be2ff42cSKirill Tkhai 	unsigned int hash = fuse_req_hash(unique);
1802334f485dSMiklos Szeredi 	struct fuse_req *req;
180305726acaSDong Fang 
1804be2ff42cSKirill Tkhai 	list_for_each_entry(req, &fpq->processing[hash], list) {
18053a5358d1SKirill Tkhai 		if (req->in.h.unique == unique)
1806334f485dSMiklos Szeredi 			return req;
1807334f485dSMiklos Szeredi 	}
1808334f485dSMiklos Szeredi 	return NULL;
1809334f485dSMiklos Szeredi }
1810334f485dSMiklos Szeredi 
1811d4993774SMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_args *args,
1812334f485dSMiklos Szeredi 			 unsigned nbytes)
1813334f485dSMiklos Szeredi {
1814334f485dSMiklos Szeredi 	unsigned reqsize = sizeof(struct fuse_out_header);
1815334f485dSMiklos Szeredi 
181614d46d7aSStefan Hajnoczi 	reqsize += fuse_len_args(args->out_numargs, args->out_args);
1817334f485dSMiklos Szeredi 
1818d4993774SMiklos Szeredi 	if (reqsize < nbytes || (reqsize > nbytes && !args->out_argvar))
1819334f485dSMiklos Szeredi 		return -EINVAL;
1820334f485dSMiklos Szeredi 	else if (reqsize > nbytes) {
1821d4993774SMiklos Szeredi 		struct fuse_arg *lastarg = &args->out_args[args->out_numargs-1];
1822334f485dSMiklos Szeredi 		unsigned diffsize = reqsize - nbytes;
1823d4993774SMiklos Szeredi 
1824334f485dSMiklos Szeredi 		if (diffsize > lastarg->size)
1825334f485dSMiklos Szeredi 			return -EINVAL;
1826334f485dSMiklos Szeredi 		lastarg->size -= diffsize;
1827334f485dSMiklos Szeredi 	}
1828d4993774SMiklos Szeredi 	return fuse_copy_args(cs, args->out_numargs, args->out_pages,
1829d4993774SMiklos Szeredi 			      args->out_args, args->page_zeroing);
1830334f485dSMiklos Szeredi }
1831334f485dSMiklos Szeredi 
1832334f485dSMiklos Szeredi /*
1833334f485dSMiklos Szeredi  * Write a single reply to a request.  First the header is copied from
1834334f485dSMiklos Szeredi  * the write buffer.  The request is then searched on the processing
1835334f485dSMiklos Szeredi  * list by the unique ID found in the header.  If found, then remove
1836334f485dSMiklos Szeredi  * it from the list and copy the rest of the buffer to the request.
183704ec5af0SStefan Hajnoczi  * The request is finished by calling fuse_request_end().
1838334f485dSMiklos Szeredi  */
1839c3696046SMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
1840dd3bb14fSMiklos Szeredi 				 struct fuse_copy_state *cs, size_t nbytes)
1841334f485dSMiklos Szeredi {
1842334f485dSMiklos Szeredi 	int err;
1843c3696046SMiklos Szeredi 	struct fuse_conn *fc = fud->fc;
1844c3696046SMiklos Szeredi 	struct fuse_pqueue *fpq = &fud->pq;
1845334f485dSMiklos Szeredi 	struct fuse_req *req;
1846334f485dSMiklos Szeredi 	struct fuse_out_header oh;
1847334f485dSMiklos Szeredi 
18487407a10dSKirill Tkhai 	err = -EINVAL;
1849334f485dSMiklos Szeredi 	if (nbytes < sizeof(struct fuse_out_header))
18507407a10dSKirill Tkhai 		goto out;
1851334f485dSMiklos Szeredi 
1852dd3bb14fSMiklos Szeredi 	err = fuse_copy_one(cs, &oh, sizeof(oh));
1853334f485dSMiklos Szeredi 	if (err)
18547407a10dSKirill Tkhai 		goto copy_finish;
18558599396bSTejun Heo 
1856334f485dSMiklos Szeredi 	err = -EINVAL;
18578599396bSTejun Heo 	if (oh.len != nbytes)
18587407a10dSKirill Tkhai 		goto copy_finish;
18598599396bSTejun Heo 
18608599396bSTejun Heo 	/*
18618599396bSTejun Heo 	 * Zero oh.unique indicates unsolicited notification message
18628599396bSTejun Heo 	 * and error contains notification code.
18638599396bSTejun Heo 	 */
18648599396bSTejun Heo 	if (!oh.unique) {
1865dd3bb14fSMiklos Szeredi 		err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs);
18667407a10dSKirill Tkhai 		goto out;
18678599396bSTejun Heo 	}
18688599396bSTejun Heo 
18698599396bSTejun Heo 	err = -EINVAL;
18708599396bSTejun Heo 	if (oh.error <= -1000 || oh.error > 0)
18717407a10dSKirill Tkhai 		goto copy_finish;
1872334f485dSMiklos Szeredi 
187345a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
18747407a10dSKirill Tkhai 	req = NULL;
18757407a10dSKirill Tkhai 	if (fpq->connected)
18763a5358d1SKirill Tkhai 		req = request_find(fpq, oh.unique & ~FUSE_INT_REQ_BIT);
18777407a10dSKirill Tkhai 
18787407a10dSKirill Tkhai 	err = -ENOENT;
18797407a10dSKirill Tkhai 	if (!req) {
18807407a10dSKirill Tkhai 		spin_unlock(&fpq->lock);
18817407a10dSKirill Tkhai 		goto copy_finish;
18827407a10dSKirill Tkhai 	}
1883334f485dSMiklos Szeredi 
18843a5358d1SKirill Tkhai 	/* Is it an interrupt reply ID? */
18853a5358d1SKirill Tkhai 	if (oh.unique & FUSE_INT_REQ_BIT) {
1886d2d2d4fbSKirill Tkhai 		__fuse_get_request(req);
188745a91cb1SMiklos Szeredi 		spin_unlock(&fpq->lock);
188845a91cb1SMiklos Szeredi 
18897407a10dSKirill Tkhai 		err = 0;
18907407a10dSKirill Tkhai 		if (nbytes != sizeof(struct fuse_out_header))
1891a4d27e75SMiklos Szeredi 			err = -EINVAL;
18927407a10dSKirill Tkhai 		else if (oh.error == -ENOSYS)
1893a4d27e75SMiklos Szeredi 			fc->no_interrupt = 1;
1894a4d27e75SMiklos Szeredi 		else if (oh.error == -EAGAIN)
18958f622e94SMax Reitz 			err = queue_interrupt(req);
18967407a10dSKirill Tkhai 
18978f622e94SMax Reitz 		fuse_put_request(req);
1898a4d27e75SMiklos Szeredi 
18997407a10dSKirill Tkhai 		goto copy_finish;
1900a4d27e75SMiklos Szeredi 	}
1901a4d27e75SMiklos Szeredi 
190233e14b4dSMiklos Szeredi 	clear_bit(FR_SENT, &req->flags);
19033a2b5b9cSMiklos Szeredi 	list_move(&req->list, &fpq->io);
1904334f485dSMiklos Szeredi 	req->out.h = oh;
1905825d6d33SMiklos Szeredi 	set_bit(FR_LOCKED, &req->flags);
190645a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1907dd3bb14fSMiklos Szeredi 	cs->req = req;
1908d4993774SMiklos Szeredi 	if (!req->args->page_replace)
1909ce534fb0SMiklos Szeredi 		cs->move_pages = 0;
1910334f485dSMiklos Szeredi 
1911d4993774SMiklos Szeredi 	if (oh.error)
1912d4993774SMiklos Szeredi 		err = nbytes != sizeof(oh) ? -EINVAL : 0;
1913d4993774SMiklos Szeredi 	else
1914d4993774SMiklos Szeredi 		err = copy_out_args(cs, req->args, nbytes);
1915dd3bb14fSMiklos Szeredi 	fuse_copy_finish(cs);
1916334f485dSMiklos Szeredi 
191745a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1918825d6d33SMiklos Szeredi 	clear_bit(FR_LOCKED, &req->flags);
1919e96edd94SMiklos Szeredi 	if (!fpq->connected)
1920334f485dSMiklos Szeredi 		err = -ENOENT;
19210d8e84b0SMiklos Szeredi 	else if (err)
1922334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
192377cd9d48SMiklos Szeredi 	if (!test_bit(FR_PRIVATE, &req->flags))
1924f377cb79SMiklos Szeredi 		list_del_init(&req->list);
192545a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
192646c34a34SMiklos Szeredi 
19278f622e94SMax Reitz 	fuse_request_end(req);
19287407a10dSKirill Tkhai out:
1929334f485dSMiklos Szeredi 	return err ? err : nbytes;
1930334f485dSMiklos Szeredi 
19317407a10dSKirill Tkhai copy_finish:
1932dd3bb14fSMiklos Szeredi 	fuse_copy_finish(cs);
19337407a10dSKirill Tkhai 	goto out;
1934334f485dSMiklos Szeredi }
1935334f485dSMiklos Szeredi 
1936fbdbaccaSAl Viro static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from)
1937dd3bb14fSMiklos Szeredi {
1938dd3bb14fSMiklos Szeredi 	struct fuse_copy_state cs;
1939cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(iocb->ki_filp);
1940cc080e9eSMiklos Szeredi 
1941cc080e9eSMiklos Szeredi 	if (!fud)
1942dd3bb14fSMiklos Szeredi 		return -EPERM;
1943dd3bb14fSMiklos Szeredi 
1944fbdbaccaSAl Viro 	if (!iter_is_iovec(from))
1945fbdbaccaSAl Viro 		return -EINVAL;
1946dd3bb14fSMiklos Szeredi 
1947dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 0, from);
1948fbdbaccaSAl Viro 
1949c3696046SMiklos Szeredi 	return fuse_dev_do_write(fud, &cs, iov_iter_count(from));
1950dd3bb14fSMiklos Szeredi }
1951dd3bb14fSMiklos Szeredi 
1952dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
1953dd3bb14fSMiklos Szeredi 				     struct file *out, loff_t *ppos,
1954dd3bb14fSMiklos Szeredi 				     size_t len, unsigned int flags)
1955dd3bb14fSMiklos Szeredi {
19568cefc107SDavid Howells 	unsigned int head, tail, mask, count;
1957dd3bb14fSMiklos Szeredi 	unsigned nbuf;
1958dd3bb14fSMiklos Szeredi 	unsigned idx;
1959dd3bb14fSMiklos Szeredi 	struct pipe_buffer *bufs;
1960dd3bb14fSMiklos Szeredi 	struct fuse_copy_state cs;
1961cc080e9eSMiklos Szeredi 	struct fuse_dev *fud;
1962dd3bb14fSMiklos Szeredi 	size_t rem;
1963dd3bb14fSMiklos Szeredi 	ssize_t ret;
1964dd3bb14fSMiklos Szeredi 
1965cc080e9eSMiklos Szeredi 	fud = fuse_get_dev(out);
1966cc080e9eSMiklos Szeredi 	if (!fud)
1967dd3bb14fSMiklos Szeredi 		return -EPERM;
1968dd3bb14fSMiklos Szeredi 
1969a2477b0eSAndrey Ryabinin 	pipe_lock(pipe);
1970a2477b0eSAndrey Ryabinin 
19718cefc107SDavid Howells 	head = pipe->head;
19728cefc107SDavid Howells 	tail = pipe->tail;
19738cefc107SDavid Howells 	mask = pipe->ring_size - 1;
19748cefc107SDavid Howells 	count = head - tail;
19758cefc107SDavid Howells 
19768cefc107SDavid Howells 	bufs = kvmalloc_array(count, sizeof(struct pipe_buffer), GFP_KERNEL);
1977a2477b0eSAndrey Ryabinin 	if (!bufs) {
1978a2477b0eSAndrey Ryabinin 		pipe_unlock(pipe);
1979dd3bb14fSMiklos Szeredi 		return -ENOMEM;
1980a2477b0eSAndrey Ryabinin 	}
1981dd3bb14fSMiklos Szeredi 
1982dd3bb14fSMiklos Szeredi 	nbuf = 0;
1983dd3bb14fSMiklos Szeredi 	rem = 0;
198476f6777cSDavid Howells 	for (idx = tail; idx != head && rem < len; idx++)
19858cefc107SDavid Howells 		rem += pipe->bufs[idx & mask].len;
1986dd3bb14fSMiklos Szeredi 
1987dd3bb14fSMiklos Szeredi 	ret = -EINVAL;
198815fab63eSMatthew Wilcox 	if (rem < len)
198915fab63eSMatthew Wilcox 		goto out_free;
1990dd3bb14fSMiklos Szeredi 
1991dd3bb14fSMiklos Szeredi 	rem = len;
1992dd3bb14fSMiklos Szeredi 	while (rem) {
1993dd3bb14fSMiklos Szeredi 		struct pipe_buffer *ibuf;
1994dd3bb14fSMiklos Szeredi 		struct pipe_buffer *obuf;
1995dd3bb14fSMiklos Szeredi 
19960e9fb6f1SVasily Averin 		if (WARN_ON(nbuf >= count || tail == head))
19970e9fb6f1SVasily Averin 			goto out_free;
19980e9fb6f1SVasily Averin 
19998cefc107SDavid Howells 		ibuf = &pipe->bufs[tail & mask];
2000dd3bb14fSMiklos Szeredi 		obuf = &bufs[nbuf];
2001dd3bb14fSMiklos Szeredi 
2002dd3bb14fSMiklos Szeredi 		if (rem >= ibuf->len) {
2003dd3bb14fSMiklos Szeredi 			*obuf = *ibuf;
2004dd3bb14fSMiklos Szeredi 			ibuf->ops = NULL;
20058cefc107SDavid Howells 			tail++;
20068cefc107SDavid Howells 			pipe->tail = tail;
2007dd3bb14fSMiklos Szeredi 		} else {
200815fab63eSMatthew Wilcox 			if (!pipe_buf_get(pipe, ibuf))
200915fab63eSMatthew Wilcox 				goto out_free;
201015fab63eSMatthew Wilcox 
2011dd3bb14fSMiklos Szeredi 			*obuf = *ibuf;
2012dd3bb14fSMiklos Szeredi 			obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
2013dd3bb14fSMiklos Szeredi 			obuf->len = rem;
2014dd3bb14fSMiklos Szeredi 			ibuf->offset += obuf->len;
2015dd3bb14fSMiklos Szeredi 			ibuf->len -= obuf->len;
2016dd3bb14fSMiklos Szeredi 		}
2017dd3bb14fSMiklos Szeredi 		nbuf++;
2018dd3bb14fSMiklos Szeredi 		rem -= obuf->len;
2019dd3bb14fSMiklos Szeredi 	}
2020dd3bb14fSMiklos Szeredi 	pipe_unlock(pipe);
2021dd3bb14fSMiklos Szeredi 
2022dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 0, NULL);
2023dd3bb14fSMiklos Szeredi 	cs.pipebufs = bufs;
20246c09e94aSAl Viro 	cs.nr_segs = nbuf;
2025dd3bb14fSMiklos Szeredi 	cs.pipe = pipe;
2026dd3bb14fSMiklos Szeredi 
2027ce534fb0SMiklos Szeredi 	if (flags & SPLICE_F_MOVE)
2028ce534fb0SMiklos Szeredi 		cs.move_pages = 1;
2029ce534fb0SMiklos Szeredi 
2030c3696046SMiklos Szeredi 	ret = fuse_dev_do_write(fud, &cs, len);
2031dd3bb14fSMiklos Szeredi 
20329509941eSJann Horn 	pipe_lock(pipe);
203315fab63eSMatthew Wilcox out_free:
2034a779638cSMiklos Szeredi 	for (idx = 0; idx < nbuf; idx++)
2035a779638cSMiklos Szeredi 		pipe_buf_release(pipe, &bufs[idx]);
20369509941eSJann Horn 	pipe_unlock(pipe);
2037a779638cSMiklos Szeredi 
2038d6d931adSAndrey Ryabinin 	kvfree(bufs);
2039dd3bb14fSMiklos Szeredi 	return ret;
2040dd3bb14fSMiklos Szeredi }
2041dd3bb14fSMiklos Szeredi 
2042076ccb76SAl Viro static __poll_t fuse_dev_poll(struct file *file, poll_table *wait)
2043334f485dSMiklos Szeredi {
2044a9a08845SLinus Torvalds 	__poll_t mask = EPOLLOUT | EPOLLWRNORM;
2045f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq;
2046cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2047cc080e9eSMiklos Szeredi 
2048cc080e9eSMiklos Szeredi 	if (!fud)
2049a9a08845SLinus Torvalds 		return EPOLLERR;
2050334f485dSMiklos Szeredi 
2051cc080e9eSMiklos Szeredi 	fiq = &fud->fc->iq;
2052f88996a9SMiklos Szeredi 	poll_wait(file, &fiq->waitq, wait);
2053334f485dSMiklos Szeredi 
205476e43c8cSEric Biggers 	spin_lock(&fiq->lock);
2055e16714d8SMiklos Szeredi 	if (!fiq->connected)
2056a9a08845SLinus Torvalds 		mask = EPOLLERR;
2057f88996a9SMiklos Szeredi 	else if (request_pending(fiq))
2058a9a08845SLinus Torvalds 		mask |= EPOLLIN | EPOLLRDNORM;
205976e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
2060334f485dSMiklos Szeredi 
2061334f485dSMiklos Szeredi 	return mask;
2062334f485dSMiklos Szeredi }
2063334f485dSMiklos Szeredi 
206434061750SKirill Tkhai /* Abort all requests on the given list (pending or processing) */
20658f622e94SMax Reitz static void end_requests(struct list_head *head)
2066334f485dSMiklos Szeredi {
2067334f485dSMiklos Szeredi 	while (!list_empty(head)) {
2068334f485dSMiklos Szeredi 		struct fuse_req *req;
2069334f485dSMiklos Szeredi 		req = list_entry(head->next, struct fuse_req, list);
2070334f485dSMiklos Szeredi 		req->out.h.error = -ECONNABORTED;
207133e14b4dSMiklos Szeredi 		clear_bit(FR_SENT, &req->flags);
2072f377cb79SMiklos Szeredi 		list_del_init(&req->list);
20738f622e94SMax Reitz 		fuse_request_end(req);
2074334f485dSMiklos Szeredi 	}
2075334f485dSMiklos Szeredi }
2076334f485dSMiklos Szeredi 
2077357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc)
2078357ccf2bSBryan Green {
2079357ccf2bSBryan Green 	struct rb_node *p;
2080357ccf2bSBryan Green 
2081357ccf2bSBryan Green 	p = rb_first(&fc->polled_files);
2082357ccf2bSBryan Green 
2083357ccf2bSBryan Green 	while (p) {
2084357ccf2bSBryan Green 		struct fuse_file *ff;
2085357ccf2bSBryan Green 		ff = rb_entry(p, struct fuse_file, polled_node);
2086357ccf2bSBryan Green 		wake_up_interruptible_all(&ff->poll_wait);
2087357ccf2bSBryan Green 
2088357ccf2bSBryan Green 		p = rb_next(p);
2089357ccf2bSBryan Green 	}
2090357ccf2bSBryan Green }
2091357ccf2bSBryan Green 
209269a53bf2SMiklos Szeredi /*
209369a53bf2SMiklos Szeredi  * Abort all requests.
209469a53bf2SMiklos Szeredi  *
2095b716d425SMiklos Szeredi  * Emergency exit in case of a malicious or accidental deadlock, or just a hung
2096b716d425SMiklos Szeredi  * filesystem.
209769a53bf2SMiklos Szeredi  *
2098b716d425SMiklos Szeredi  * The same effect is usually achievable through killing the filesystem daemon
2099b716d425SMiklos Szeredi  * and all users of the filesystem.  The exception is the combination of an
2100b716d425SMiklos Szeredi  * asynchronous request and the tricky deadlock (see
210172ef5e52SMauro Carvalho Chehab  * Documentation/filesystems/fuse.rst).
210269a53bf2SMiklos Szeredi  *
2103b716d425SMiklos Szeredi  * Aborting requests under I/O goes as follows: 1: Separate out unlocked
2104b716d425SMiklos Szeredi  * requests, they should be finished off immediately.  Locked requests will be
2105b716d425SMiklos Szeredi  * finished after unlock; see unlock_request(). 2: Finish off the unlocked
2106b716d425SMiklos Szeredi  * requests.  It is possible that some request will finish before we can.  This
2107b716d425SMiklos Szeredi  * is OK, the request will in that case be removed from the list before we touch
2108b716d425SMiklos Szeredi  * it.
210969a53bf2SMiklos Szeredi  */
2110eb98e3bdSMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc)
211169a53bf2SMiklos Szeredi {
2112f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
2113f88996a9SMiklos Szeredi 
2114d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
211569a53bf2SMiklos Szeredi 	if (fc->connected) {
2116c3696046SMiklos Szeredi 		struct fuse_dev *fud;
2117b716d425SMiklos Szeredi 		struct fuse_req *req, *next;
211875f3ee4cSMiklos Szeredi 		LIST_HEAD(to_end);
2119be2ff42cSKirill Tkhai 		unsigned int i;
2120b716d425SMiklos Szeredi 
212163825b4eSKirill Tkhai 		/* Background queuing checks fc->connected under bg_lock */
212263825b4eSKirill Tkhai 		spin_lock(&fc->bg_lock);
212369a53bf2SMiklos Szeredi 		fc->connected = 0;
212463825b4eSKirill Tkhai 		spin_unlock(&fc->bg_lock);
212563825b4eSKirill Tkhai 
21269759bd51SMiklos Szeredi 		fuse_set_initialized(fc);
2127c3696046SMiklos Szeredi 		list_for_each_entry(fud, &fc->devices, entry) {
2128c3696046SMiklos Szeredi 			struct fuse_pqueue *fpq = &fud->pq;
2129c3696046SMiklos Szeredi 
213045a91cb1SMiklos Szeredi 			spin_lock(&fpq->lock);
2131e96edd94SMiklos Szeredi 			fpq->connected = 0;
21323a2b5b9cSMiklos Szeredi 			list_for_each_entry_safe(req, next, &fpq->io, list) {
2133b716d425SMiklos Szeredi 				req->out.h.error = -ECONNABORTED;
2134b716d425SMiklos Szeredi 				spin_lock(&req->waitq.lock);
2135b716d425SMiklos Szeredi 				set_bit(FR_ABORTED, &req->flags);
213677cd9d48SMiklos Szeredi 				if (!test_bit(FR_LOCKED, &req->flags)) {
213777cd9d48SMiklos Szeredi 					set_bit(FR_PRIVATE, &req->flags);
213887114373SMiklos Szeredi 					__fuse_get_request(req);
213975f3ee4cSMiklos Szeredi 					list_move(&req->list, &to_end);
214077cd9d48SMiklos Szeredi 				}
2141b716d425SMiklos Szeredi 				spin_unlock(&req->waitq.lock);
2142b716d425SMiklos Szeredi 			}
2143be2ff42cSKirill Tkhai 			for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
2144be2ff42cSKirill Tkhai 				list_splice_tail_init(&fpq->processing[i],
2145be2ff42cSKirill Tkhai 						      &to_end);
214645a91cb1SMiklos Szeredi 			spin_unlock(&fpq->lock);
2147c3696046SMiklos Szeredi 		}
2148ae2dffa3SKirill Tkhai 		spin_lock(&fc->bg_lock);
2149ae2dffa3SKirill Tkhai 		fc->blocked = 0;
215041f98274SMiklos Szeredi 		fc->max_background = UINT_MAX;
215141f98274SMiklos Szeredi 		flush_bg_queue(fc);
2152ae2dffa3SKirill Tkhai 		spin_unlock(&fc->bg_lock);
21538c91189aSMiklos Szeredi 
215476e43c8cSEric Biggers 		spin_lock(&fiq->lock);
21558c91189aSMiklos Szeredi 		fiq->connected = 0;
215675f3ee4cSMiklos Szeredi 		list_for_each_entry(req, &fiq->pending, list)
2157a8a86d78STahsin Erdogan 			clear_bit(FR_PENDING, &req->flags);
215875f3ee4cSMiklos Szeredi 		list_splice_tail_init(&fiq->pending, &to_end);
21598c91189aSMiklos Szeredi 		while (forget_pending(fiq))
21604388c5aaSVivek Goyal 			kfree(fuse_dequeue_forget(fiq, 1, NULL));
216176e43c8cSEric Biggers 		wake_up_all(&fiq->waitq);
216276e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
21638c91189aSMiklos Szeredi 		kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
2164ee314a87SMiklos Szeredi 		end_polls(fc);
2165ee314a87SMiklos Szeredi 		wake_up_all(&fc->blocked_waitq);
2166ee314a87SMiklos Szeredi 		spin_unlock(&fc->lock);
21678c91189aSMiklos Szeredi 
21688f622e94SMax Reitz 		end_requests(&to_end);
2169ee314a87SMiklos Szeredi 	} else {
2170d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
217169a53bf2SMiklos Szeredi 	}
2172ee314a87SMiklos Szeredi }
217308cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn);
217469a53bf2SMiklos Szeredi 
2175b8f95e5dSMiklos Szeredi void fuse_wait_aborted(struct fuse_conn *fc)
2176b8f95e5dSMiklos Szeredi {
21772d84a2d1SMiklos Szeredi 	/* matches implicit memory barrier in fuse_drop_waiting() */
21782d84a2d1SMiklos Szeredi 	smp_mb();
2179b8f95e5dSMiklos Szeredi 	wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
2180b8f95e5dSMiklos Szeredi }
2181b8f95e5dSMiklos Szeredi 
218208cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file)
2183334f485dSMiklos Szeredi {
2184cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2185cc080e9eSMiklos Szeredi 
2186cc080e9eSMiklos Szeredi 	if (fud) {
2187cc080e9eSMiklos Szeredi 		struct fuse_conn *fc = fud->fc;
2188c3696046SMiklos Szeredi 		struct fuse_pqueue *fpq = &fud->pq;
218945ff350bSMiklos Szeredi 		LIST_HEAD(to_end);
2190be2ff42cSKirill Tkhai 		unsigned int i;
2191cc080e9eSMiklos Szeredi 
219245ff350bSMiklos Szeredi 		spin_lock(&fpq->lock);
2193c3696046SMiklos Szeredi 		WARN_ON(!list_empty(&fpq->io));
2194be2ff42cSKirill Tkhai 		for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
2195be2ff42cSKirill Tkhai 			list_splice_init(&fpq->processing[i], &to_end);
219645ff350bSMiklos Szeredi 		spin_unlock(&fpq->lock);
219745ff350bSMiklos Szeredi 
21988f622e94SMax Reitz 		end_requests(&to_end);
219945ff350bSMiklos Szeredi 
2200c3696046SMiklos Szeredi 		/* Are we the last open device? */
2201c3696046SMiklos Szeredi 		if (atomic_dec_and_test(&fc->dev_count)) {
2202f88996a9SMiklos Szeredi 			WARN_ON(fc->iq.fasync != NULL);
2203eb98e3bdSMiklos Szeredi 			fuse_abort_conn(fc);
2204c3696046SMiklos Szeredi 		}
2205cc080e9eSMiklos Szeredi 		fuse_dev_free(fud);
2206385a17bfSJeff Dike 	}
2207334f485dSMiklos Szeredi 	return 0;
2208334f485dSMiklos Szeredi }
220908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release);
2210334f485dSMiklos Szeredi 
2211385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on)
2212385a17bfSJeff Dike {
2213cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2214cc080e9eSMiklos Szeredi 
2215cc080e9eSMiklos Szeredi 	if (!fud)
2216a87046d8SMiklos Szeredi 		return -EPERM;
2217385a17bfSJeff Dike 
2218385a17bfSJeff Dike 	/* No locking - fasync_helper does its own locking */
2219cc080e9eSMiklos Szeredi 	return fasync_helper(fd, file, on, &fud->fc->iq.fasync);
2220385a17bfSJeff Dike }
2221385a17bfSJeff Dike 
222200c570f4SMiklos Szeredi static int fuse_device_clone(struct fuse_conn *fc, struct file *new)
222300c570f4SMiklos Szeredi {
2224cc080e9eSMiklos Szeredi 	struct fuse_dev *fud;
2225cc080e9eSMiklos Szeredi 
222600c570f4SMiklos Szeredi 	if (new->private_data)
222700c570f4SMiklos Szeredi 		return -EINVAL;
222800c570f4SMiklos Szeredi 
22290cd1eb9aSVivek Goyal 	fud = fuse_dev_alloc_install(fc);
2230cc080e9eSMiklos Szeredi 	if (!fud)
2231cc080e9eSMiklos Szeredi 		return -ENOMEM;
2232cc080e9eSMiklos Szeredi 
2233cc080e9eSMiklos Szeredi 	new->private_data = fud;
2234c3696046SMiklos Szeredi 	atomic_inc(&fc->dev_count);
223500c570f4SMiklos Szeredi 
223600c570f4SMiklos Szeredi 	return 0;
223700c570f4SMiklos Szeredi }
223800c570f4SMiklos Szeredi 
223900c570f4SMiklos Szeredi static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
224000c570f4SMiklos Szeredi 			   unsigned long arg)
224100c570f4SMiklos Szeredi {
2242f8425c93SAlessio Balsini 	int res;
224300c570f4SMiklos Szeredi 	int oldfd;
2244f8425c93SAlessio Balsini 	struct fuse_dev *fud = NULL;
224500c570f4SMiklos Szeredi 
22466076f5f3SAlessio Balsini 	switch (cmd) {
22476076f5f3SAlessio Balsini 	case FUSE_DEV_IOC_CLONE:
2248f8425c93SAlessio Balsini 		res = -EFAULT;
224900c570f4SMiklos Szeredi 		if (!get_user(oldfd, (__u32 __user *)arg)) {
225000c570f4SMiklos Szeredi 			struct file *old = fget(oldfd);
225100c570f4SMiklos Szeredi 
2252f8425c93SAlessio Balsini 			res = -EINVAL;
225300c570f4SMiklos Szeredi 			if (old) {
22548ed1f0e2SJann Horn 				/*
22558ed1f0e2SJann Horn 				 * Check against file->f_op because CUSE
22568ed1f0e2SJann Horn 				 * uses the same ioctl handler.
22578ed1f0e2SJann Horn 				 */
22588ed1f0e2SJann Horn 				if (old->f_op == file->f_op &&
22598ed1f0e2SJann Horn 				    old->f_cred->user_ns == file->f_cred->user_ns)
22608ed1f0e2SJann Horn 					fud = fuse_get_dev(old);
226100c570f4SMiklos Szeredi 
2262cc080e9eSMiklos Szeredi 				if (fud) {
226300c570f4SMiklos Szeredi 					mutex_lock(&fuse_mutex);
2264f8425c93SAlessio Balsini 					res = fuse_device_clone(fud->fc, file);
226500c570f4SMiklos Szeredi 					mutex_unlock(&fuse_mutex);
226600c570f4SMiklos Szeredi 				}
226700c570f4SMiklos Szeredi 				fput(old);
226800c570f4SMiklos Szeredi 			}
226900c570f4SMiklos Szeredi 		}
2270f8425c93SAlessio Balsini 		break;
2271f8425c93SAlessio Balsini 	default:
2272f8425c93SAlessio Balsini 		res = -ENOTTY;
2273f8425c93SAlessio Balsini 		break;
227400c570f4SMiklos Szeredi 	}
2275f8425c93SAlessio Balsini 	return res;
227600c570f4SMiklos Szeredi }
227700c570f4SMiklos Szeredi 
22784b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = {
2279334f485dSMiklos Szeredi 	.owner		= THIS_MODULE,
228094e4fe2cSTom Van Braeckel 	.open		= fuse_dev_open,
2281334f485dSMiklos Szeredi 	.llseek		= no_llseek,
2282fbdbaccaSAl Viro 	.read_iter	= fuse_dev_read,
2283c3021629SMiklos Szeredi 	.splice_read	= fuse_dev_splice_read,
2284fbdbaccaSAl Viro 	.write_iter	= fuse_dev_write,
2285dd3bb14fSMiklos Szeredi 	.splice_write	= fuse_dev_splice_write,
2286334f485dSMiklos Szeredi 	.poll		= fuse_dev_poll,
2287334f485dSMiklos Szeredi 	.release	= fuse_dev_release,
2288385a17bfSJeff Dike 	.fasync		= fuse_dev_fasync,
228900c570f4SMiklos Szeredi 	.unlocked_ioctl = fuse_dev_ioctl,
22901832f2d8SArnd Bergmann 	.compat_ioctl   = compat_ptr_ioctl,
2291334f485dSMiklos Szeredi };
229208cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations);
2293334f485dSMiklos Szeredi 
2294334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = {
2295334f485dSMiklos Szeredi 	.minor = FUSE_MINOR,
2296334f485dSMiklos Szeredi 	.name  = "fuse",
2297334f485dSMiklos Szeredi 	.fops = &fuse_dev_operations,
2298334f485dSMiklos Szeredi };
2299334f485dSMiklos Szeredi 
2300334f485dSMiklos Szeredi int __init fuse_dev_init(void)
2301334f485dSMiklos Szeredi {
2302334f485dSMiklos Szeredi 	int err = -ENOMEM;
2303334f485dSMiklos Szeredi 	fuse_req_cachep = kmem_cache_create("fuse_request",
2304334f485dSMiklos Szeredi 					    sizeof(struct fuse_req),
230520c2df83SPaul Mundt 					    0, 0, NULL);
2306334f485dSMiklos Szeredi 	if (!fuse_req_cachep)
2307334f485dSMiklos Szeredi 		goto out;
2308334f485dSMiklos Szeredi 
2309334f485dSMiklos Szeredi 	err = misc_register(&fuse_miscdevice);
2310334f485dSMiklos Szeredi 	if (err)
2311334f485dSMiklos Szeredi 		goto out_cache_clean;
2312334f485dSMiklos Szeredi 
2313334f485dSMiklos Szeredi 	return 0;
2314334f485dSMiklos Szeredi 
2315334f485dSMiklos Szeredi  out_cache_clean:
2316334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
2317334f485dSMiklos Szeredi  out:
2318334f485dSMiklos Szeredi 	return err;
2319334f485dSMiklos Szeredi }
2320334f485dSMiklos Szeredi 
2321334f485dSMiklos Szeredi void fuse_dev_cleanup(void)
2322334f485dSMiklos Szeredi {
2323334f485dSMiklos Szeredi 	misc_deregister(&fuse_miscdevice);
2324334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
2325334f485dSMiklos Szeredi }
2326