xref: /openbmc/linux/fs/fuse/dev.c (revision 4f8d3702)
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()
94c4e0cd4eSZheng Yongjun 	 * provides a memory barrier matched 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
291e1e71c16SMiklos Szeredi 	 * changing and below FR_INTERRUPTED check. Pairs with
292217316a6SKirill Tkhai 	 * smp_mb() from queue_interrupt().
293217316a6SKirill Tkhai 	 */
294e1e71c16SMiklos Szeredi 	if (test_bit(FR_INTERRUPTED, &req->flags)) {
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 
31851eb01e7SMiklos Szeredi 		fc->num_background--;
319d12def1bSMiklos Szeredi 		fc->active_background--;
320d12def1bSMiklos Szeredi 		flush_bg_queue(fc);
321ae2dffa3SKirill Tkhai 		spin_unlock(&fc->bg_lock);
3225e0fed71SKirill Tkhai 	} else {
3235e0fed71SKirill Tkhai 		/* Wake up waiter sleeping in request_wait_answer() */
32451eb01e7SMiklos Szeredi 		wake_up(&req->waitq);
3255e0fed71SKirill Tkhai 	}
3265e0fed71SKirill Tkhai 
3273e8cb8b2SMiklos Szeredi 	if (test_bit(FR_ASYNC, &req->flags))
328fcee216bSMax Reitz 		req->args->end(fm, req->args, req->out.h.error);
329b8f95e5dSMiklos Szeredi put_request:
3308f622e94SMax Reitz 	fuse_put_request(req);
331334f485dSMiklos Szeredi }
33204ec5af0SStefan Hajnoczi EXPORT_SYMBOL_GPL(fuse_request_end);
333334f485dSMiklos Szeredi 
3348f622e94SMax Reitz static int queue_interrupt(struct fuse_req *req)
335a4d27e75SMiklos Szeredi {
336fcee216bSMax Reitz 	struct fuse_iqueue *fiq = &req->fm->fc->iq;
3378f622e94SMax Reitz 
33876e43c8cSEric Biggers 	spin_lock(&fiq->lock);
339b782911bSKirill Tkhai 	/* Check for we've sent request to interrupt this req */
340b782911bSKirill Tkhai 	if (unlikely(!test_bit(FR_INTERRUPTED, &req->flags))) {
34176e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
342b782911bSKirill Tkhai 		return -EINVAL;
343b782911bSKirill Tkhai 	}
344b782911bSKirill Tkhai 
345217316a6SKirill Tkhai 	if (list_empty(&req->intr_entry)) {
346217316a6SKirill Tkhai 		list_add_tail(&req->intr_entry, &fiq->interrupts);
347217316a6SKirill Tkhai 		/*
348217316a6SKirill Tkhai 		 * Pairs with smp_mb() implied by test_and_set_bit()
34975d89258SKirill Tkhai 		 * from fuse_request_end().
350217316a6SKirill Tkhai 		 */
351217316a6SKirill Tkhai 		smp_mb();
3526ba4d272SSahitya Tummala 		if (test_bit(FR_FINISHED, &req->flags)) {
353217316a6SKirill Tkhai 			list_del_init(&req->intr_entry);
35476e43c8cSEric Biggers 			spin_unlock(&fiq->lock);
355b782911bSKirill Tkhai 			return 0;
3566ba4d272SSahitya Tummala 		}
357ae3aad77SStefan Hajnoczi 		fiq->ops->wake_interrupt_and_unlock(fiq);
358ae3aad77SStefan Hajnoczi 	} else {
35976e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
360ae3aad77SStefan Hajnoczi 	}
361b782911bSKirill Tkhai 	return 0;
362a4d27e75SMiklos Szeredi }
363a4d27e75SMiklos Szeredi 
3648f622e94SMax Reitz static void request_wait_answer(struct fuse_req *req)
365334f485dSMiklos Szeredi {
366fcee216bSMax Reitz 	struct fuse_conn *fc = req->fm->fc;
3674ce60812SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
368c4775267SMiklos Szeredi 	int err;
369c4775267SMiklos Szeredi 
370a4d27e75SMiklos Szeredi 	if (!fc->no_interrupt) {
371a4d27e75SMiklos Szeredi 		/* Any signal may interrupt this */
372c4775267SMiklos Szeredi 		err = wait_event_interruptible(req->waitq,
37333e14b4dSMiklos Szeredi 					test_bit(FR_FINISHED, &req->flags));
374c4775267SMiklos Szeredi 		if (!err)
375334f485dSMiklos Szeredi 			return;
376334f485dSMiklos Szeredi 
377825d6d33SMiklos Szeredi 		set_bit(FR_INTERRUPTED, &req->flags);
3788f7bb368SMiklos Szeredi 		/* matches barrier in fuse_dev_do_read() */
3798f7bb368SMiklos Szeredi 		smp_mb__after_atomic();
38033e14b4dSMiklos Szeredi 		if (test_bit(FR_SENT, &req->flags))
3818f622e94SMax Reitz 			queue_interrupt(req);
382a4d27e75SMiklos Szeredi 	}
383a4d27e75SMiklos Szeredi 
384825d6d33SMiklos Szeredi 	if (!test_bit(FR_FORCE, &req->flags)) {
385a4d27e75SMiklos Szeredi 		/* Only fatal signals may interrupt this */
3867d3a07fcSAl Viro 		err = wait_event_killable(req->waitq,
38733e14b4dSMiklos Szeredi 					test_bit(FR_FINISHED, &req->flags));
388c4775267SMiklos Szeredi 		if (!err)
389a4d27e75SMiklos Szeredi 			return;
390a4d27e75SMiklos Szeredi 
39176e43c8cSEric Biggers 		spin_lock(&fiq->lock);
392a131de0aSMiklos Szeredi 		/* Request is not yet in userspace, bail out */
39333e14b4dSMiklos Szeredi 		if (test_bit(FR_PENDING, &req->flags)) {
394a131de0aSMiklos Szeredi 			list_del(&req->list);
39576e43c8cSEric Biggers 			spin_unlock(&fiq->lock);
396a131de0aSMiklos Szeredi 			__fuse_put_request(req);
397334f485dSMiklos Szeredi 			req->out.h.error = -EINTR;
398a131de0aSMiklos Szeredi 			return;
399a131de0aSMiklos Szeredi 		}
40076e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
401a131de0aSMiklos Szeredi 	}
402a131de0aSMiklos Szeredi 
403a131de0aSMiklos Szeredi 	/*
404a131de0aSMiklos Szeredi 	 * Either request is already in userspace, or it was forced.
405a131de0aSMiklos Szeredi 	 * Wait it out.
406a131de0aSMiklos Szeredi 	 */
40733e14b4dSMiklos Szeredi 	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
408334f485dSMiklos Szeredi }
409334f485dSMiklos Szeredi 
4108f622e94SMax Reitz static void __fuse_request_send(struct fuse_req *req)
411334f485dSMiklos Szeredi {
412fcee216bSMax Reitz 	struct fuse_iqueue *fiq = &req->fm->fc->iq;
413e16714d8SMiklos Szeredi 
414825d6d33SMiklos Szeredi 	BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
41576e43c8cSEric Biggers 	spin_lock(&fiq->lock);
416e16714d8SMiklos Szeredi 	if (!fiq->connected) {
41776e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
418334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
419c4775267SMiklos Szeredi 	} else {
420f88996a9SMiklos Szeredi 		req->in.h.unique = fuse_get_unique(fiq);
421334f485dSMiklos Szeredi 		/* acquire extra reference, since request is still needed
42204ec5af0SStefan Hajnoczi 		   after fuse_request_end() */
423334f485dSMiklos Szeredi 		__fuse_get_request(req);
424ae3aad77SStefan Hajnoczi 		queue_request_and_unlock(fiq, req);
425334f485dSMiklos Szeredi 
4268f622e94SMax Reitz 		request_wait_answer(req);
42704ec5af0SStefan Hajnoczi 		/* Pairs with smp_wmb() in fuse_request_end() */
428c4775267SMiklos Szeredi 		smp_rmb();
429334f485dSMiklos Szeredi 	}
430334f485dSMiklos Szeredi }
4316a4e922cSEric Wong 
43221f62174SMiklos Szeredi static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args)
43321f62174SMiklos Szeredi {
434d5b48543SMiklos Szeredi 	if (fc->minor < 4 && args->opcode == FUSE_STATFS)
435d5b48543SMiklos Szeredi 		args->out_args[0].size = FUSE_COMPAT_STATFS_SIZE;
43621f62174SMiklos Szeredi 
43721f62174SMiklos Szeredi 	if (fc->minor < 9) {
438d5b48543SMiklos Szeredi 		switch (args->opcode) {
43921f62174SMiklos Szeredi 		case FUSE_LOOKUP:
44021f62174SMiklos Szeredi 		case FUSE_CREATE:
44121f62174SMiklos Szeredi 		case FUSE_MKNOD:
44221f62174SMiklos Szeredi 		case FUSE_MKDIR:
44321f62174SMiklos Szeredi 		case FUSE_SYMLINK:
44421f62174SMiklos Szeredi 		case FUSE_LINK:
445d5b48543SMiklos Szeredi 			args->out_args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
44621f62174SMiklos Szeredi 			break;
44721f62174SMiklos Szeredi 		case FUSE_GETATTR:
44821f62174SMiklos Szeredi 		case FUSE_SETATTR:
449d5b48543SMiklos Szeredi 			args->out_args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
45021f62174SMiklos Szeredi 			break;
45121f62174SMiklos Szeredi 		}
45221f62174SMiklos Szeredi 	}
45321f62174SMiklos Szeredi 	if (fc->minor < 12) {
454d5b48543SMiklos Szeredi 		switch (args->opcode) {
45521f62174SMiklos Szeredi 		case FUSE_CREATE:
456d5b48543SMiklos Szeredi 			args->in_args[0].size = sizeof(struct fuse_open_in);
45721f62174SMiklos Szeredi 			break;
45821f62174SMiklos Szeredi 		case FUSE_MKNOD:
459d5b48543SMiklos Szeredi 			args->in_args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE;
46021f62174SMiklos Szeredi 			break;
46121f62174SMiklos Szeredi 		}
46221f62174SMiklos Szeredi 	}
46321f62174SMiklos Szeredi }
46421f62174SMiklos Szeredi 
4658f622e94SMax Reitz static void fuse_force_creds(struct fuse_req *req)
466e413754bSMiklos Szeredi {
467fcee216bSMax Reitz 	struct fuse_conn *fc = req->fm->fc;
4688f622e94SMax Reitz 
469e413754bSMiklos Szeredi 	req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
470e413754bSMiklos Szeredi 	req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid());
471e413754bSMiklos Szeredi 	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
472e413754bSMiklos Szeredi }
473e413754bSMiklos Szeredi 
4745addcd5dSYueHaibing static void fuse_args_to_req(struct fuse_req *req, struct fuse_args *args)
47568583165SMiklos Szeredi {
47668583165SMiklos Szeredi 	req->in.h.opcode = args->opcode;
47768583165SMiklos Szeredi 	req->in.h.nodeid = args->nodeid;
478d4993774SMiklos Szeredi 	req->args = args;
4793e8cb8b2SMiklos Szeredi 	if (args->end)
4803e8cb8b2SMiklos Szeredi 		__set_bit(FR_ASYNC, &req->flags);
48168583165SMiklos Szeredi }
48268583165SMiklos Szeredi 
483fcee216bSMax Reitz ssize_t fuse_simple_request(struct fuse_mount *fm, struct fuse_args *args)
4847078187aSMiklos Szeredi {
485fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
4867078187aSMiklos Szeredi 	struct fuse_req *req;
4877078187aSMiklos Szeredi 	ssize_t ret;
4887078187aSMiklos Szeredi 
489c500ebaaSMiklos Szeredi 	if (args->force) {
490e413754bSMiklos Szeredi 		atomic_inc(&fc->num_waiting);
491fcee216bSMax Reitz 		req = fuse_request_alloc(fm, GFP_KERNEL | __GFP_NOFAIL);
492e413754bSMiklos Szeredi 
493e413754bSMiklos Szeredi 		if (!args->nocreds)
4948f622e94SMax Reitz 			fuse_force_creds(req);
495e413754bSMiklos Szeredi 
496e413754bSMiklos Szeredi 		__set_bit(FR_WAITING, &req->flags);
497c500ebaaSMiklos Szeredi 		__set_bit(FR_FORCE, &req->flags);
498c500ebaaSMiklos Szeredi 	} else {
499e413754bSMiklos Szeredi 		WARN_ON(args->nocreds);
500fcee216bSMax Reitz 		req = fuse_get_req(fm, false);
5017078187aSMiklos Szeredi 		if (IS_ERR(req))
5027078187aSMiklos Szeredi 			return PTR_ERR(req);
503c500ebaaSMiklos Szeredi 	}
5047078187aSMiklos Szeredi 
50521f62174SMiklos Szeredi 	/* Needs to be done after fuse_get_req() so that fc->minor is valid */
50621f62174SMiklos Szeredi 	fuse_adjust_compat(fc, args);
50768583165SMiklos Szeredi 	fuse_args_to_req(req, args);
50821f62174SMiklos Szeredi 
509454a7613SMiklos Szeredi 	if (!args->noreply)
510454a7613SMiklos Szeredi 		__set_bit(FR_ISREPLY, &req->flags);
5118f622e94SMax Reitz 	__fuse_request_send(req);
5127078187aSMiklos Szeredi 	ret = req->out.h.error;
513d5b48543SMiklos Szeredi 	if (!ret && args->out_argvar) {
514093f38a2SMiklos Szeredi 		BUG_ON(args->out_numargs == 0);
515d4993774SMiklos Szeredi 		ret = args->out_args[args->out_numargs - 1].size;
5167078187aSMiklos Szeredi 	}
5178f622e94SMax Reitz 	fuse_put_request(req);
5187078187aSMiklos Szeredi 
5197078187aSMiklos Szeredi 	return ret;
5207078187aSMiklos Szeredi }
5217078187aSMiklos Szeredi 
5228f622e94SMax Reitz static bool fuse_request_queue_background(struct fuse_req *req)
523334f485dSMiklos Szeredi {
524fcee216bSMax Reitz 	struct fuse_mount *fm = req->fm;
525fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
52663825b4eSKirill Tkhai 	bool queued = false;
52763825b4eSKirill Tkhai 
52863825b4eSKirill Tkhai 	WARN_ON(!test_bit(FR_BACKGROUND, &req->flags));
529825d6d33SMiklos Szeredi 	if (!test_bit(FR_WAITING, &req->flags)) {
530825d6d33SMiklos Szeredi 		__set_bit(FR_WAITING, &req->flags);
5315437f241SMiklos Szeredi 		atomic_inc(&fc->num_waiting);
5325437f241SMiklos Szeredi 	}
533825d6d33SMiklos Szeredi 	__set_bit(FR_ISREPLY, &req->flags);
534ae2dffa3SKirill Tkhai 	spin_lock(&fc->bg_lock);
53563825b4eSKirill Tkhai 	if (likely(fc->connected)) {
53651eb01e7SMiklos Szeredi 		fc->num_background++;
5377a6d3c8bSCsaba Henk 		if (fc->num_background == fc->max_background)
53851eb01e7SMiklos Szeredi 			fc->blocked = 1;
539d12def1bSMiklos Szeredi 		list_add_tail(&req->list, &fc->bg_queue);
540d12def1bSMiklos Szeredi 		flush_bg_queue(fc);
54163825b4eSKirill Tkhai 		queued = true;
54263825b4eSKirill Tkhai 	}
543ae2dffa3SKirill Tkhai 	spin_unlock(&fc->bg_lock);
54463825b4eSKirill Tkhai 
54563825b4eSKirill Tkhai 	return queued;
546d12def1bSMiklos Szeredi }
54751eb01e7SMiklos Szeredi 
548fcee216bSMax Reitz int fuse_simple_background(struct fuse_mount *fm, struct fuse_args *args,
54912597287SMiklos Szeredi 			    gfp_t gfp_flags)
55012597287SMiklos Szeredi {
55112597287SMiklos Szeredi 	struct fuse_req *req;
55212597287SMiklos Szeredi 
55312597287SMiklos Szeredi 	if (args->force) {
55412597287SMiklos Szeredi 		WARN_ON(!args->nocreds);
555fcee216bSMax Reitz 		req = fuse_request_alloc(fm, gfp_flags);
55612597287SMiklos Szeredi 		if (!req)
55712597287SMiklos Szeredi 			return -ENOMEM;
55812597287SMiklos Szeredi 		__set_bit(FR_BACKGROUND, &req->flags);
55912597287SMiklos Szeredi 	} else {
56012597287SMiklos Szeredi 		WARN_ON(args->nocreds);
561fcee216bSMax Reitz 		req = fuse_get_req(fm, true);
56212597287SMiklos Szeredi 		if (IS_ERR(req))
56312597287SMiklos Szeredi 			return PTR_ERR(req);
56412597287SMiklos Szeredi 	}
56512597287SMiklos Szeredi 
56612597287SMiklos Szeredi 	fuse_args_to_req(req, args);
56712597287SMiklos Szeredi 
5688f622e94SMax Reitz 	if (!fuse_request_queue_background(req)) {
5698f622e94SMax Reitz 		fuse_put_request(req);
57012597287SMiklos Szeredi 		return -ENOTCONN;
57112597287SMiklos Szeredi 	}
57212597287SMiklos Szeredi 
57312597287SMiklos Szeredi 	return 0;
57412597287SMiklos Szeredi }
57512597287SMiklos Szeredi EXPORT_SYMBOL_GPL(fuse_simple_background);
57612597287SMiklos Szeredi 
577fcee216bSMax Reitz static int fuse_simple_notify_reply(struct fuse_mount *fm,
57875b399ddSMiklos Szeredi 				    struct fuse_args *args, u64 unique)
5792d45ba38SMiklos Szeredi {
58075b399ddSMiklos Szeredi 	struct fuse_req *req;
581fcee216bSMax Reitz 	struct fuse_iqueue *fiq = &fm->fc->iq;
58275b399ddSMiklos Szeredi 	int err = 0;
58375b399ddSMiklos Szeredi 
584fcee216bSMax Reitz 	req = fuse_get_req(fm, false);
58575b399ddSMiklos Szeredi 	if (IS_ERR(req))
58675b399ddSMiklos Szeredi 		return PTR_ERR(req);
5872d45ba38SMiklos Szeredi 
588825d6d33SMiklos Szeredi 	__clear_bit(FR_ISREPLY, &req->flags);
5892d45ba38SMiklos Szeredi 	req->in.h.unique = unique;
59075b399ddSMiklos Szeredi 
59175b399ddSMiklos Szeredi 	fuse_args_to_req(req, args);
59275b399ddSMiklos Szeredi 
59376e43c8cSEric Biggers 	spin_lock(&fiq->lock);
594e16714d8SMiklos Szeredi 	if (fiq->connected) {
595ae3aad77SStefan Hajnoczi 		queue_request_and_unlock(fiq, req);
59675b399ddSMiklos Szeredi 	} else {
59775b399ddSMiklos Szeredi 		err = -ENODEV;
59875b399ddSMiklos Szeredi 		spin_unlock(&fiq->lock);
5998f622e94SMax Reitz 		fuse_put_request(req);
6002d45ba38SMiklos Szeredi 	}
6012d45ba38SMiklos Szeredi 
6022d45ba38SMiklos Szeredi 	return err;
6032d45ba38SMiklos Szeredi }
6042d45ba38SMiklos Szeredi 
6053be5a52bSMiklos Szeredi /*
606334f485dSMiklos Szeredi  * Lock the request.  Up to the next unlock_request() there mustn't be
607334f485dSMiklos Szeredi  * anything that could cause a page-fault.  If the request was already
608f9a2842eSMiklos Szeredi  * aborted bail out.
609334f485dSMiklos Szeredi  */
610dc00809aSMiklos Szeredi static int lock_request(struct fuse_req *req)
611334f485dSMiklos Szeredi {
612334f485dSMiklos Szeredi 	int err = 0;
613334f485dSMiklos Szeredi 	if (req) {
614dc00809aSMiklos Szeredi 		spin_lock(&req->waitq.lock);
615825d6d33SMiklos Szeredi 		if (test_bit(FR_ABORTED, &req->flags))
616334f485dSMiklos Szeredi 			err = -ENOENT;
617334f485dSMiklos Szeredi 		else
618825d6d33SMiklos Szeredi 			set_bit(FR_LOCKED, &req->flags);
619dc00809aSMiklos Szeredi 		spin_unlock(&req->waitq.lock);
620334f485dSMiklos Szeredi 	}
621334f485dSMiklos Szeredi 	return err;
622334f485dSMiklos Szeredi }
623334f485dSMiklos Szeredi 
624334f485dSMiklos Szeredi /*
6250d8e84b0SMiklos Szeredi  * Unlock request.  If it was aborted while locked, caller is responsible
6260d8e84b0SMiklos Szeredi  * for unlocking and ending the request.
627334f485dSMiklos Szeredi  */
628dc00809aSMiklos Szeredi static int unlock_request(struct fuse_req *req)
629334f485dSMiklos Szeredi {
6300d8e84b0SMiklos Szeredi 	int err = 0;
631334f485dSMiklos Szeredi 	if (req) {
632dc00809aSMiklos Szeredi 		spin_lock(&req->waitq.lock);
633825d6d33SMiklos Szeredi 		if (test_bit(FR_ABORTED, &req->flags))
6340d8e84b0SMiklos Szeredi 			err = -ENOENT;
6350d8e84b0SMiklos Szeredi 		else
636825d6d33SMiklos Szeredi 			clear_bit(FR_LOCKED, &req->flags);
637dc00809aSMiklos Szeredi 		spin_unlock(&req->waitq.lock);
638334f485dSMiklos Szeredi 	}
6390d8e84b0SMiklos Szeredi 	return err;
640334f485dSMiklos Szeredi }
641334f485dSMiklos Szeredi 
642334f485dSMiklos Szeredi struct fuse_copy_state {
643334f485dSMiklos Szeredi 	int write;
644334f485dSMiklos Szeredi 	struct fuse_req *req;
6456c09e94aSAl Viro 	struct iov_iter *iter;
646dd3bb14fSMiklos Szeredi 	struct pipe_buffer *pipebufs;
647dd3bb14fSMiklos Szeredi 	struct pipe_buffer *currbuf;
648dd3bb14fSMiklos Szeredi 	struct pipe_inode_info *pipe;
649334f485dSMiklos Szeredi 	unsigned long nr_segs;
650334f485dSMiklos Szeredi 	struct page *pg;
651334f485dSMiklos Szeredi 	unsigned len;
652c55a01d3SMiklos Szeredi 	unsigned offset;
653ce534fb0SMiklos Szeredi 	unsigned move_pages:1;
654334f485dSMiklos Szeredi };
655334f485dSMiklos Szeredi 
656dc00809aSMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, int write,
6576c09e94aSAl Viro 			   struct iov_iter *iter)
658334f485dSMiklos Szeredi {
659334f485dSMiklos Szeredi 	memset(cs, 0, sizeof(*cs));
660334f485dSMiklos Szeredi 	cs->write = write;
6616c09e94aSAl Viro 	cs->iter = iter;
662334f485dSMiklos Szeredi }
663334f485dSMiklos Szeredi 
664334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */
6658bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs)
666334f485dSMiklos Szeredi {
667dd3bb14fSMiklos Szeredi 	if (cs->currbuf) {
668dd3bb14fSMiklos Szeredi 		struct pipe_buffer *buf = cs->currbuf;
669dd3bb14fSMiklos Szeredi 
670c55a01d3SMiklos Szeredi 		if (cs->write)
671c3021629SMiklos Szeredi 			buf->len = PAGE_SIZE - cs->len;
672dd3bb14fSMiklos Szeredi 		cs->currbuf = NULL;
673c55a01d3SMiklos Szeredi 	} else if (cs->pg) {
674334f485dSMiklos Szeredi 		if (cs->write) {
675334f485dSMiklos Szeredi 			flush_dcache_page(cs->pg);
676334f485dSMiklos Szeredi 			set_page_dirty_lock(cs->pg);
677334f485dSMiklos Szeredi 		}
678334f485dSMiklos Szeredi 		put_page(cs->pg);
679334f485dSMiklos Szeredi 	}
680c55a01d3SMiklos Szeredi 	cs->pg = NULL;
681334f485dSMiklos Szeredi }
682334f485dSMiklos Szeredi 
683334f485dSMiklos Szeredi /*
684334f485dSMiklos Szeredi  * Get another pagefull of userspace buffer, and map it to kernel
685334f485dSMiklos Szeredi  * address space, and lock request
686334f485dSMiklos Szeredi  */
687334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs)
688334f485dSMiklos Szeredi {
689c55a01d3SMiklos Szeredi 	struct page *page;
690334f485dSMiklos Szeredi 	int err;
691334f485dSMiklos Szeredi 
692dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
6930d8e84b0SMiklos Szeredi 	if (err)
6940d8e84b0SMiklos Szeredi 		return err;
6950d8e84b0SMiklos Szeredi 
696334f485dSMiklos Szeredi 	fuse_copy_finish(cs);
697dd3bb14fSMiklos Szeredi 	if (cs->pipebufs) {
698dd3bb14fSMiklos Szeredi 		struct pipe_buffer *buf = cs->pipebufs;
699dd3bb14fSMiklos Szeredi 
700c3021629SMiklos Szeredi 		if (!cs->write) {
701fba597dbSMiklos Szeredi 			err = pipe_buf_confirm(cs->pipe, buf);
702dd3bb14fSMiklos Szeredi 			if (err)
703dd3bb14fSMiklos Szeredi 				return err;
704dd3bb14fSMiklos Szeredi 
705dd3bb14fSMiklos Szeredi 			BUG_ON(!cs->nr_segs);
706dd3bb14fSMiklos Szeredi 			cs->currbuf = buf;
707c55a01d3SMiklos Szeredi 			cs->pg = buf->page;
708c55a01d3SMiklos Szeredi 			cs->offset = buf->offset;
709dd3bb14fSMiklos Szeredi 			cs->len = buf->len;
710dd3bb14fSMiklos Szeredi 			cs->pipebufs++;
711dd3bb14fSMiklos Szeredi 			cs->nr_segs--;
712dd3bb14fSMiklos Szeredi 		} else {
7136718b6f8SDavid Howells 			if (cs->nr_segs >= cs->pipe->max_usage)
714c3021629SMiklos Szeredi 				return -EIO;
715c3021629SMiklos Szeredi 
716c3021629SMiklos Szeredi 			page = alloc_page(GFP_HIGHUSER);
717c3021629SMiklos Szeredi 			if (!page)
718c3021629SMiklos Szeredi 				return -ENOMEM;
719c3021629SMiklos Szeredi 
720c3021629SMiklos Szeredi 			buf->page = page;
721c3021629SMiklos Szeredi 			buf->offset = 0;
722c3021629SMiklos Szeredi 			buf->len = 0;
723c3021629SMiklos Szeredi 
724c3021629SMiklos Szeredi 			cs->currbuf = buf;
725c55a01d3SMiklos Szeredi 			cs->pg = page;
726c55a01d3SMiklos Szeredi 			cs->offset = 0;
727c3021629SMiklos Szeredi 			cs->len = PAGE_SIZE;
728c3021629SMiklos Szeredi 			cs->pipebufs++;
729c3021629SMiklos Szeredi 			cs->nr_segs++;
730c3021629SMiklos Szeredi 		}
731c3021629SMiklos Szeredi 	} else {
7326c09e94aSAl Viro 		size_t off;
7331ef255e2SAl Viro 		err = iov_iter_get_pages2(cs->iter, &page, PAGE_SIZE, 1, &off);
734334f485dSMiklos Szeredi 		if (err < 0)
735334f485dSMiklos Szeredi 			return err;
7366c09e94aSAl Viro 		BUG_ON(!err);
7376c09e94aSAl Viro 		cs->len = err;
7386c09e94aSAl Viro 		cs->offset = off;
739c55a01d3SMiklos Szeredi 		cs->pg = page;
740dd3bb14fSMiklos Szeredi 	}
741334f485dSMiklos Szeredi 
742dc00809aSMiklos Szeredi 	return lock_request(cs->req);
743334f485dSMiklos Szeredi }
744334f485dSMiklos Szeredi 
745334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */
7468bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
747334f485dSMiklos Szeredi {
748334f485dSMiklos Szeredi 	unsigned ncpy = min(*size, cs->len);
749334f485dSMiklos Szeredi 	if (val) {
7505fe0fc9fSPeng Hao 		void *pgaddr = kmap_local_page(cs->pg);
751c55a01d3SMiklos Szeredi 		void *buf = pgaddr + cs->offset;
752c55a01d3SMiklos Szeredi 
753334f485dSMiklos Szeredi 		if (cs->write)
754c55a01d3SMiklos Szeredi 			memcpy(buf, *val, ncpy);
755334f485dSMiklos Szeredi 		else
756c55a01d3SMiklos Szeredi 			memcpy(*val, buf, ncpy);
757c55a01d3SMiklos Szeredi 
7585fe0fc9fSPeng Hao 		kunmap_local(pgaddr);
759334f485dSMiklos Szeredi 		*val += ncpy;
760334f485dSMiklos Szeredi 	}
761334f485dSMiklos Szeredi 	*size -= ncpy;
762334f485dSMiklos Szeredi 	cs->len -= ncpy;
763c55a01d3SMiklos Szeredi 	cs->offset += ncpy;
764334f485dSMiklos Szeredi 	return ncpy;
765334f485dSMiklos Szeredi }
766334f485dSMiklos Szeredi 
767ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page)
768ce534fb0SMiklos Szeredi {
769ce534fb0SMiklos Szeredi 	if (page_mapcount(page) ||
770ce534fb0SMiklos Szeredi 	    page->mapping != NULL ||
771ce534fb0SMiklos Szeredi 	    (page->flags & PAGE_FLAGS_CHECK_AT_PREP &
772ce534fb0SMiklos Szeredi 	     ~(1 << PG_locked |
773ce534fb0SMiklos Szeredi 	       1 << PG_referenced |
774ce534fb0SMiklos Szeredi 	       1 << PG_uptodate |
775ce534fb0SMiklos Szeredi 	       1 << PG_lru |
776ce534fb0SMiklos Szeredi 	       1 << PG_active |
777b89ecd60SMiklos Szeredi 	       1 << PG_workingset |
778a5005c3cSMiklos Szeredi 	       1 << PG_reclaim |
779ec1c86b2SYu Zhao 	       1 << PG_waiters |
780ec1c86b2SYu Zhao 	       LRU_GEN_MASK | LRU_REFS_MASK))) {
78100589386SMiklos Szeredi 		dump_page(page, "fuse: trying to steal weird page");
782ce534fb0SMiklos Szeredi 		return 1;
783ce534fb0SMiklos Szeredi 	}
784ce534fb0SMiklos Szeredi 	return 0;
785ce534fb0SMiklos Szeredi }
786ce534fb0SMiklos Szeredi 
787ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
788ce534fb0SMiklos Szeredi {
789ce534fb0SMiklos Szeredi 	int err;
790ce534fb0SMiklos Szeredi 	struct page *oldpage = *pagep;
791ce534fb0SMiklos Szeredi 	struct page *newpage;
792ce534fb0SMiklos Szeredi 	struct pipe_buffer *buf = cs->pipebufs;
793ce534fb0SMiklos Szeredi 
794d78092e4SMiklos Szeredi 	get_page(oldpage);
795dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
7960d8e84b0SMiklos Szeredi 	if (err)
797d78092e4SMiklos Szeredi 		goto out_put_old;
7980d8e84b0SMiklos Szeredi 
799ce534fb0SMiklos Szeredi 	fuse_copy_finish(cs);
800ce534fb0SMiklos Szeredi 
801fba597dbSMiklos Szeredi 	err = pipe_buf_confirm(cs->pipe, buf);
802ce534fb0SMiklos Szeredi 	if (err)
803d78092e4SMiklos Szeredi 		goto out_put_old;
804ce534fb0SMiklos Szeredi 
805ce534fb0SMiklos Szeredi 	BUG_ON(!cs->nr_segs);
806ce534fb0SMiklos Szeredi 	cs->currbuf = buf;
807ce534fb0SMiklos Szeredi 	cs->len = buf->len;
808ce534fb0SMiklos Szeredi 	cs->pipebufs++;
809ce534fb0SMiklos Szeredi 	cs->nr_segs--;
810ce534fb0SMiklos Szeredi 
811ce534fb0SMiklos Szeredi 	if (cs->len != PAGE_SIZE)
812ce534fb0SMiklos Szeredi 		goto out_fallback;
813ce534fb0SMiklos Szeredi 
814c928f642SChristoph Hellwig 	if (!pipe_buf_try_steal(cs->pipe, buf))
815ce534fb0SMiklos Szeredi 		goto out_fallback;
816ce534fb0SMiklos Szeredi 
817ce534fb0SMiklos Szeredi 	newpage = buf->page;
818ce534fb0SMiklos Szeredi 
819aa991b3bSMiklos Szeredi 	if (!PageUptodate(newpage))
820aa991b3bSMiklos Szeredi 		SetPageUptodate(newpage);
821ce534fb0SMiklos Szeredi 
822ce534fb0SMiklos Szeredi 	ClearPageMappedToDisk(newpage);
823ce534fb0SMiklos Szeredi 
824ce534fb0SMiklos Szeredi 	if (fuse_check_page(newpage) != 0)
825ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
826ce534fb0SMiklos Szeredi 
827ce534fb0SMiklos Szeredi 	/*
828ce534fb0SMiklos Szeredi 	 * This is a new and locked page, it shouldn't be mapped or
829ce534fb0SMiklos Szeredi 	 * have any special flags on it
830ce534fb0SMiklos Szeredi 	 */
831ce534fb0SMiklos Szeredi 	if (WARN_ON(page_mapped(oldpage)))
832ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
833ce534fb0SMiklos Szeredi 	if (WARN_ON(page_has_private(oldpage)))
834ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
835ce534fb0SMiklos Szeredi 	if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage)))
836ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
837ce534fb0SMiklos Szeredi 	if (WARN_ON(PageMlocked(oldpage)))
838ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
839ce534fb0SMiklos Szeredi 
8401f7ef657SBaolin Wang 	replace_page_cache_page(oldpage, newpage);
841ef6a3c63SMiklos Szeredi 
84247344172SMiklos Szeredi 	get_page(newpage);
84347344172SMiklos Szeredi 
84447344172SMiklos Szeredi 	if (!(buf->flags & PIPE_BUF_FLAG_LRU))
84547344172SMiklos Szeredi 		lru_cache_add(newpage);
84647344172SMiklos Szeredi 
847712a9510SMiklos Szeredi 	/*
848712a9510SMiklos Szeredi 	 * Release while we have extra ref on stolen page.  Otherwise
849712a9510SMiklos Szeredi 	 * anon_pipe_buf_release() might think the page can be reused.
850712a9510SMiklos Szeredi 	 */
851712a9510SMiklos Szeredi 	pipe_buf_release(cs->pipe, buf);
852712a9510SMiklos Szeredi 
853ce534fb0SMiklos Szeredi 	err = 0;
854dc00809aSMiklos Szeredi 	spin_lock(&cs->req->waitq.lock);
855825d6d33SMiklos Szeredi 	if (test_bit(FR_ABORTED, &cs->req->flags))
856ce534fb0SMiklos Szeredi 		err = -ENOENT;
857ce534fb0SMiklos Szeredi 	else
858ce534fb0SMiklos Szeredi 		*pagep = newpage;
859dc00809aSMiklos Szeredi 	spin_unlock(&cs->req->waitq.lock);
860ce534fb0SMiklos Szeredi 
861ce534fb0SMiklos Szeredi 	if (err) {
862ce534fb0SMiklos Szeredi 		unlock_page(newpage);
86309cbfeafSKirill A. Shutemov 		put_page(newpage);
864d78092e4SMiklos Szeredi 		goto out_put_old;
865ce534fb0SMiklos Szeredi 	}
866ce534fb0SMiklos Szeredi 
867ce534fb0SMiklos Szeredi 	unlock_page(oldpage);
868d78092e4SMiklos Szeredi 	/* Drop ref for ap->pages[] array */
86909cbfeafSKirill A. Shutemov 	put_page(oldpage);
870ce534fb0SMiklos Szeredi 	cs->len = 0;
871ce534fb0SMiklos Szeredi 
872d78092e4SMiklos Szeredi 	err = 0;
873d78092e4SMiklos Szeredi out_put_old:
874d78092e4SMiklos Szeredi 	/* Drop ref obtained in this function */
875d78092e4SMiklos Szeredi 	put_page(oldpage);
876d78092e4SMiklos Szeredi 	return err;
877ce534fb0SMiklos Szeredi 
878ce534fb0SMiklos Szeredi out_fallback_unlock:
879ce534fb0SMiklos Szeredi 	unlock_page(newpage);
880ce534fb0SMiklos Szeredi out_fallback:
881c55a01d3SMiklos Szeredi 	cs->pg = buf->page;
882c55a01d3SMiklos Szeredi 	cs->offset = buf->offset;
883ce534fb0SMiklos Szeredi 
884dc00809aSMiklos Szeredi 	err = lock_request(cs->req);
885d78092e4SMiklos Szeredi 	if (!err)
886d78092e4SMiklos Szeredi 		err = 1;
887ce534fb0SMiklos Szeredi 
888d78092e4SMiklos Szeredi 	goto out_put_old;
889ce534fb0SMiklos Szeredi }
890ce534fb0SMiklos Szeredi 
891c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
892c3021629SMiklos Szeredi 			 unsigned offset, unsigned count)
893c3021629SMiklos Szeredi {
894c3021629SMiklos Szeredi 	struct pipe_buffer *buf;
8950d8e84b0SMiklos Szeredi 	int err;
896c3021629SMiklos Szeredi 
8976718b6f8SDavid Howells 	if (cs->nr_segs >= cs->pipe->max_usage)
898c3021629SMiklos Szeredi 		return -EIO;
899c3021629SMiklos Szeredi 
900d78092e4SMiklos Szeredi 	get_page(page);
901dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
902d78092e4SMiklos Szeredi 	if (err) {
903d78092e4SMiklos Szeredi 		put_page(page);
9040d8e84b0SMiklos Szeredi 		return err;
905d78092e4SMiklos Szeredi 	}
9060d8e84b0SMiklos Szeredi 
907c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
908c3021629SMiklos Szeredi 
909c3021629SMiklos Szeredi 	buf = cs->pipebufs;
910c3021629SMiklos Szeredi 	buf->page = page;
911c3021629SMiklos Szeredi 	buf->offset = offset;
912c3021629SMiklos Szeredi 	buf->len = count;
913c3021629SMiklos Szeredi 
914c3021629SMiklos Szeredi 	cs->pipebufs++;
915c3021629SMiklos Szeredi 	cs->nr_segs++;
916c3021629SMiklos Szeredi 	cs->len = 0;
917c3021629SMiklos Szeredi 
918c3021629SMiklos Szeredi 	return 0;
919c3021629SMiklos Szeredi }
920c3021629SMiklos Szeredi 
921334f485dSMiklos Szeredi /*
922334f485dSMiklos Szeredi  * Copy a page in the request to/from the userspace buffer.  Must be
923334f485dSMiklos Szeredi  * done atomically
924334f485dSMiklos Szeredi  */
925ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
926334f485dSMiklos Szeredi 			  unsigned offset, unsigned count, int zeroing)
927334f485dSMiklos Szeredi {
928ce534fb0SMiklos Szeredi 	int err;
929ce534fb0SMiklos Szeredi 	struct page *page = *pagep;
930ce534fb0SMiklos Szeredi 
931b6777c40SMiklos Szeredi 	if (page && zeroing && count < PAGE_SIZE)
932b6777c40SMiklos Szeredi 		clear_highpage(page);
933b6777c40SMiklos Szeredi 
934334f485dSMiklos Szeredi 	while (count) {
935c3021629SMiklos Szeredi 		if (cs->write && cs->pipebufs && page) {
9360c4bcfdeSMiklos Szeredi 			/*
9370c4bcfdeSMiklos Szeredi 			 * Can't control lifetime of pipe buffers, so always
9380c4bcfdeSMiklos Szeredi 			 * copy user pages.
9390c4bcfdeSMiklos Szeredi 			 */
9400c4bcfdeSMiklos Szeredi 			if (cs->req->args->user_pages) {
9410c4bcfdeSMiklos Szeredi 				err = fuse_copy_fill(cs);
9420c4bcfdeSMiklos Szeredi 				if (err)
9430c4bcfdeSMiklos Szeredi 					return err;
9440c4bcfdeSMiklos Szeredi 			} else {
945c3021629SMiklos Szeredi 				return fuse_ref_page(cs, page, offset, count);
9460c4bcfdeSMiklos Szeredi 			}
947c3021629SMiklos Szeredi 		} else if (!cs->len) {
948ce534fb0SMiklos Szeredi 			if (cs->move_pages && page &&
949ce534fb0SMiklos Szeredi 			    offset == 0 && count == PAGE_SIZE) {
950ce534fb0SMiklos Szeredi 				err = fuse_try_move_page(cs, pagep);
951ce534fb0SMiklos Szeredi 				if (err <= 0)
952ce534fb0SMiklos Szeredi 					return err;
953ce534fb0SMiklos Szeredi 			} else {
954ce534fb0SMiklos Szeredi 				err = fuse_copy_fill(cs);
9551729a16cSMiklos Szeredi 				if (err)
956334f485dSMiklos Szeredi 					return err;
9571729a16cSMiklos Szeredi 			}
958ce534fb0SMiklos Szeredi 		}
959334f485dSMiklos Szeredi 		if (page) {
9605fe0fc9fSPeng Hao 			void *mapaddr = kmap_local_page(page);
961334f485dSMiklos Szeredi 			void *buf = mapaddr + offset;
962334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, &buf, &count);
9635fe0fc9fSPeng Hao 			kunmap_local(mapaddr);
964334f485dSMiklos Szeredi 		} else
965334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, NULL, &count);
966334f485dSMiklos Szeredi 	}
967334f485dSMiklos Szeredi 	if (page && !cs->write)
968334f485dSMiklos Szeredi 		flush_dcache_page(page);
969334f485dSMiklos Szeredi 	return 0;
970334f485dSMiklos Szeredi }
971334f485dSMiklos Szeredi 
972334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */
973334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
974334f485dSMiklos Szeredi 			   int zeroing)
975334f485dSMiklos Szeredi {
976334f485dSMiklos Szeredi 	unsigned i;
977334f485dSMiklos Szeredi 	struct fuse_req *req = cs->req;
97805ea48ccSMiklos Szeredi 	struct fuse_args_pages *ap = container_of(req->args, typeof(*ap), args);
979334f485dSMiklos Szeredi 
98005ea48ccSMiklos Szeredi 
98105ea48ccSMiklos Szeredi 	for (i = 0; i < ap->num_pages && (nbytes || zeroing); i++) {
982ce534fb0SMiklos Szeredi 		int err;
98305ea48ccSMiklos Szeredi 		unsigned int offset = ap->descs[i].offset;
98405ea48ccSMiklos Szeredi 		unsigned int count = min(nbytes, ap->descs[i].length);
985ce534fb0SMiklos Szeredi 
98605ea48ccSMiklos Szeredi 		err = fuse_copy_page(cs, &ap->pages[i], offset, count, zeroing);
987334f485dSMiklos Szeredi 		if (err)
988334f485dSMiklos Szeredi 			return err;
989334f485dSMiklos Szeredi 
990334f485dSMiklos Szeredi 		nbytes -= count;
991334f485dSMiklos Szeredi 	}
992334f485dSMiklos Szeredi 	return 0;
993334f485dSMiklos Szeredi }
994334f485dSMiklos Szeredi 
995334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */
996334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
997334f485dSMiklos Szeredi {
998334f485dSMiklos Szeredi 	while (size) {
9991729a16cSMiklos Szeredi 		if (!cs->len) {
10001729a16cSMiklos Szeredi 			int err = fuse_copy_fill(cs);
10011729a16cSMiklos Szeredi 			if (err)
1002334f485dSMiklos Szeredi 				return err;
10031729a16cSMiklos Szeredi 		}
1004334f485dSMiklos Szeredi 		fuse_copy_do(cs, &val, &size);
1005334f485dSMiklos Szeredi 	}
1006334f485dSMiklos Szeredi 	return 0;
1007334f485dSMiklos Szeredi }
1008334f485dSMiklos Szeredi 
1009334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */
1010334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
1011334f485dSMiklos Szeredi 			  unsigned argpages, struct fuse_arg *args,
1012334f485dSMiklos Szeredi 			  int zeroing)
1013334f485dSMiklos Szeredi {
1014334f485dSMiklos Szeredi 	int err = 0;
1015334f485dSMiklos Szeredi 	unsigned i;
1016334f485dSMiklos Szeredi 
1017334f485dSMiklos Szeredi 	for (i = 0; !err && i < numargs; i++)  {
1018334f485dSMiklos Szeredi 		struct fuse_arg *arg = &args[i];
1019334f485dSMiklos Szeredi 		if (i == numargs - 1 && argpages)
1020334f485dSMiklos Szeredi 			err = fuse_copy_pages(cs, arg->size, zeroing);
1021334f485dSMiklos Szeredi 		else
1022334f485dSMiklos Szeredi 			err = fuse_copy_one(cs, arg->value, arg->size);
1023334f485dSMiklos Szeredi 	}
1024334f485dSMiklos Szeredi 	return err;
1025334f485dSMiklos Szeredi }
1026334f485dSMiklos Szeredi 
1027f88996a9SMiklos Szeredi static int forget_pending(struct fuse_iqueue *fiq)
102807e77dcaSMiklos Szeredi {
1029f88996a9SMiklos Szeredi 	return fiq->forget_list_head.next != NULL;
103007e77dcaSMiklos Szeredi }
103107e77dcaSMiklos Szeredi 
1032f88996a9SMiklos Szeredi static int request_pending(struct fuse_iqueue *fiq)
1033a4d27e75SMiklos Szeredi {
1034f88996a9SMiklos Szeredi 	return !list_empty(&fiq->pending) || !list_empty(&fiq->interrupts) ||
1035f88996a9SMiklos Szeredi 		forget_pending(fiq);
1036a4d27e75SMiklos Szeredi }
1037a4d27e75SMiklos Szeredi 
1038334f485dSMiklos Szeredi /*
1039a4d27e75SMiklos Szeredi  * Transfer an interrupt request to userspace
1040a4d27e75SMiklos Szeredi  *
1041a4d27e75SMiklos Szeredi  * Unlike other requests this is assembled on demand, without a need
1042a4d27e75SMiklos Szeredi  * to allocate a separate fuse_req structure.
1043a4d27e75SMiklos Szeredi  *
104476e43c8cSEric Biggers  * Called with fiq->lock held, releases it
1045a4d27e75SMiklos Szeredi  */
1046fd22d62eSMiklos Szeredi static int fuse_read_interrupt(struct fuse_iqueue *fiq,
1047fd22d62eSMiklos Szeredi 			       struct fuse_copy_state *cs,
1048c3021629SMiklos Szeredi 			       size_t nbytes, struct fuse_req *req)
104976e43c8cSEric Biggers __releases(fiq->lock)
1050a4d27e75SMiklos Szeredi {
1051a4d27e75SMiklos Szeredi 	struct fuse_in_header ih;
1052a4d27e75SMiklos Szeredi 	struct fuse_interrupt_in arg;
1053a4d27e75SMiklos Szeredi 	unsigned reqsize = sizeof(ih) + sizeof(arg);
1054a4d27e75SMiklos Szeredi 	int err;
1055a4d27e75SMiklos Szeredi 
1056a4d27e75SMiklos Szeredi 	list_del_init(&req->intr_entry);
1057a4d27e75SMiklos Szeredi 	memset(&ih, 0, sizeof(ih));
1058a4d27e75SMiklos Szeredi 	memset(&arg, 0, sizeof(arg));
1059a4d27e75SMiklos Szeredi 	ih.len = reqsize;
1060a4d27e75SMiklos Szeredi 	ih.opcode = FUSE_INTERRUPT;
10613a5358d1SKirill Tkhai 	ih.unique = (req->in.h.unique | FUSE_INT_REQ_BIT);
1062a4d27e75SMiklos Szeredi 	arg.unique = req->in.h.unique;
1063a4d27e75SMiklos Szeredi 
106476e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
1065c3021629SMiklos Szeredi 	if (nbytes < reqsize)
1066a4d27e75SMiklos Szeredi 		return -EINVAL;
1067a4d27e75SMiklos Szeredi 
1068c3021629SMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
1069a4d27e75SMiklos Szeredi 	if (!err)
1070c3021629SMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
1071c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
1072a4d27e75SMiklos Szeredi 
1073a4d27e75SMiklos Szeredi 	return err ? err : reqsize;
1074a4d27e75SMiklos Szeredi }
1075a4d27e75SMiklos Szeredi 
10764388c5aaSVivek Goyal struct fuse_forget_link *fuse_dequeue_forget(struct fuse_iqueue *fiq,
10774388c5aaSVivek Goyal 					     unsigned int max,
10784388c5aaSVivek Goyal 					     unsigned int *countp)
107907e77dcaSMiklos Szeredi {
1080f88996a9SMiklos Szeredi 	struct fuse_forget_link *head = fiq->forget_list_head.next;
108102c048b9SMiklos Szeredi 	struct fuse_forget_link **newhead = &head;
108202c048b9SMiklos Szeredi 	unsigned count;
108307e77dcaSMiklos Szeredi 
108402c048b9SMiklos Szeredi 	for (count = 0; *newhead != NULL && count < max; count++)
108502c048b9SMiklos Szeredi 		newhead = &(*newhead)->next;
108602c048b9SMiklos Szeredi 
1087f88996a9SMiklos Szeredi 	fiq->forget_list_head.next = *newhead;
108802c048b9SMiklos Szeredi 	*newhead = NULL;
1089f88996a9SMiklos Szeredi 	if (fiq->forget_list_head.next == NULL)
1090f88996a9SMiklos Szeredi 		fiq->forget_list_tail = &fiq->forget_list_head;
109107e77dcaSMiklos Szeredi 
109202c048b9SMiklos Szeredi 	if (countp != NULL)
109302c048b9SMiklos Szeredi 		*countp = count;
109402c048b9SMiklos Szeredi 
109502c048b9SMiklos Szeredi 	return head;
109607e77dcaSMiklos Szeredi }
10974388c5aaSVivek Goyal EXPORT_SYMBOL(fuse_dequeue_forget);
109807e77dcaSMiklos Szeredi 
1099fd22d62eSMiklos Szeredi static int fuse_read_single_forget(struct fuse_iqueue *fiq,
110007e77dcaSMiklos Szeredi 				   struct fuse_copy_state *cs,
110107e77dcaSMiklos Szeredi 				   size_t nbytes)
110276e43c8cSEric Biggers __releases(fiq->lock)
110307e77dcaSMiklos Szeredi {
110407e77dcaSMiklos Szeredi 	int err;
11054388c5aaSVivek Goyal 	struct fuse_forget_link *forget = fuse_dequeue_forget(fiq, 1, NULL);
110607e77dcaSMiklos Szeredi 	struct fuse_forget_in arg = {
110702c048b9SMiklos Szeredi 		.nlookup = forget->forget_one.nlookup,
110807e77dcaSMiklos Szeredi 	};
110907e77dcaSMiklos Szeredi 	struct fuse_in_header ih = {
111007e77dcaSMiklos Szeredi 		.opcode = FUSE_FORGET,
111102c048b9SMiklos Szeredi 		.nodeid = forget->forget_one.nodeid,
1112f88996a9SMiklos Szeredi 		.unique = fuse_get_unique(fiq),
111307e77dcaSMiklos Szeredi 		.len = sizeof(ih) + sizeof(arg),
111407e77dcaSMiklos Szeredi 	};
111507e77dcaSMiklos Szeredi 
111676e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
111707e77dcaSMiklos Szeredi 	kfree(forget);
111807e77dcaSMiklos Szeredi 	if (nbytes < ih.len)
111907e77dcaSMiklos Szeredi 		return -EINVAL;
112007e77dcaSMiklos Szeredi 
112107e77dcaSMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
112207e77dcaSMiklos Szeredi 	if (!err)
112307e77dcaSMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
112407e77dcaSMiklos Szeredi 	fuse_copy_finish(cs);
112507e77dcaSMiklos Szeredi 
112607e77dcaSMiklos Szeredi 	if (err)
112707e77dcaSMiklos Szeredi 		return err;
112807e77dcaSMiklos Szeredi 
112907e77dcaSMiklos Szeredi 	return ih.len;
113007e77dcaSMiklos Szeredi }
113107e77dcaSMiklos Szeredi 
1132fd22d62eSMiklos Szeredi static int fuse_read_batch_forget(struct fuse_iqueue *fiq,
113302c048b9SMiklos Szeredi 				   struct fuse_copy_state *cs, size_t nbytes)
113476e43c8cSEric Biggers __releases(fiq->lock)
113502c048b9SMiklos Szeredi {
113602c048b9SMiklos Szeredi 	int err;
113702c048b9SMiklos Szeredi 	unsigned max_forgets;
113802c048b9SMiklos Szeredi 	unsigned count;
113902c048b9SMiklos Szeredi 	struct fuse_forget_link *head;
114002c048b9SMiklos Szeredi 	struct fuse_batch_forget_in arg = { .count = 0 };
114102c048b9SMiklos Szeredi 	struct fuse_in_header ih = {
114202c048b9SMiklos Szeredi 		.opcode = FUSE_BATCH_FORGET,
1143f88996a9SMiklos Szeredi 		.unique = fuse_get_unique(fiq),
114402c048b9SMiklos Szeredi 		.len = sizeof(ih) + sizeof(arg),
114502c048b9SMiklos Szeredi 	};
114602c048b9SMiklos Szeredi 
114702c048b9SMiklos Szeredi 	if (nbytes < ih.len) {
114876e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
114902c048b9SMiklos Szeredi 		return -EINVAL;
115002c048b9SMiklos Szeredi 	}
115102c048b9SMiklos Szeredi 
115202c048b9SMiklos Szeredi 	max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one);
11534388c5aaSVivek Goyal 	head = fuse_dequeue_forget(fiq, max_forgets, &count);
115476e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
115502c048b9SMiklos Szeredi 
115602c048b9SMiklos Szeredi 	arg.count = count;
115702c048b9SMiklos Szeredi 	ih.len += count * sizeof(struct fuse_forget_one);
115802c048b9SMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
115902c048b9SMiklos Szeredi 	if (!err)
116002c048b9SMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
116102c048b9SMiklos Szeredi 
116202c048b9SMiklos Szeredi 	while (head) {
116302c048b9SMiklos Szeredi 		struct fuse_forget_link *forget = head;
116402c048b9SMiklos Szeredi 
116502c048b9SMiklos Szeredi 		if (!err) {
116602c048b9SMiklos Szeredi 			err = fuse_copy_one(cs, &forget->forget_one,
116702c048b9SMiklos Szeredi 					    sizeof(forget->forget_one));
116802c048b9SMiklos Szeredi 		}
116902c048b9SMiklos Szeredi 		head = forget->next;
117002c048b9SMiklos Szeredi 		kfree(forget);
117102c048b9SMiklos Szeredi 	}
117202c048b9SMiklos Szeredi 
117302c048b9SMiklos Szeredi 	fuse_copy_finish(cs);
117402c048b9SMiklos Szeredi 
117502c048b9SMiklos Szeredi 	if (err)
117602c048b9SMiklos Szeredi 		return err;
117702c048b9SMiklos Szeredi 
117802c048b9SMiklos Szeredi 	return ih.len;
117902c048b9SMiklos Szeredi }
118002c048b9SMiklos Szeredi 
1181fd22d62eSMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq,
1182fd22d62eSMiklos Szeredi 			    struct fuse_copy_state *cs,
118302c048b9SMiklos Szeredi 			    size_t nbytes)
118476e43c8cSEric Biggers __releases(fiq->lock)
118502c048b9SMiklos Szeredi {
1186f88996a9SMiklos Szeredi 	if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL)
1187fd22d62eSMiklos Szeredi 		return fuse_read_single_forget(fiq, cs, nbytes);
118802c048b9SMiklos Szeredi 	else
1189fd22d62eSMiklos Szeredi 		return fuse_read_batch_forget(fiq, cs, nbytes);
119002c048b9SMiklos Szeredi }
119102c048b9SMiklos Szeredi 
1192a4d27e75SMiklos Szeredi /*
1193334f485dSMiklos Szeredi  * Read a single request into the userspace filesystem's buffer.  This
1194334f485dSMiklos Szeredi  * function waits until a request is available, then removes it from
1195334f485dSMiklos Szeredi  * the pending list and copies request data to userspace buffer.  If
1196f9a2842eSMiklos Szeredi  * no reply is needed (FORGET) or request has been aborted or there
1197f9a2842eSMiklos Szeredi  * was an error during the copying then it's finished by calling
119804ec5af0SStefan Hajnoczi  * fuse_request_end().  Otherwise add it to the processing list, and set
1199334f485dSMiklos Szeredi  * the 'sent' flag.
1200334f485dSMiklos Szeredi  */
1201c3696046SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
1202c3021629SMiklos Szeredi 				struct fuse_copy_state *cs, size_t nbytes)
1203334f485dSMiklos Szeredi {
120482cbdcd3SMiklos Szeredi 	ssize_t err;
1205c3696046SMiklos Szeredi 	struct fuse_conn *fc = fud->fc;
1206f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
1207c3696046SMiklos Szeredi 	struct fuse_pqueue *fpq = &fud->pq;
1208334f485dSMiklos Szeredi 	struct fuse_req *req;
1209d4993774SMiklos Szeredi 	struct fuse_args *args;
1210334f485dSMiklos Szeredi 	unsigned reqsize;
1211be2ff42cSKirill Tkhai 	unsigned int hash;
1212334f485dSMiklos Szeredi 
12131fb027d7SKirill Smelkov 	/*
12141fb027d7SKirill Smelkov 	 * Require sane minimum read buffer - that has capacity for fixed part
12151fb027d7SKirill Smelkov 	 * of any request header + negotiated max_write room for data.
12161fb027d7SKirill Smelkov 	 *
12171fb027d7SKirill Smelkov 	 * Historically libfuse reserves 4K for fixed header room, but e.g.
12181fb027d7SKirill Smelkov 	 * GlusterFS reserves only 80 bytes
12191fb027d7SKirill Smelkov 	 *
12201fb027d7SKirill Smelkov 	 *	= `sizeof(fuse_in_header) + sizeof(fuse_write_in)`
12211fb027d7SKirill Smelkov 	 *
12221fb027d7SKirill Smelkov 	 * which is the absolute minimum any sane filesystem should be using
12231fb027d7SKirill Smelkov 	 * for header room.
12241fb027d7SKirill Smelkov 	 */
12251fb027d7SKirill Smelkov 	if (nbytes < max_t(size_t, FUSE_MIN_READ_BUFFER,
12261fb027d7SKirill Smelkov 			   sizeof(struct fuse_in_header) +
12271fb027d7SKirill Smelkov 			   sizeof(struct fuse_write_in) +
12281fb027d7SKirill Smelkov 			   fc->max_write))
12291fb027d7SKirill Smelkov 		return -EINVAL;
12301fb027d7SKirill Smelkov 
12311d3d752bSMiklos Szeredi  restart:
123276e43c8cSEric Biggers 	for (;;) {
123376e43c8cSEric Biggers 		spin_lock(&fiq->lock);
123476e43c8cSEric Biggers 		if (!fiq->connected || request_pending(fiq))
123576e43c8cSEric Biggers 			break;
123676e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
1237e5ac1d1eSJeff Dike 
123876e43c8cSEric Biggers 		if (file->f_flags & O_NONBLOCK)
123976e43c8cSEric Biggers 			return -EAGAIN;
124076e43c8cSEric Biggers 		err = wait_event_interruptible_exclusive(fiq->waitq,
12415250921bSMiklos Szeredi 				!fiq->connected || request_pending(fiq));
12425250921bSMiklos Szeredi 		if (err)
124376e43c8cSEric Biggers 			return err;
124476e43c8cSEric Biggers 	}
12455250921bSMiklos Szeredi 
12463b7008b2SSzymon Lukasz 	if (!fiq->connected) {
1247eb98e3bdSMiklos Szeredi 		err = fc->aborted ? -ECONNABORTED : -ENODEV;
1248334f485dSMiklos Szeredi 		goto err_unlock;
12493b7008b2SSzymon Lukasz 	}
1250334f485dSMiklos Szeredi 
1251f88996a9SMiklos Szeredi 	if (!list_empty(&fiq->interrupts)) {
1252f88996a9SMiklos Szeredi 		req = list_entry(fiq->interrupts.next, struct fuse_req,
1253a4d27e75SMiklos Szeredi 				 intr_entry);
1254fd22d62eSMiklos Szeredi 		return fuse_read_interrupt(fiq, cs, nbytes, req);
1255a4d27e75SMiklos Szeredi 	}
1256a4d27e75SMiklos Szeredi 
1257f88996a9SMiklos Szeredi 	if (forget_pending(fiq)) {
1258f88996a9SMiklos Szeredi 		if (list_empty(&fiq->pending) || fiq->forget_batch-- > 0)
1259fd22d62eSMiklos Szeredi 			return fuse_read_forget(fc, fiq, cs, nbytes);
126007e77dcaSMiklos Szeredi 
1261f88996a9SMiklos Szeredi 		if (fiq->forget_batch <= -8)
1262f88996a9SMiklos Szeredi 			fiq->forget_batch = 16;
126307e77dcaSMiklos Szeredi 	}
126407e77dcaSMiklos Szeredi 
1265f88996a9SMiklos Szeredi 	req = list_entry(fiq->pending.next, struct fuse_req, list);
126633e14b4dSMiklos Szeredi 	clear_bit(FR_PENDING, &req->flags);
1267ef759258SMiklos Szeredi 	list_del_init(&req->list);
126876e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
12694ce60812SMiklos Szeredi 
1270d4993774SMiklos Szeredi 	args = req->args;
1271d4993774SMiklos Szeredi 	reqsize = req->in.h.len;
12725d6d3a30SMiklos Szeredi 
12731d3d752bSMiklos Szeredi 	/* If request is too large, reply with an error and restart the read */
1274c3021629SMiklos Szeredi 	if (nbytes < reqsize) {
12751d3d752bSMiklos Szeredi 		req->out.h.error = -EIO;
12761d3d752bSMiklos Szeredi 		/* SETXATTR is special, since it may contain too large data */
1277d4993774SMiklos Szeredi 		if (args->opcode == FUSE_SETXATTR)
12781d3d752bSMiklos Szeredi 			req->out.h.error = -E2BIG;
12798f622e94SMax Reitz 		fuse_request_end(req);
12801d3d752bSMiklos Szeredi 		goto restart;
12811d3d752bSMiklos Szeredi 	}
128245a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
128380ef0867SMiklos Szeredi 	/*
128480ef0867SMiklos Szeredi 	 *  Must not put request on fpq->io queue after having been shut down by
128580ef0867SMiklos Szeredi 	 *  fuse_abort_conn()
128680ef0867SMiklos Szeredi 	 */
128780ef0867SMiklos Szeredi 	if (!fpq->connected) {
128880ef0867SMiklos Szeredi 		req->out.h.error = err = -ECONNABORTED;
128980ef0867SMiklos Szeredi 		goto out_end;
129080ef0867SMiklos Szeredi 
129180ef0867SMiklos Szeredi 	}
129282cbdcd3SMiklos Szeredi 	list_add(&req->list, &fpq->io);
129345a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1294c3021629SMiklos Szeredi 	cs->req = req;
1295d4993774SMiklos Szeredi 	err = fuse_copy_one(cs, &req->in.h, sizeof(req->in.h));
1296334f485dSMiklos Szeredi 	if (!err)
1297d4993774SMiklos Szeredi 		err = fuse_copy_args(cs, args->in_numargs, args->in_pages,
1298d4993774SMiklos Szeredi 				     (struct fuse_arg *) args->in_args, 0);
1299c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
130045a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1301825d6d33SMiklos Szeredi 	clear_bit(FR_LOCKED, &req->flags);
1302e96edd94SMiklos Szeredi 	if (!fpq->connected) {
1303eb98e3bdSMiklos Szeredi 		err = fc->aborted ? -ECONNABORTED : -ENODEV;
130482cbdcd3SMiklos Szeredi 		goto out_end;
1305c9c9d7dfSMiklos Szeredi 	}
1306334f485dSMiklos Szeredi 	if (err) {
1307334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
130882cbdcd3SMiklos Szeredi 		goto out_end;
1309334f485dSMiklos Szeredi 	}
1310825d6d33SMiklos Szeredi 	if (!test_bit(FR_ISREPLY, &req->flags)) {
131182cbdcd3SMiklos Szeredi 		err = reqsize;
131282cbdcd3SMiklos Szeredi 		goto out_end;
131382cbdcd3SMiklos Szeredi 	}
1314be2ff42cSKirill Tkhai 	hash = fuse_req_hash(req->in.h.unique);
1315be2ff42cSKirill Tkhai 	list_move_tail(&req->list, &fpq->processing[hash]);
1316bc78abbdSKirill Tkhai 	__fuse_get_request(req);
13178f7bb368SMiklos Szeredi 	set_bit(FR_SENT, &req->flags);
13184c316f2fSMiklos Szeredi 	spin_unlock(&fpq->lock);
13198f7bb368SMiklos Szeredi 	/* matches barrier in request_wait_answer() */
13208f7bb368SMiklos Szeredi 	smp_mb__after_atomic();
1321825d6d33SMiklos Szeredi 	if (test_bit(FR_INTERRUPTED, &req->flags))
13228f622e94SMax Reitz 		queue_interrupt(req);
13238f622e94SMax Reitz 	fuse_put_request(req);
132482cbdcd3SMiklos Szeredi 
1325334f485dSMiklos Szeredi 	return reqsize;
1326334f485dSMiklos Szeredi 
132782cbdcd3SMiklos Szeredi out_end:
132877cd9d48SMiklos Szeredi 	if (!test_bit(FR_PRIVATE, &req->flags))
132982cbdcd3SMiklos Szeredi 		list_del_init(&req->list);
133045a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
13318f622e94SMax Reitz 	fuse_request_end(req);
133282cbdcd3SMiklos Szeredi 	return err;
133382cbdcd3SMiklos Szeredi 
1334334f485dSMiklos Szeredi  err_unlock:
133576e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
1336334f485dSMiklos Szeredi 	return err;
1337334f485dSMiklos Szeredi }
1338334f485dSMiklos Szeredi 
133994e4fe2cSTom Van Braeckel static int fuse_dev_open(struct inode *inode, struct file *file)
134094e4fe2cSTom Van Braeckel {
134194e4fe2cSTom Van Braeckel 	/*
134294e4fe2cSTom Van Braeckel 	 * The fuse device's file's private_data is used to hold
134394e4fe2cSTom Van Braeckel 	 * the fuse_conn(ection) when it is mounted, and is used to
134494e4fe2cSTom Van Braeckel 	 * keep track of whether the file has been mounted already.
134594e4fe2cSTom Van Braeckel 	 */
134694e4fe2cSTom Van Braeckel 	file->private_data = NULL;
134794e4fe2cSTom Van Braeckel 	return 0;
134894e4fe2cSTom Van Braeckel }
134994e4fe2cSTom Van Braeckel 
1350fbdbaccaSAl Viro static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to)
1351c3021629SMiklos Szeredi {
1352c3021629SMiklos Szeredi 	struct fuse_copy_state cs;
1353c3021629SMiklos Szeredi 	struct file *file = iocb->ki_filp;
1354cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
1355cc080e9eSMiklos Szeredi 
1356cc080e9eSMiklos Szeredi 	if (!fud)
1357c3021629SMiklos Szeredi 		return -EPERM;
1358c3021629SMiklos Szeredi 
1359fcb14cb1SAl Viro 	if (!user_backed_iter(to))
1360fbdbaccaSAl Viro 		return -EINVAL;
1361c3021629SMiklos Szeredi 
1362dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 1, to);
1363fbdbaccaSAl Viro 
1364c3696046SMiklos Szeredi 	return fuse_dev_do_read(fud, file, &cs, iov_iter_count(to));
1365c3021629SMiklos Szeredi }
1366c3021629SMiklos Szeredi 
1367c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
1368c3021629SMiklos Szeredi 				    struct pipe_inode_info *pipe,
1369c3021629SMiklos Szeredi 				    size_t len, unsigned int flags)
1370c3021629SMiklos Szeredi {
1371d82718e3SAl Viro 	int total, ret;
1372c3021629SMiklos Szeredi 	int page_nr = 0;
1373c3021629SMiklos Szeredi 	struct pipe_buffer *bufs;
1374c3021629SMiklos Szeredi 	struct fuse_copy_state cs;
1375cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(in);
1376cc080e9eSMiklos Szeredi 
1377cc080e9eSMiklos Szeredi 	if (!fud)
1378c3021629SMiklos Szeredi 		return -EPERM;
1379c3021629SMiklos Szeredi 
13806718b6f8SDavid Howells 	bufs = kvmalloc_array(pipe->max_usage, sizeof(struct pipe_buffer),
13816da2ec56SKees Cook 			      GFP_KERNEL);
1382c3021629SMiklos Szeredi 	if (!bufs)
1383c3021629SMiklos Szeredi 		return -ENOMEM;
1384c3021629SMiklos Szeredi 
1385dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 1, NULL);
1386c3021629SMiklos Szeredi 	cs.pipebufs = bufs;
1387c3021629SMiklos Szeredi 	cs.pipe = pipe;
1388c3696046SMiklos Szeredi 	ret = fuse_dev_do_read(fud, in, &cs, len);
1389c3021629SMiklos Szeredi 	if (ret < 0)
1390c3021629SMiklos Szeredi 		goto out;
1391c3021629SMiklos Szeredi 
13926718b6f8SDavid Howells 	if (pipe_occupancy(pipe->head, pipe->tail) + cs.nr_segs > pipe->max_usage) {
1393c3021629SMiklos Szeredi 		ret = -EIO;
1394d82718e3SAl Viro 		goto out;
1395c3021629SMiklos Szeredi 	}
1396c3021629SMiklos Szeredi 
1397d82718e3SAl Viro 	for (ret = total = 0; page_nr < cs.nr_segs; total += ret) {
139828a625cbSMiklos Szeredi 		/*
139928a625cbSMiklos Szeredi 		 * Need to be careful about this.  Having buf->ops in module
140028a625cbSMiklos Szeredi 		 * code can Oops if the buffer persists after module unload.
140128a625cbSMiklos Szeredi 		 */
1402d82718e3SAl Viro 		bufs[page_nr].ops = &nosteal_pipe_buf_ops;
140384588a93SMiklos Szeredi 		bufs[page_nr].flags = 0;
1404d82718e3SAl Viro 		ret = add_to_pipe(pipe, &bufs[page_nr++]);
1405d82718e3SAl Viro 		if (unlikely(ret < 0))
1406d82718e3SAl Viro 			break;
1407c3021629SMiklos Szeredi 	}
1408d82718e3SAl Viro 	if (total)
1409d82718e3SAl Viro 		ret = total;
1410c3021629SMiklos Szeredi out:
1411c3021629SMiklos Szeredi 	for (; page_nr < cs.nr_segs; page_nr++)
141209cbfeafSKirill A. Shutemov 		put_page(bufs[page_nr].page);
1413c3021629SMiklos Szeredi 
1414d6d931adSAndrey Ryabinin 	kvfree(bufs);
1415c3021629SMiklos Szeredi 	return ret;
1416c3021629SMiklos Szeredi }
1417c3021629SMiklos Szeredi 
141895668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size,
141995668a69STejun Heo 			    struct fuse_copy_state *cs)
142095668a69STejun Heo {
142195668a69STejun Heo 	struct fuse_notify_poll_wakeup_out outarg;
1422f6d47a17SMiklos Szeredi 	int err = -EINVAL;
142395668a69STejun Heo 
142495668a69STejun Heo 	if (size != sizeof(outarg))
1425f6d47a17SMiklos Szeredi 		goto err;
142695668a69STejun Heo 
142795668a69STejun Heo 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
142895668a69STejun Heo 	if (err)
1429f6d47a17SMiklos Szeredi 		goto err;
143095668a69STejun Heo 
1431f6d47a17SMiklos Szeredi 	fuse_copy_finish(cs);
143295668a69STejun Heo 	return fuse_notify_poll_wakeup(fc, &outarg);
1433f6d47a17SMiklos Szeredi 
1434f6d47a17SMiklos Szeredi err:
1435f6d47a17SMiklos Szeredi 	fuse_copy_finish(cs);
1436f6d47a17SMiklos Szeredi 	return err;
143795668a69STejun Heo }
143895668a69STejun Heo 
14393b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size,
14403b463ae0SJohn Muir 				   struct fuse_copy_state *cs)
14413b463ae0SJohn Muir {
14423b463ae0SJohn Muir 	struct fuse_notify_inval_inode_out outarg;
14433b463ae0SJohn Muir 	int err = -EINVAL;
14443b463ae0SJohn Muir 
14453b463ae0SJohn Muir 	if (size != sizeof(outarg))
14463b463ae0SJohn Muir 		goto err;
14473b463ae0SJohn Muir 
14483b463ae0SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
14493b463ae0SJohn Muir 	if (err)
14503b463ae0SJohn Muir 		goto err;
14513b463ae0SJohn Muir 	fuse_copy_finish(cs);
14523b463ae0SJohn Muir 
14533b463ae0SJohn Muir 	down_read(&fc->killsb);
1454fcee216bSMax Reitz 	err = fuse_reverse_inval_inode(fc, outarg.ino,
14553b463ae0SJohn Muir 				       outarg.off, outarg.len);
14563b463ae0SJohn Muir 	up_read(&fc->killsb);
14573b463ae0SJohn Muir 	return err;
14583b463ae0SJohn Muir 
14593b463ae0SJohn Muir err:
14603b463ae0SJohn Muir 	fuse_copy_finish(cs);
14613b463ae0SJohn Muir 	return err;
14623b463ae0SJohn Muir }
14633b463ae0SJohn Muir 
14643b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size,
14653b463ae0SJohn Muir 				   struct fuse_copy_state *cs)
14663b463ae0SJohn Muir {
14673b463ae0SJohn Muir 	struct fuse_notify_inval_entry_out outarg;
1468b2d82ee3SFang Wenqi 	int err = -ENOMEM;
1469b2d82ee3SFang Wenqi 	char *buf;
14703b463ae0SJohn Muir 	struct qstr name;
14713b463ae0SJohn Muir 
1472b2d82ee3SFang Wenqi 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
1473b2d82ee3SFang Wenqi 	if (!buf)
1474b2d82ee3SFang Wenqi 		goto err;
1475b2d82ee3SFang Wenqi 
1476b2d82ee3SFang Wenqi 	err = -EINVAL;
14773b463ae0SJohn Muir 	if (size < sizeof(outarg))
14783b463ae0SJohn Muir 		goto err;
14793b463ae0SJohn Muir 
14803b463ae0SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
14813b463ae0SJohn Muir 	if (err)
14823b463ae0SJohn Muir 		goto err;
14833b463ae0SJohn Muir 
14843b463ae0SJohn Muir 	err = -ENAMETOOLONG;
14853b463ae0SJohn Muir 	if (outarg.namelen > FUSE_NAME_MAX)
14863b463ae0SJohn Muir 		goto err;
14873b463ae0SJohn Muir 
1488c2183d1eSMiklos Szeredi 	err = -EINVAL;
1489c2183d1eSMiklos Szeredi 	if (size != sizeof(outarg) + outarg.namelen + 1)
1490c2183d1eSMiklos Szeredi 		goto err;
1491c2183d1eSMiklos Szeredi 
14923b463ae0SJohn Muir 	name.name = buf;
14933b463ae0SJohn Muir 	name.len = outarg.namelen;
14943b463ae0SJohn Muir 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
14953b463ae0SJohn Muir 	if (err)
14963b463ae0SJohn Muir 		goto err;
14973b463ae0SJohn Muir 	fuse_copy_finish(cs);
14983b463ae0SJohn Muir 	buf[outarg.namelen] = 0;
14993b463ae0SJohn Muir 
15003b463ae0SJohn Muir 	down_read(&fc->killsb);
1501*4f8d3702SMiklos Szeredi 	err = fuse_reverse_inval_entry(fc, outarg.parent, 0, &name, outarg.flags);
1502451d0f59SJohn Muir 	up_read(&fc->killsb);
1503451d0f59SJohn Muir 	kfree(buf);
1504451d0f59SJohn Muir 	return err;
1505451d0f59SJohn Muir 
1506451d0f59SJohn Muir err:
1507451d0f59SJohn Muir 	kfree(buf);
1508451d0f59SJohn Muir 	fuse_copy_finish(cs);
1509451d0f59SJohn Muir 	return err;
1510451d0f59SJohn Muir }
1511451d0f59SJohn Muir 
1512451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size,
1513451d0f59SJohn Muir 			      struct fuse_copy_state *cs)
1514451d0f59SJohn Muir {
1515451d0f59SJohn Muir 	struct fuse_notify_delete_out outarg;
1516451d0f59SJohn Muir 	int err = -ENOMEM;
1517451d0f59SJohn Muir 	char *buf;
1518451d0f59SJohn Muir 	struct qstr name;
1519451d0f59SJohn Muir 
1520451d0f59SJohn Muir 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
1521451d0f59SJohn Muir 	if (!buf)
1522451d0f59SJohn Muir 		goto err;
1523451d0f59SJohn Muir 
1524451d0f59SJohn Muir 	err = -EINVAL;
1525451d0f59SJohn Muir 	if (size < sizeof(outarg))
1526451d0f59SJohn Muir 		goto err;
1527451d0f59SJohn Muir 
1528451d0f59SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
1529451d0f59SJohn Muir 	if (err)
1530451d0f59SJohn Muir 		goto err;
1531451d0f59SJohn Muir 
1532451d0f59SJohn Muir 	err = -ENAMETOOLONG;
1533451d0f59SJohn Muir 	if (outarg.namelen > FUSE_NAME_MAX)
1534451d0f59SJohn Muir 		goto err;
1535451d0f59SJohn Muir 
1536451d0f59SJohn Muir 	err = -EINVAL;
1537451d0f59SJohn Muir 	if (size != sizeof(outarg) + outarg.namelen + 1)
1538451d0f59SJohn Muir 		goto err;
1539451d0f59SJohn Muir 
1540451d0f59SJohn Muir 	name.name = buf;
1541451d0f59SJohn Muir 	name.len = outarg.namelen;
1542451d0f59SJohn Muir 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
1543451d0f59SJohn Muir 	if (err)
1544451d0f59SJohn Muir 		goto err;
1545451d0f59SJohn Muir 	fuse_copy_finish(cs);
1546451d0f59SJohn Muir 	buf[outarg.namelen] = 0;
1547451d0f59SJohn Muir 
1548451d0f59SJohn Muir 	down_read(&fc->killsb);
1549*4f8d3702SMiklos Szeredi 	err = fuse_reverse_inval_entry(fc, outarg.parent, outarg.child, &name, 0);
15503b463ae0SJohn Muir 	up_read(&fc->killsb);
1551b2d82ee3SFang Wenqi 	kfree(buf);
15523b463ae0SJohn Muir 	return err;
15533b463ae0SJohn Muir 
15543b463ae0SJohn Muir err:
1555b2d82ee3SFang Wenqi 	kfree(buf);
15563b463ae0SJohn Muir 	fuse_copy_finish(cs);
15573b463ae0SJohn Muir 	return err;
15583b463ae0SJohn Muir }
15593b463ae0SJohn Muir 
1560a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
1561a1d75f25SMiklos Szeredi 			     struct fuse_copy_state *cs)
1562a1d75f25SMiklos Szeredi {
1563a1d75f25SMiklos Szeredi 	struct fuse_notify_store_out outarg;
1564a1d75f25SMiklos Szeredi 	struct inode *inode;
1565a1d75f25SMiklos Szeredi 	struct address_space *mapping;
1566a1d75f25SMiklos Szeredi 	u64 nodeid;
1567a1d75f25SMiklos Szeredi 	int err;
1568a1d75f25SMiklos Szeredi 	pgoff_t index;
1569a1d75f25SMiklos Szeredi 	unsigned int offset;
1570a1d75f25SMiklos Szeredi 	unsigned int num;
1571a1d75f25SMiklos Szeredi 	loff_t file_size;
1572a1d75f25SMiklos Szeredi 	loff_t end;
1573a1d75f25SMiklos Szeredi 
1574a1d75f25SMiklos Szeredi 	err = -EINVAL;
1575a1d75f25SMiklos Szeredi 	if (size < sizeof(outarg))
1576a1d75f25SMiklos Szeredi 		goto out_finish;
1577a1d75f25SMiklos Szeredi 
1578a1d75f25SMiklos Szeredi 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
1579a1d75f25SMiklos Szeredi 	if (err)
1580a1d75f25SMiklos Szeredi 		goto out_finish;
1581a1d75f25SMiklos Szeredi 
1582a1d75f25SMiklos Szeredi 	err = -EINVAL;
1583a1d75f25SMiklos Szeredi 	if (size - sizeof(outarg) != outarg.size)
1584a1d75f25SMiklos Szeredi 		goto out_finish;
1585a1d75f25SMiklos Szeredi 
1586a1d75f25SMiklos Szeredi 	nodeid = outarg.nodeid;
1587a1d75f25SMiklos Szeredi 
1588a1d75f25SMiklos Szeredi 	down_read(&fc->killsb);
1589a1d75f25SMiklos Szeredi 
1590a1d75f25SMiklos Szeredi 	err = -ENOENT;
1591fcee216bSMax Reitz 	inode = fuse_ilookup(fc, nodeid,  NULL);
1592a1d75f25SMiklos Szeredi 	if (!inode)
1593a1d75f25SMiklos Szeredi 		goto out_up_killsb;
1594a1d75f25SMiklos Szeredi 
1595a1d75f25SMiklos Szeredi 	mapping = inode->i_mapping;
159609cbfeafSKirill A. Shutemov 	index = outarg.offset >> PAGE_SHIFT;
159709cbfeafSKirill A. Shutemov 	offset = outarg.offset & ~PAGE_MASK;
1598a1d75f25SMiklos Szeredi 	file_size = i_size_read(inode);
1599a1d75f25SMiklos Szeredi 	end = outarg.offset + outarg.size;
1600a1d75f25SMiklos Szeredi 	if (end > file_size) {
1601a1d75f25SMiklos Szeredi 		file_size = end;
1602d347739aSMiklos Szeredi 		fuse_write_update_attr(inode, file_size, outarg.size);
1603a1d75f25SMiklos Szeredi 	}
1604a1d75f25SMiklos Szeredi 
1605a1d75f25SMiklos Szeredi 	num = outarg.size;
1606a1d75f25SMiklos Szeredi 	while (num) {
1607a1d75f25SMiklos Szeredi 		struct page *page;
1608a1d75f25SMiklos Szeredi 		unsigned int this_num;
1609a1d75f25SMiklos Szeredi 
1610a1d75f25SMiklos Szeredi 		err = -ENOMEM;
1611a1d75f25SMiklos Szeredi 		page = find_or_create_page(mapping, index,
1612a1d75f25SMiklos Szeredi 					   mapping_gfp_mask(mapping));
1613a1d75f25SMiklos Szeredi 		if (!page)
1614a1d75f25SMiklos Szeredi 			goto out_iput;
1615a1d75f25SMiklos Szeredi 
161609cbfeafSKirill A. Shutemov 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
1617a1d75f25SMiklos Szeredi 		err = fuse_copy_page(cs, &page, offset, this_num, 0);
1618063ec1e5SMiklos Szeredi 		if (!err && offset == 0 &&
161909cbfeafSKirill A. Shutemov 		    (this_num == PAGE_SIZE || file_size == end))
1620a1d75f25SMiklos Szeredi 			SetPageUptodate(page);
1621a1d75f25SMiklos Szeredi 		unlock_page(page);
162209cbfeafSKirill A. Shutemov 		put_page(page);
1623a1d75f25SMiklos Szeredi 
1624a1d75f25SMiklos Szeredi 		if (err)
1625a1d75f25SMiklos Szeredi 			goto out_iput;
1626a1d75f25SMiklos Szeredi 
1627a1d75f25SMiklos Szeredi 		num -= this_num;
1628a1d75f25SMiklos Szeredi 		offset = 0;
1629a1d75f25SMiklos Szeredi 		index++;
1630a1d75f25SMiklos Szeredi 	}
1631a1d75f25SMiklos Szeredi 
1632a1d75f25SMiklos Szeredi 	err = 0;
1633a1d75f25SMiklos Szeredi 
1634a1d75f25SMiklos Szeredi out_iput:
1635a1d75f25SMiklos Szeredi 	iput(inode);
1636a1d75f25SMiklos Szeredi out_up_killsb:
1637a1d75f25SMiklos Szeredi 	up_read(&fc->killsb);
1638a1d75f25SMiklos Szeredi out_finish:
1639a1d75f25SMiklos Szeredi 	fuse_copy_finish(cs);
1640a1d75f25SMiklos Szeredi 	return err;
1641a1d75f25SMiklos Szeredi }
1642a1d75f25SMiklos Szeredi 
164375b399ddSMiklos Szeredi struct fuse_retrieve_args {
164475b399ddSMiklos Szeredi 	struct fuse_args_pages ap;
164575b399ddSMiklos Szeredi 	struct fuse_notify_retrieve_in inarg;
164675b399ddSMiklos Szeredi };
164775b399ddSMiklos Szeredi 
1648fcee216bSMax Reitz static void fuse_retrieve_end(struct fuse_mount *fm, struct fuse_args *args,
164975b399ddSMiklos Szeredi 			      int error)
16502d45ba38SMiklos Szeredi {
165175b399ddSMiklos Szeredi 	struct fuse_retrieve_args *ra =
165275b399ddSMiklos Szeredi 		container_of(args, typeof(*ra), ap.args);
165375b399ddSMiklos Szeredi 
165475b399ddSMiklos Szeredi 	release_pages(ra->ap.pages, ra->ap.num_pages);
165575b399ddSMiklos Szeredi 	kfree(ra);
16562d45ba38SMiklos Szeredi }
16572d45ba38SMiklos Szeredi 
1658fcee216bSMax Reitz static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
16592d45ba38SMiklos Szeredi 			 struct fuse_notify_retrieve_out *outarg)
16602d45ba38SMiklos Szeredi {
16612d45ba38SMiklos Szeredi 	int err;
16622d45ba38SMiklos Szeredi 	struct address_space *mapping = inode->i_mapping;
16632d45ba38SMiklos Szeredi 	pgoff_t index;
16642d45ba38SMiklos Szeredi 	loff_t file_size;
16652d45ba38SMiklos Szeredi 	unsigned int num;
16662d45ba38SMiklos Szeredi 	unsigned int offset;
16670157443cSGeert Uytterhoeven 	size_t total_len = 0;
16685da784ccSConstantine Shulyupin 	unsigned int num_pages;
1669fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
167075b399ddSMiklos Szeredi 	struct fuse_retrieve_args *ra;
167175b399ddSMiklos Szeredi 	size_t args_size = sizeof(*ra);
167275b399ddSMiklos Szeredi 	struct fuse_args_pages *ap;
167375b399ddSMiklos Szeredi 	struct fuse_args *args;
16742d45ba38SMiklos Szeredi 
167509cbfeafSKirill A. Shutemov 	offset = outarg->offset & ~PAGE_MASK;
16764d53dc99SMaxim Patlasov 	file_size = i_size_read(inode);
16774d53dc99SMaxim Patlasov 
16787640682eSKirill Smelkov 	num = min(outarg->size, fc->max_write);
16794d53dc99SMaxim Patlasov 	if (outarg->offset > file_size)
16804d53dc99SMaxim Patlasov 		num = 0;
16814d53dc99SMaxim Patlasov 	else if (outarg->offset + num > file_size)
16824d53dc99SMaxim Patlasov 		num = file_size - outarg->offset;
16834d53dc99SMaxim Patlasov 
16844d53dc99SMaxim Patlasov 	num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
16855da784ccSConstantine Shulyupin 	num_pages = min(num_pages, fc->max_pages);
16864d53dc99SMaxim Patlasov 
168775b399ddSMiklos Szeredi 	args_size += num_pages * (sizeof(ap->pages[0]) + sizeof(ap->descs[0]));
16882d45ba38SMiklos Szeredi 
168975b399ddSMiklos Szeredi 	ra = kzalloc(args_size, GFP_KERNEL);
169075b399ddSMiklos Szeredi 	if (!ra)
169175b399ddSMiklos Szeredi 		return -ENOMEM;
169275b399ddSMiklos Szeredi 
169375b399ddSMiklos Szeredi 	ap = &ra->ap;
169475b399ddSMiklos Szeredi 	ap->pages = (void *) (ra + 1);
169575b399ddSMiklos Szeredi 	ap->descs = (void *) (ap->pages + num_pages);
169675b399ddSMiklos Szeredi 
169775b399ddSMiklos Szeredi 	args = &ap->args;
169875b399ddSMiklos Szeredi 	args->nodeid = outarg->nodeid;
169975b399ddSMiklos Szeredi 	args->opcode = FUSE_NOTIFY_REPLY;
170075b399ddSMiklos Szeredi 	args->in_numargs = 2;
170175b399ddSMiklos Szeredi 	args->in_pages = true;
170275b399ddSMiklos Szeredi 	args->end = fuse_retrieve_end;
17032d45ba38SMiklos Szeredi 
170409cbfeafSKirill A. Shutemov 	index = outarg->offset >> PAGE_SHIFT;
17052d45ba38SMiklos Szeredi 
170675b399ddSMiklos Szeredi 	while (num && ap->num_pages < num_pages) {
17072d45ba38SMiklos Szeredi 		struct page *page;
17082d45ba38SMiklos Szeredi 		unsigned int this_num;
17092d45ba38SMiklos Szeredi 
17102d45ba38SMiklos Szeredi 		page = find_get_page(mapping, index);
17112d45ba38SMiklos Szeredi 		if (!page)
17122d45ba38SMiklos Szeredi 			break;
17132d45ba38SMiklos Szeredi 
171409cbfeafSKirill A. Shutemov 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
171575b399ddSMiklos Szeredi 		ap->pages[ap->num_pages] = page;
171675b399ddSMiklos Szeredi 		ap->descs[ap->num_pages].offset = offset;
171775b399ddSMiklos Szeredi 		ap->descs[ap->num_pages].length = this_num;
171875b399ddSMiklos Szeredi 		ap->num_pages++;
17192d45ba38SMiklos Szeredi 
1720c9e67d48SMiklos Szeredi 		offset = 0;
17212d45ba38SMiklos Szeredi 		num -= this_num;
17222d45ba38SMiklos Szeredi 		total_len += this_num;
172348706d0aSMiklos Szeredi 		index++;
17242d45ba38SMiklos Szeredi 	}
172575b399ddSMiklos Szeredi 	ra->inarg.offset = outarg->offset;
172675b399ddSMiklos Szeredi 	ra->inarg.size = total_len;
172775b399ddSMiklos Szeredi 	args->in_args[0].size = sizeof(ra->inarg);
172875b399ddSMiklos Szeredi 	args->in_args[0].value = &ra->inarg;
172975b399ddSMiklos Szeredi 	args->in_args[1].size = total_len;
17302d45ba38SMiklos Szeredi 
1731fcee216bSMax Reitz 	err = fuse_simple_notify_reply(fm, args, outarg->notify_unique);
173275b399ddSMiklos Szeredi 	if (err)
1733fcee216bSMax Reitz 		fuse_retrieve_end(fm, args, err);
17342d45ba38SMiklos Szeredi 
17352d45ba38SMiklos Szeredi 	return err;
17362d45ba38SMiklos Szeredi }
17372d45ba38SMiklos Szeredi 
17382d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size,
17392d45ba38SMiklos Szeredi 				struct fuse_copy_state *cs)
17402d45ba38SMiklos Szeredi {
17412d45ba38SMiklos Szeredi 	struct fuse_notify_retrieve_out outarg;
1742fcee216bSMax Reitz 	struct fuse_mount *fm;
17432d45ba38SMiklos Szeredi 	struct inode *inode;
1744fcee216bSMax Reitz 	u64 nodeid;
17452d45ba38SMiklos Szeredi 	int err;
17462d45ba38SMiklos Szeredi 
17472d45ba38SMiklos Szeredi 	err = -EINVAL;
17482d45ba38SMiklos Szeredi 	if (size != sizeof(outarg))
17492d45ba38SMiklos Szeredi 		goto copy_finish;
17502d45ba38SMiklos Szeredi 
17512d45ba38SMiklos Szeredi 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
17522d45ba38SMiklos Szeredi 	if (err)
17532d45ba38SMiklos Szeredi 		goto copy_finish;
17542d45ba38SMiklos Szeredi 
17552d45ba38SMiklos Szeredi 	fuse_copy_finish(cs);
17562d45ba38SMiklos Szeredi 
17572d45ba38SMiklos Szeredi 	down_read(&fc->killsb);
17582d45ba38SMiklos Szeredi 	err = -ENOENT;
1759fcee216bSMax Reitz 	nodeid = outarg.nodeid;
17602d45ba38SMiklos Szeredi 
1761fcee216bSMax Reitz 	inode = fuse_ilookup(fc, nodeid, &fm);
17622d45ba38SMiklos Szeredi 	if (inode) {
1763fcee216bSMax Reitz 		err = fuse_retrieve(fm, inode, &outarg);
17642d45ba38SMiklos Szeredi 		iput(inode);
17652d45ba38SMiklos Szeredi 	}
17662d45ba38SMiklos Szeredi 	up_read(&fc->killsb);
17672d45ba38SMiklos Szeredi 
17682d45ba38SMiklos Szeredi 	return err;
17692d45ba38SMiklos Szeredi 
17702d45ba38SMiklos Szeredi copy_finish:
17712d45ba38SMiklos Szeredi 	fuse_copy_finish(cs);
17722d45ba38SMiklos Szeredi 	return err;
17732d45ba38SMiklos Szeredi }
17742d45ba38SMiklos Szeredi 
17758599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
17768599396bSTejun Heo 		       unsigned int size, struct fuse_copy_state *cs)
17778599396bSTejun Heo {
17780d278362SMiklos Szeredi 	/* Don't try to move pages (yet) */
17790d278362SMiklos Szeredi 	cs->move_pages = 0;
17800d278362SMiklos Szeredi 
17818599396bSTejun Heo 	switch (code) {
178295668a69STejun Heo 	case FUSE_NOTIFY_POLL:
178395668a69STejun Heo 		return fuse_notify_poll(fc, size, cs);
178495668a69STejun Heo 
17853b463ae0SJohn Muir 	case FUSE_NOTIFY_INVAL_INODE:
17863b463ae0SJohn Muir 		return fuse_notify_inval_inode(fc, size, cs);
17873b463ae0SJohn Muir 
17883b463ae0SJohn Muir 	case FUSE_NOTIFY_INVAL_ENTRY:
17893b463ae0SJohn Muir 		return fuse_notify_inval_entry(fc, size, cs);
17903b463ae0SJohn Muir 
1791a1d75f25SMiklos Szeredi 	case FUSE_NOTIFY_STORE:
1792a1d75f25SMiklos Szeredi 		return fuse_notify_store(fc, size, cs);
1793a1d75f25SMiklos Szeredi 
17942d45ba38SMiklos Szeredi 	case FUSE_NOTIFY_RETRIEVE:
17952d45ba38SMiklos Szeredi 		return fuse_notify_retrieve(fc, size, cs);
17962d45ba38SMiklos Szeredi 
1797451d0f59SJohn Muir 	case FUSE_NOTIFY_DELETE:
1798451d0f59SJohn Muir 		return fuse_notify_delete(fc, size, cs);
1799451d0f59SJohn Muir 
18008599396bSTejun Heo 	default:
1801f6d47a17SMiklos Szeredi 		fuse_copy_finish(cs);
18028599396bSTejun Heo 		return -EINVAL;
18038599396bSTejun Heo 	}
18048599396bSTejun Heo }
18058599396bSTejun Heo 
1806334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */
18073a2b5b9cSMiklos Szeredi static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique)
1808334f485dSMiklos Szeredi {
1809be2ff42cSKirill Tkhai 	unsigned int hash = fuse_req_hash(unique);
1810334f485dSMiklos Szeredi 	struct fuse_req *req;
181105726acaSDong Fang 
1812be2ff42cSKirill Tkhai 	list_for_each_entry(req, &fpq->processing[hash], list) {
18133a5358d1SKirill Tkhai 		if (req->in.h.unique == unique)
1814334f485dSMiklos Szeredi 			return req;
1815334f485dSMiklos Szeredi 	}
1816334f485dSMiklos Szeredi 	return NULL;
1817334f485dSMiklos Szeredi }
1818334f485dSMiklos Szeredi 
1819d4993774SMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_args *args,
1820334f485dSMiklos Szeredi 			 unsigned nbytes)
1821334f485dSMiklos Szeredi {
1822334f485dSMiklos Szeredi 	unsigned reqsize = sizeof(struct fuse_out_header);
1823334f485dSMiklos Szeredi 
182414d46d7aSStefan Hajnoczi 	reqsize += fuse_len_args(args->out_numargs, args->out_args);
1825334f485dSMiklos Szeredi 
1826d4993774SMiklos Szeredi 	if (reqsize < nbytes || (reqsize > nbytes && !args->out_argvar))
1827334f485dSMiklos Szeredi 		return -EINVAL;
1828334f485dSMiklos Szeredi 	else if (reqsize > nbytes) {
1829d4993774SMiklos Szeredi 		struct fuse_arg *lastarg = &args->out_args[args->out_numargs-1];
1830334f485dSMiklos Szeredi 		unsigned diffsize = reqsize - nbytes;
1831d4993774SMiklos Szeredi 
1832334f485dSMiklos Szeredi 		if (diffsize > lastarg->size)
1833334f485dSMiklos Szeredi 			return -EINVAL;
1834334f485dSMiklos Szeredi 		lastarg->size -= diffsize;
1835334f485dSMiklos Szeredi 	}
1836d4993774SMiklos Szeredi 	return fuse_copy_args(cs, args->out_numargs, args->out_pages,
1837d4993774SMiklos Szeredi 			      args->out_args, args->page_zeroing);
1838334f485dSMiklos Szeredi }
1839334f485dSMiklos Szeredi 
1840334f485dSMiklos Szeredi /*
1841334f485dSMiklos Szeredi  * Write a single reply to a request.  First the header is copied from
1842334f485dSMiklos Szeredi  * the write buffer.  The request is then searched on the processing
1843334f485dSMiklos Szeredi  * list by the unique ID found in the header.  If found, then remove
1844334f485dSMiklos Szeredi  * it from the list and copy the rest of the buffer to the request.
184504ec5af0SStefan Hajnoczi  * The request is finished by calling fuse_request_end().
1846334f485dSMiklos Szeredi  */
1847c3696046SMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
1848dd3bb14fSMiklos Szeredi 				 struct fuse_copy_state *cs, size_t nbytes)
1849334f485dSMiklos Szeredi {
1850334f485dSMiklos Szeredi 	int err;
1851c3696046SMiklos Szeredi 	struct fuse_conn *fc = fud->fc;
1852c3696046SMiklos Szeredi 	struct fuse_pqueue *fpq = &fud->pq;
1853334f485dSMiklos Szeredi 	struct fuse_req *req;
1854334f485dSMiklos Szeredi 	struct fuse_out_header oh;
1855334f485dSMiklos Szeredi 
18567407a10dSKirill Tkhai 	err = -EINVAL;
1857334f485dSMiklos Szeredi 	if (nbytes < sizeof(struct fuse_out_header))
18587407a10dSKirill Tkhai 		goto out;
1859334f485dSMiklos Szeredi 
1860dd3bb14fSMiklos Szeredi 	err = fuse_copy_one(cs, &oh, sizeof(oh));
1861334f485dSMiklos Szeredi 	if (err)
18627407a10dSKirill Tkhai 		goto copy_finish;
18638599396bSTejun Heo 
1864334f485dSMiklos Szeredi 	err = -EINVAL;
18658599396bSTejun Heo 	if (oh.len != nbytes)
18667407a10dSKirill Tkhai 		goto copy_finish;
18678599396bSTejun Heo 
18688599396bSTejun Heo 	/*
18698599396bSTejun Heo 	 * Zero oh.unique indicates unsolicited notification message
18708599396bSTejun Heo 	 * and error contains notification code.
18718599396bSTejun Heo 	 */
18728599396bSTejun Heo 	if (!oh.unique) {
1873dd3bb14fSMiklos Szeredi 		err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs);
18747407a10dSKirill Tkhai 		goto out;
18758599396bSTejun Heo 	}
18768599396bSTejun Heo 
18778599396bSTejun Heo 	err = -EINVAL;
187849221cf8SMiklos Szeredi 	if (oh.error <= -512 || oh.error > 0)
18797407a10dSKirill Tkhai 		goto copy_finish;
1880334f485dSMiklos Szeredi 
188145a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
18827407a10dSKirill Tkhai 	req = NULL;
18837407a10dSKirill Tkhai 	if (fpq->connected)
18843a5358d1SKirill Tkhai 		req = request_find(fpq, oh.unique & ~FUSE_INT_REQ_BIT);
18857407a10dSKirill Tkhai 
18867407a10dSKirill Tkhai 	err = -ENOENT;
18877407a10dSKirill Tkhai 	if (!req) {
18887407a10dSKirill Tkhai 		spin_unlock(&fpq->lock);
18897407a10dSKirill Tkhai 		goto copy_finish;
18907407a10dSKirill Tkhai 	}
1891334f485dSMiklos Szeredi 
18923a5358d1SKirill Tkhai 	/* Is it an interrupt reply ID? */
18933a5358d1SKirill Tkhai 	if (oh.unique & FUSE_INT_REQ_BIT) {
1894d2d2d4fbSKirill Tkhai 		__fuse_get_request(req);
189545a91cb1SMiklos Szeredi 		spin_unlock(&fpq->lock);
189645a91cb1SMiklos Szeredi 
18977407a10dSKirill Tkhai 		err = 0;
18987407a10dSKirill Tkhai 		if (nbytes != sizeof(struct fuse_out_header))
1899a4d27e75SMiklos Szeredi 			err = -EINVAL;
19007407a10dSKirill Tkhai 		else if (oh.error == -ENOSYS)
1901a4d27e75SMiklos Szeredi 			fc->no_interrupt = 1;
1902a4d27e75SMiklos Szeredi 		else if (oh.error == -EAGAIN)
19038f622e94SMax Reitz 			err = queue_interrupt(req);
19047407a10dSKirill Tkhai 
19058f622e94SMax Reitz 		fuse_put_request(req);
1906a4d27e75SMiklos Szeredi 
19077407a10dSKirill Tkhai 		goto copy_finish;
1908a4d27e75SMiklos Szeredi 	}
1909a4d27e75SMiklos Szeredi 
191033e14b4dSMiklos Szeredi 	clear_bit(FR_SENT, &req->flags);
19113a2b5b9cSMiklos Szeredi 	list_move(&req->list, &fpq->io);
1912334f485dSMiklos Szeredi 	req->out.h = oh;
1913825d6d33SMiklos Szeredi 	set_bit(FR_LOCKED, &req->flags);
191445a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1915dd3bb14fSMiklos Szeredi 	cs->req = req;
1916d4993774SMiklos Szeredi 	if (!req->args->page_replace)
1917ce534fb0SMiklos Szeredi 		cs->move_pages = 0;
1918334f485dSMiklos Szeredi 
1919d4993774SMiklos Szeredi 	if (oh.error)
1920d4993774SMiklos Szeredi 		err = nbytes != sizeof(oh) ? -EINVAL : 0;
1921d4993774SMiklos Szeredi 	else
1922d4993774SMiklos Szeredi 		err = copy_out_args(cs, req->args, nbytes);
1923dd3bb14fSMiklos Szeredi 	fuse_copy_finish(cs);
1924334f485dSMiklos Szeredi 
192545a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1926825d6d33SMiklos Szeredi 	clear_bit(FR_LOCKED, &req->flags);
1927e96edd94SMiklos Szeredi 	if (!fpq->connected)
1928334f485dSMiklos Szeredi 		err = -ENOENT;
19290d8e84b0SMiklos Szeredi 	else if (err)
1930334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
193177cd9d48SMiklos Szeredi 	if (!test_bit(FR_PRIVATE, &req->flags))
1932f377cb79SMiklos Szeredi 		list_del_init(&req->list);
193345a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
193446c34a34SMiklos Szeredi 
19358f622e94SMax Reitz 	fuse_request_end(req);
19367407a10dSKirill Tkhai out:
1937334f485dSMiklos Szeredi 	return err ? err : nbytes;
1938334f485dSMiklos Szeredi 
19397407a10dSKirill Tkhai copy_finish:
1940dd3bb14fSMiklos Szeredi 	fuse_copy_finish(cs);
19417407a10dSKirill Tkhai 	goto out;
1942334f485dSMiklos Szeredi }
1943334f485dSMiklos Szeredi 
1944fbdbaccaSAl Viro static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from)
1945dd3bb14fSMiklos Szeredi {
1946dd3bb14fSMiklos Szeredi 	struct fuse_copy_state cs;
1947cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(iocb->ki_filp);
1948cc080e9eSMiklos Szeredi 
1949cc080e9eSMiklos Szeredi 	if (!fud)
1950dd3bb14fSMiklos Szeredi 		return -EPERM;
1951dd3bb14fSMiklos Szeredi 
1952fcb14cb1SAl Viro 	if (!user_backed_iter(from))
1953fbdbaccaSAl Viro 		return -EINVAL;
1954dd3bb14fSMiklos Szeredi 
1955dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 0, from);
1956fbdbaccaSAl Viro 
1957c3696046SMiklos Szeredi 	return fuse_dev_do_write(fud, &cs, iov_iter_count(from));
1958dd3bb14fSMiklos Szeredi }
1959dd3bb14fSMiklos Szeredi 
1960dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
1961dd3bb14fSMiklos Szeredi 				     struct file *out, loff_t *ppos,
1962dd3bb14fSMiklos Szeredi 				     size_t len, unsigned int flags)
1963dd3bb14fSMiklos Szeredi {
19648cefc107SDavid Howells 	unsigned int head, tail, mask, count;
1965dd3bb14fSMiklos Szeredi 	unsigned nbuf;
1966dd3bb14fSMiklos Szeredi 	unsigned idx;
1967dd3bb14fSMiklos Szeredi 	struct pipe_buffer *bufs;
1968dd3bb14fSMiklos Szeredi 	struct fuse_copy_state cs;
1969cc080e9eSMiklos Szeredi 	struct fuse_dev *fud;
1970dd3bb14fSMiklos Szeredi 	size_t rem;
1971dd3bb14fSMiklos Szeredi 	ssize_t ret;
1972dd3bb14fSMiklos Szeredi 
1973cc080e9eSMiklos Szeredi 	fud = fuse_get_dev(out);
1974cc080e9eSMiklos Szeredi 	if (!fud)
1975dd3bb14fSMiklos Szeredi 		return -EPERM;
1976dd3bb14fSMiklos Szeredi 
1977a2477b0eSAndrey Ryabinin 	pipe_lock(pipe);
1978a2477b0eSAndrey Ryabinin 
19798cefc107SDavid Howells 	head = pipe->head;
19808cefc107SDavid Howells 	tail = pipe->tail;
19818cefc107SDavid Howells 	mask = pipe->ring_size - 1;
19828cefc107SDavid Howells 	count = head - tail;
19838cefc107SDavid Howells 
19848cefc107SDavid Howells 	bufs = kvmalloc_array(count, sizeof(struct pipe_buffer), GFP_KERNEL);
1985a2477b0eSAndrey Ryabinin 	if (!bufs) {
1986a2477b0eSAndrey Ryabinin 		pipe_unlock(pipe);
1987dd3bb14fSMiklos Szeredi 		return -ENOMEM;
1988a2477b0eSAndrey Ryabinin 	}
1989dd3bb14fSMiklos Szeredi 
1990dd3bb14fSMiklos Szeredi 	nbuf = 0;
1991dd3bb14fSMiklos Szeredi 	rem = 0;
199276f6777cSDavid Howells 	for (idx = tail; idx != head && rem < len; idx++)
19938cefc107SDavid Howells 		rem += pipe->bufs[idx & mask].len;
1994dd3bb14fSMiklos Szeredi 
1995dd3bb14fSMiklos Szeredi 	ret = -EINVAL;
199615fab63eSMatthew Wilcox 	if (rem < len)
199715fab63eSMatthew Wilcox 		goto out_free;
1998dd3bb14fSMiklos Szeredi 
1999dd3bb14fSMiklos Szeredi 	rem = len;
2000dd3bb14fSMiklos Szeredi 	while (rem) {
2001dd3bb14fSMiklos Szeredi 		struct pipe_buffer *ibuf;
2002dd3bb14fSMiklos Szeredi 		struct pipe_buffer *obuf;
2003dd3bb14fSMiklos Szeredi 
20040e9fb6f1SVasily Averin 		if (WARN_ON(nbuf >= count || tail == head))
20050e9fb6f1SVasily Averin 			goto out_free;
20060e9fb6f1SVasily Averin 
20078cefc107SDavid Howells 		ibuf = &pipe->bufs[tail & mask];
2008dd3bb14fSMiklos Szeredi 		obuf = &bufs[nbuf];
2009dd3bb14fSMiklos Szeredi 
2010dd3bb14fSMiklos Szeredi 		if (rem >= ibuf->len) {
2011dd3bb14fSMiklos Szeredi 			*obuf = *ibuf;
2012dd3bb14fSMiklos Szeredi 			ibuf->ops = NULL;
20138cefc107SDavid Howells 			tail++;
20148cefc107SDavid Howells 			pipe->tail = tail;
2015dd3bb14fSMiklos Szeredi 		} else {
201615fab63eSMatthew Wilcox 			if (!pipe_buf_get(pipe, ibuf))
201715fab63eSMatthew Wilcox 				goto out_free;
201815fab63eSMatthew Wilcox 
2019dd3bb14fSMiklos Szeredi 			*obuf = *ibuf;
2020dd3bb14fSMiklos Szeredi 			obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
2021dd3bb14fSMiklos Szeredi 			obuf->len = rem;
2022dd3bb14fSMiklos Szeredi 			ibuf->offset += obuf->len;
2023dd3bb14fSMiklos Szeredi 			ibuf->len -= obuf->len;
2024dd3bb14fSMiklos Szeredi 		}
2025dd3bb14fSMiklos Szeredi 		nbuf++;
2026dd3bb14fSMiklos Szeredi 		rem -= obuf->len;
2027dd3bb14fSMiklos Szeredi 	}
2028dd3bb14fSMiklos Szeredi 	pipe_unlock(pipe);
2029dd3bb14fSMiklos Szeredi 
2030dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 0, NULL);
2031dd3bb14fSMiklos Szeredi 	cs.pipebufs = bufs;
20326c09e94aSAl Viro 	cs.nr_segs = nbuf;
2033dd3bb14fSMiklos Szeredi 	cs.pipe = pipe;
2034dd3bb14fSMiklos Szeredi 
2035ce534fb0SMiklos Szeredi 	if (flags & SPLICE_F_MOVE)
2036ce534fb0SMiklos Szeredi 		cs.move_pages = 1;
2037ce534fb0SMiklos Szeredi 
2038c3696046SMiklos Szeredi 	ret = fuse_dev_do_write(fud, &cs, len);
2039dd3bb14fSMiklos Szeredi 
20409509941eSJann Horn 	pipe_lock(pipe);
204115fab63eSMatthew Wilcox out_free:
2042712a9510SMiklos Szeredi 	for (idx = 0; idx < nbuf; idx++) {
2043712a9510SMiklos Szeredi 		struct pipe_buffer *buf = &bufs[idx];
2044712a9510SMiklos Szeredi 
2045712a9510SMiklos Szeredi 		if (buf->ops)
2046712a9510SMiklos Szeredi 			pipe_buf_release(pipe, buf);
2047712a9510SMiklos Szeredi 	}
20489509941eSJann Horn 	pipe_unlock(pipe);
2049a779638cSMiklos Szeredi 
2050d6d931adSAndrey Ryabinin 	kvfree(bufs);
2051dd3bb14fSMiklos Szeredi 	return ret;
2052dd3bb14fSMiklos Szeredi }
2053dd3bb14fSMiklos Szeredi 
2054076ccb76SAl Viro static __poll_t fuse_dev_poll(struct file *file, poll_table *wait)
2055334f485dSMiklos Szeredi {
2056a9a08845SLinus Torvalds 	__poll_t mask = EPOLLOUT | EPOLLWRNORM;
2057f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq;
2058cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2059cc080e9eSMiklos Szeredi 
2060cc080e9eSMiklos Szeredi 	if (!fud)
2061a9a08845SLinus Torvalds 		return EPOLLERR;
2062334f485dSMiklos Szeredi 
2063cc080e9eSMiklos Szeredi 	fiq = &fud->fc->iq;
2064f88996a9SMiklos Szeredi 	poll_wait(file, &fiq->waitq, wait);
2065334f485dSMiklos Szeredi 
206676e43c8cSEric Biggers 	spin_lock(&fiq->lock);
2067e16714d8SMiklos Szeredi 	if (!fiq->connected)
2068a9a08845SLinus Torvalds 		mask = EPOLLERR;
2069f88996a9SMiklos Szeredi 	else if (request_pending(fiq))
2070a9a08845SLinus Torvalds 		mask |= EPOLLIN | EPOLLRDNORM;
207176e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
2072334f485dSMiklos Szeredi 
2073334f485dSMiklos Szeredi 	return mask;
2074334f485dSMiklos Szeredi }
2075334f485dSMiklos Szeredi 
207634061750SKirill Tkhai /* Abort all requests on the given list (pending or processing) */
20778f622e94SMax Reitz static void end_requests(struct list_head *head)
2078334f485dSMiklos Szeredi {
2079334f485dSMiklos Szeredi 	while (!list_empty(head)) {
2080334f485dSMiklos Szeredi 		struct fuse_req *req;
2081334f485dSMiklos Szeredi 		req = list_entry(head->next, struct fuse_req, list);
2082334f485dSMiklos Szeredi 		req->out.h.error = -ECONNABORTED;
208333e14b4dSMiklos Szeredi 		clear_bit(FR_SENT, &req->flags);
2084f377cb79SMiklos Szeredi 		list_del_init(&req->list);
20858f622e94SMax Reitz 		fuse_request_end(req);
2086334f485dSMiklos Szeredi 	}
2087334f485dSMiklos Szeredi }
2088334f485dSMiklos Szeredi 
2089357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc)
2090357ccf2bSBryan Green {
2091357ccf2bSBryan Green 	struct rb_node *p;
2092357ccf2bSBryan Green 
2093357ccf2bSBryan Green 	p = rb_first(&fc->polled_files);
2094357ccf2bSBryan Green 
2095357ccf2bSBryan Green 	while (p) {
2096357ccf2bSBryan Green 		struct fuse_file *ff;
2097357ccf2bSBryan Green 		ff = rb_entry(p, struct fuse_file, polled_node);
2098357ccf2bSBryan Green 		wake_up_interruptible_all(&ff->poll_wait);
2099357ccf2bSBryan Green 
2100357ccf2bSBryan Green 		p = rb_next(p);
2101357ccf2bSBryan Green 	}
2102357ccf2bSBryan Green }
2103357ccf2bSBryan Green 
210469a53bf2SMiklos Szeredi /*
210569a53bf2SMiklos Szeredi  * Abort all requests.
210669a53bf2SMiklos Szeredi  *
2107b716d425SMiklos Szeredi  * Emergency exit in case of a malicious or accidental deadlock, or just a hung
2108b716d425SMiklos Szeredi  * filesystem.
210969a53bf2SMiklos Szeredi  *
2110b716d425SMiklos Szeredi  * The same effect is usually achievable through killing the filesystem daemon
2111b716d425SMiklos Szeredi  * and all users of the filesystem.  The exception is the combination of an
2112b716d425SMiklos Szeredi  * asynchronous request and the tricky deadlock (see
211372ef5e52SMauro Carvalho Chehab  * Documentation/filesystems/fuse.rst).
211469a53bf2SMiklos Szeredi  *
2115b716d425SMiklos Szeredi  * Aborting requests under I/O goes as follows: 1: Separate out unlocked
2116b716d425SMiklos Szeredi  * requests, they should be finished off immediately.  Locked requests will be
2117b716d425SMiklos Szeredi  * finished after unlock; see unlock_request(). 2: Finish off the unlocked
2118b716d425SMiklos Szeredi  * requests.  It is possible that some request will finish before we can.  This
2119b716d425SMiklos Szeredi  * is OK, the request will in that case be removed from the list before we touch
2120b716d425SMiklos Szeredi  * it.
212169a53bf2SMiklos Szeredi  */
2122eb98e3bdSMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc)
212369a53bf2SMiklos Szeredi {
2124f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
2125f88996a9SMiklos Szeredi 
2126d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
212769a53bf2SMiklos Szeredi 	if (fc->connected) {
2128c3696046SMiklos Szeredi 		struct fuse_dev *fud;
2129b716d425SMiklos Szeredi 		struct fuse_req *req, *next;
213075f3ee4cSMiklos Szeredi 		LIST_HEAD(to_end);
2131be2ff42cSKirill Tkhai 		unsigned int i;
2132b716d425SMiklos Szeredi 
213363825b4eSKirill Tkhai 		/* Background queuing checks fc->connected under bg_lock */
213463825b4eSKirill Tkhai 		spin_lock(&fc->bg_lock);
213569a53bf2SMiklos Szeredi 		fc->connected = 0;
213663825b4eSKirill Tkhai 		spin_unlock(&fc->bg_lock);
213763825b4eSKirill Tkhai 
21389759bd51SMiklos Szeredi 		fuse_set_initialized(fc);
2139c3696046SMiklos Szeredi 		list_for_each_entry(fud, &fc->devices, entry) {
2140c3696046SMiklos Szeredi 			struct fuse_pqueue *fpq = &fud->pq;
2141c3696046SMiklos Szeredi 
214245a91cb1SMiklos Szeredi 			spin_lock(&fpq->lock);
2143e96edd94SMiklos Szeredi 			fpq->connected = 0;
21443a2b5b9cSMiklos Szeredi 			list_for_each_entry_safe(req, next, &fpq->io, list) {
2145b716d425SMiklos Szeredi 				req->out.h.error = -ECONNABORTED;
2146b716d425SMiklos Szeredi 				spin_lock(&req->waitq.lock);
2147b716d425SMiklos Szeredi 				set_bit(FR_ABORTED, &req->flags);
214877cd9d48SMiklos Szeredi 				if (!test_bit(FR_LOCKED, &req->flags)) {
214977cd9d48SMiklos Szeredi 					set_bit(FR_PRIVATE, &req->flags);
215087114373SMiklos Szeredi 					__fuse_get_request(req);
215175f3ee4cSMiklos Szeredi 					list_move(&req->list, &to_end);
215277cd9d48SMiklos Szeredi 				}
2153b716d425SMiklos Szeredi 				spin_unlock(&req->waitq.lock);
2154b716d425SMiklos Szeredi 			}
2155be2ff42cSKirill Tkhai 			for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
2156be2ff42cSKirill Tkhai 				list_splice_tail_init(&fpq->processing[i],
2157be2ff42cSKirill Tkhai 						      &to_end);
215845a91cb1SMiklos Szeredi 			spin_unlock(&fpq->lock);
2159c3696046SMiklos Szeredi 		}
2160ae2dffa3SKirill Tkhai 		spin_lock(&fc->bg_lock);
2161ae2dffa3SKirill Tkhai 		fc->blocked = 0;
216241f98274SMiklos Szeredi 		fc->max_background = UINT_MAX;
216341f98274SMiklos Szeredi 		flush_bg_queue(fc);
2164ae2dffa3SKirill Tkhai 		spin_unlock(&fc->bg_lock);
21658c91189aSMiklos Szeredi 
216676e43c8cSEric Biggers 		spin_lock(&fiq->lock);
21678c91189aSMiklos Szeredi 		fiq->connected = 0;
216875f3ee4cSMiklos Szeredi 		list_for_each_entry(req, &fiq->pending, list)
2169a8a86d78STahsin Erdogan 			clear_bit(FR_PENDING, &req->flags);
217075f3ee4cSMiklos Szeredi 		list_splice_tail_init(&fiq->pending, &to_end);
21718c91189aSMiklos Szeredi 		while (forget_pending(fiq))
21724388c5aaSVivek Goyal 			kfree(fuse_dequeue_forget(fiq, 1, NULL));
217376e43c8cSEric Biggers 		wake_up_all(&fiq->waitq);
217476e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
21758c91189aSMiklos Szeredi 		kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
2176ee314a87SMiklos Szeredi 		end_polls(fc);
2177ee314a87SMiklos Szeredi 		wake_up_all(&fc->blocked_waitq);
2178ee314a87SMiklos Szeredi 		spin_unlock(&fc->lock);
21798c91189aSMiklos Szeredi 
21808f622e94SMax Reitz 		end_requests(&to_end);
2181ee314a87SMiklos Szeredi 	} else {
2182d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
218369a53bf2SMiklos Szeredi 	}
2184ee314a87SMiklos Szeredi }
218508cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn);
218669a53bf2SMiklos Szeredi 
2187b8f95e5dSMiklos Szeredi void fuse_wait_aborted(struct fuse_conn *fc)
2188b8f95e5dSMiklos Szeredi {
21892d84a2d1SMiklos Szeredi 	/* matches implicit memory barrier in fuse_drop_waiting() */
21902d84a2d1SMiklos Szeredi 	smp_mb();
2191b8f95e5dSMiklos Szeredi 	wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
2192b8f95e5dSMiklos Szeredi }
2193b8f95e5dSMiklos Szeredi 
219408cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file)
2195334f485dSMiklos Szeredi {
2196cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2197cc080e9eSMiklos Szeredi 
2198cc080e9eSMiklos Szeredi 	if (fud) {
2199cc080e9eSMiklos Szeredi 		struct fuse_conn *fc = fud->fc;
2200c3696046SMiklos Szeredi 		struct fuse_pqueue *fpq = &fud->pq;
220145ff350bSMiklos Szeredi 		LIST_HEAD(to_end);
2202be2ff42cSKirill Tkhai 		unsigned int i;
2203cc080e9eSMiklos Szeredi 
220445ff350bSMiklos Szeredi 		spin_lock(&fpq->lock);
2205c3696046SMiklos Szeredi 		WARN_ON(!list_empty(&fpq->io));
2206be2ff42cSKirill Tkhai 		for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
2207be2ff42cSKirill Tkhai 			list_splice_init(&fpq->processing[i], &to_end);
220845ff350bSMiklos Szeredi 		spin_unlock(&fpq->lock);
220945ff350bSMiklos Szeredi 
22108f622e94SMax Reitz 		end_requests(&to_end);
221145ff350bSMiklos Szeredi 
2212c3696046SMiklos Szeredi 		/* Are we the last open device? */
2213c3696046SMiklos Szeredi 		if (atomic_dec_and_test(&fc->dev_count)) {
2214f88996a9SMiklos Szeredi 			WARN_ON(fc->iq.fasync != NULL);
2215eb98e3bdSMiklos Szeredi 			fuse_abort_conn(fc);
2216c3696046SMiklos Szeredi 		}
2217cc080e9eSMiklos Szeredi 		fuse_dev_free(fud);
2218385a17bfSJeff Dike 	}
2219334f485dSMiklos Szeredi 	return 0;
2220334f485dSMiklos Szeredi }
222108cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release);
2222334f485dSMiklos Szeredi 
2223385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on)
2224385a17bfSJeff Dike {
2225cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2226cc080e9eSMiklos Szeredi 
2227cc080e9eSMiklos Szeredi 	if (!fud)
2228a87046d8SMiklos Szeredi 		return -EPERM;
2229385a17bfSJeff Dike 
2230385a17bfSJeff Dike 	/* No locking - fasync_helper does its own locking */
2231cc080e9eSMiklos Szeredi 	return fasync_helper(fd, file, on, &fud->fc->iq.fasync);
2232385a17bfSJeff Dike }
2233385a17bfSJeff Dike 
223400c570f4SMiklos Szeredi static int fuse_device_clone(struct fuse_conn *fc, struct file *new)
223500c570f4SMiklos Szeredi {
2236cc080e9eSMiklos Szeredi 	struct fuse_dev *fud;
2237cc080e9eSMiklos Szeredi 
223800c570f4SMiklos Szeredi 	if (new->private_data)
223900c570f4SMiklos Szeredi 		return -EINVAL;
224000c570f4SMiklos Szeredi 
22410cd1eb9aSVivek Goyal 	fud = fuse_dev_alloc_install(fc);
2242cc080e9eSMiklos Szeredi 	if (!fud)
2243cc080e9eSMiklos Szeredi 		return -ENOMEM;
2244cc080e9eSMiklos Szeredi 
2245cc080e9eSMiklos Szeredi 	new->private_data = fud;
2246c3696046SMiklos Szeredi 	atomic_inc(&fc->dev_count);
224700c570f4SMiklos Szeredi 
224800c570f4SMiklos Szeredi 	return 0;
224900c570f4SMiklos Szeredi }
225000c570f4SMiklos Szeredi 
225100c570f4SMiklos Szeredi static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
225200c570f4SMiklos Szeredi 			   unsigned long arg)
225300c570f4SMiklos Szeredi {
2254f8425c93SAlessio Balsini 	int res;
225500c570f4SMiklos Szeredi 	int oldfd;
2256f8425c93SAlessio Balsini 	struct fuse_dev *fud = NULL;
225700c570f4SMiklos Szeredi 
22586076f5f3SAlessio Balsini 	switch (cmd) {
22596076f5f3SAlessio Balsini 	case FUSE_DEV_IOC_CLONE:
2260f8425c93SAlessio Balsini 		res = -EFAULT;
226100c570f4SMiklos Szeredi 		if (!get_user(oldfd, (__u32 __user *)arg)) {
226200c570f4SMiklos Szeredi 			struct file *old = fget(oldfd);
226300c570f4SMiklos Szeredi 
2264f8425c93SAlessio Balsini 			res = -EINVAL;
226500c570f4SMiklos Szeredi 			if (old) {
22668ed1f0e2SJann Horn 				/*
22678ed1f0e2SJann Horn 				 * Check against file->f_op because CUSE
22688ed1f0e2SJann Horn 				 * uses the same ioctl handler.
22698ed1f0e2SJann Horn 				 */
22708ed1f0e2SJann Horn 				if (old->f_op == file->f_op &&
22718ed1f0e2SJann Horn 				    old->f_cred->user_ns == file->f_cred->user_ns)
22728ed1f0e2SJann Horn 					fud = fuse_get_dev(old);
227300c570f4SMiklos Szeredi 
2274cc080e9eSMiklos Szeredi 				if (fud) {
227500c570f4SMiklos Szeredi 					mutex_lock(&fuse_mutex);
2276f8425c93SAlessio Balsini 					res = fuse_device_clone(fud->fc, file);
227700c570f4SMiklos Szeredi 					mutex_unlock(&fuse_mutex);
227800c570f4SMiklos Szeredi 				}
227900c570f4SMiklos Szeredi 				fput(old);
228000c570f4SMiklos Szeredi 			}
228100c570f4SMiklos Szeredi 		}
2282f8425c93SAlessio Balsini 		break;
2283f8425c93SAlessio Balsini 	default:
2284f8425c93SAlessio Balsini 		res = -ENOTTY;
2285f8425c93SAlessio Balsini 		break;
228600c570f4SMiklos Szeredi 	}
2287f8425c93SAlessio Balsini 	return res;
228800c570f4SMiklos Szeredi }
228900c570f4SMiklos Szeredi 
22904b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = {
2291334f485dSMiklos Szeredi 	.owner		= THIS_MODULE,
229294e4fe2cSTom Van Braeckel 	.open		= fuse_dev_open,
2293334f485dSMiklos Szeredi 	.llseek		= no_llseek,
2294fbdbaccaSAl Viro 	.read_iter	= fuse_dev_read,
2295c3021629SMiklos Szeredi 	.splice_read	= fuse_dev_splice_read,
2296fbdbaccaSAl Viro 	.write_iter	= fuse_dev_write,
2297dd3bb14fSMiklos Szeredi 	.splice_write	= fuse_dev_splice_write,
2298334f485dSMiklos Szeredi 	.poll		= fuse_dev_poll,
2299334f485dSMiklos Szeredi 	.release	= fuse_dev_release,
2300385a17bfSJeff Dike 	.fasync		= fuse_dev_fasync,
230100c570f4SMiklos Szeredi 	.unlocked_ioctl = fuse_dev_ioctl,
23021832f2d8SArnd Bergmann 	.compat_ioctl   = compat_ptr_ioctl,
2303334f485dSMiklos Szeredi };
230408cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations);
2305334f485dSMiklos Szeredi 
2306334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = {
2307334f485dSMiklos Szeredi 	.minor = FUSE_MINOR,
2308334f485dSMiklos Szeredi 	.name  = "fuse",
2309334f485dSMiklos Szeredi 	.fops = &fuse_dev_operations,
2310334f485dSMiklos Szeredi };
2311334f485dSMiklos Szeredi 
2312334f485dSMiklos Szeredi int __init fuse_dev_init(void)
2313334f485dSMiklos Szeredi {
2314334f485dSMiklos Szeredi 	int err = -ENOMEM;
2315334f485dSMiklos Szeredi 	fuse_req_cachep = kmem_cache_create("fuse_request",
2316334f485dSMiklos Szeredi 					    sizeof(struct fuse_req),
231720c2df83SPaul Mundt 					    0, 0, NULL);
2318334f485dSMiklos Szeredi 	if (!fuse_req_cachep)
2319334f485dSMiklos Szeredi 		goto out;
2320334f485dSMiklos Szeredi 
2321334f485dSMiklos Szeredi 	err = misc_register(&fuse_miscdevice);
2322334f485dSMiklos Szeredi 	if (err)
2323334f485dSMiklos Szeredi 		goto out_cache_clean;
2324334f485dSMiklos Szeredi 
2325334f485dSMiklos Szeredi 	return 0;
2326334f485dSMiklos Szeredi 
2327334f485dSMiklos Szeredi  out_cache_clean:
2328334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
2329334f485dSMiklos Szeredi  out:
2330334f485dSMiklos Szeredi 	return err;
2331334f485dSMiklos Szeredi }
2332334f485dSMiklos Szeredi 
2333334f485dSMiklos Szeredi void fuse_dev_cleanup(void)
2334334f485dSMiklos Szeredi {
2335334f485dSMiklos Szeredi 	misc_deregister(&fuse_miscdevice);
2336334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
2337334f485dSMiklos Szeredi }
2338