xref: /openbmc/linux/fs/fuse/dev.c (revision 5addcd5d)
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 
437213394cSMiklos Szeredi static void fuse_request_init(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);
50334f485dSMiklos Szeredi }
51334f485dSMiklos Szeredi 
527213394cSMiklos Szeredi static struct fuse_req *fuse_request_alloc(gfp_t flags)
53334f485dSMiklos Szeredi {
548a7aa286SMiklos Szeredi 	struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags);
557213394cSMiklos Szeredi 	if (req)
567213394cSMiklos Szeredi 		fuse_request_init(req);
574250c066SMaxim Patlasov 
58334f485dSMiklos Szeredi 	return req;
59334f485dSMiklos Szeredi }
604250c066SMaxim Patlasov 
6166abc359SMiklos Szeredi static void fuse_request_free(struct fuse_req *req)
62e52a8250SMiklos Szeredi {
63334f485dSMiklos Szeredi 	kmem_cache_free(fuse_req_cachep, req);
64334f485dSMiklos Szeredi }
65334f485dSMiklos Szeredi 
6666abc359SMiklos Szeredi static void __fuse_get_request(struct fuse_req *req)
67334f485dSMiklos Szeredi {
68ec99f6d3SElena Reshetova 	refcount_inc(&req->count);
69334f485dSMiklos Szeredi }
70334f485dSMiklos Szeredi 
71334f485dSMiklos Szeredi /* Must be called with > 1 refcount */
72334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req)
73334f485dSMiklos Szeredi {
74ec99f6d3SElena Reshetova 	refcount_dec(&req->count);
75334f485dSMiklos Szeredi }
76334f485dSMiklos Szeredi 
779759bd51SMiklos Szeredi void fuse_set_initialized(struct fuse_conn *fc)
789759bd51SMiklos Szeredi {
799759bd51SMiklos Szeredi 	/* Make sure stores before this are seen on another CPU */
809759bd51SMiklos Szeredi 	smp_wmb();
819759bd51SMiklos Szeredi 	fc->initialized = 1;
829759bd51SMiklos Szeredi }
839759bd51SMiklos Szeredi 
840aada884SMaxim Patlasov static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background)
850aada884SMaxim Patlasov {
860aada884SMaxim Patlasov 	return !fc->initialized || (for_background && fc->blocked);
870aada884SMaxim Patlasov }
880aada884SMaxim Patlasov 
89b8f95e5dSMiklos Szeredi static void fuse_drop_waiting(struct fuse_conn *fc)
90b8f95e5dSMiklos Szeredi {
912d84a2d1SMiklos Szeredi 	/*
922d84a2d1SMiklos Szeredi 	 * lockess check of fc->connected is okay, because atomic_dec_and_test()
932d84a2d1SMiklos Szeredi 	 * provides a memory barrier mached with the one in fuse_wait_aborted()
942d84a2d1SMiklos Szeredi 	 * to ensure no wake-up is missed.
952d84a2d1SMiklos Szeredi 	 */
962d84a2d1SMiklos Szeredi 	if (atomic_dec_and_test(&fc->num_waiting) &&
972d84a2d1SMiklos Szeredi 	    !READ_ONCE(fc->connected)) {
98b8f95e5dSMiklos Szeredi 		/* wake up aborters */
99b8f95e5dSMiklos Szeredi 		wake_up_all(&fc->blocked_waitq);
100b8f95e5dSMiklos Szeredi 	}
101b8f95e5dSMiklos Szeredi }
102b8f95e5dSMiklos Szeredi 
10366abc359SMiklos Szeredi static void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
10466abc359SMiklos Szeredi 
1057213394cSMiklos Szeredi static struct fuse_req *fuse_get_req(struct fuse_conn *fc, bool for_background)
106334f485dSMiklos Szeredi {
10708a53cdcSMiklos Szeredi 	struct fuse_req *req;
1080aada884SMaxim Patlasov 	int err;
1090aada884SMaxim Patlasov 	atomic_inc(&fc->num_waiting);
1100aada884SMaxim Patlasov 
1110aada884SMaxim Patlasov 	if (fuse_block_alloc(fc, for_background)) {
1129bc5dddaSMiklos Szeredi 		err = -EINTR;
1137d3a07fcSAl Viro 		if (wait_event_killable_exclusive(fc->blocked_waitq,
1147d3a07fcSAl Viro 				!fuse_block_alloc(fc, for_background)))
1159bc5dddaSMiklos Szeredi 			goto out;
1160aada884SMaxim Patlasov 	}
1179759bd51SMiklos Szeredi 	/* Matches smp_wmb() in fuse_set_initialized() */
1189759bd51SMiklos Szeredi 	smp_rmb();
11908a53cdcSMiklos Szeredi 
12051eb01e7SMiklos Szeredi 	err = -ENOTCONN;
12151eb01e7SMiklos Szeredi 	if (!fc->connected)
12251eb01e7SMiklos Szeredi 		goto out;
12351eb01e7SMiklos Szeredi 
124de155226SMiklos Szeredi 	err = -ECONNREFUSED;
125de155226SMiklos Szeredi 	if (fc->conn_error)
126de155226SMiklos Szeredi 		goto out;
127de155226SMiklos Szeredi 
1287213394cSMiklos Szeredi 	req = fuse_request_alloc(GFP_KERNEL);
1299bc5dddaSMiklos Szeredi 	err = -ENOMEM;
130722d2beaSMaxim Patlasov 	if (!req) {
131722d2beaSMaxim Patlasov 		if (for_background)
132722d2beaSMaxim Patlasov 			wake_up(&fc->blocked_waitq);
1339bc5dddaSMiklos Szeredi 		goto out;
134722d2beaSMaxim Patlasov 	}
135334f485dSMiklos Szeredi 
1368cb08329SEric W. Biederman 	req->in.h.uid = from_kuid(fc->user_ns, current_fsuid());
1378cb08329SEric W. Biederman 	req->in.h.gid = from_kgid(fc->user_ns, current_fsgid());
138c9582eb0SEric W. Biederman 	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
139c9582eb0SEric W. Biederman 
140825d6d33SMiklos Szeredi 	__set_bit(FR_WAITING, &req->flags);
141825d6d33SMiklos Szeredi 	if (for_background)
142825d6d33SMiklos Szeredi 		__set_bit(FR_BACKGROUND, &req->flags);
143825d6d33SMiklos Szeredi 
144c9582eb0SEric W. Biederman 	if (unlikely(req->in.h.uid == ((uid_t)-1) ||
145c9582eb0SEric W. Biederman 		     req->in.h.gid == ((gid_t)-1))) {
146c9582eb0SEric W. Biederman 		fuse_put_request(fc, req);
147c9582eb0SEric W. Biederman 		return ERR_PTR(-EOVERFLOW);
148c9582eb0SEric W. Biederman 	}
149334f485dSMiklos Szeredi 	return req;
1509bc5dddaSMiklos Szeredi 
1519bc5dddaSMiklos Szeredi  out:
152b8f95e5dSMiklos Szeredi 	fuse_drop_waiting(fc);
1539bc5dddaSMiklos Szeredi 	return ERR_PTR(err);
154334f485dSMiklos Szeredi }
1558b41e671SMaxim Patlasov 
15666abc359SMiklos Szeredi static void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
157334f485dSMiklos Szeredi {
158ec99f6d3SElena Reshetova 	if (refcount_dec_and_test(&req->count)) {
159825d6d33SMiklos Szeredi 		if (test_bit(FR_BACKGROUND, &req->flags)) {
160722d2beaSMaxim Patlasov 			/*
161722d2beaSMaxim Patlasov 			 * We get here in the unlikely case that a background
162722d2beaSMaxim Patlasov 			 * request was allocated but not sent
163722d2beaSMaxim Patlasov 			 */
164ae2dffa3SKirill Tkhai 			spin_lock(&fc->bg_lock);
165722d2beaSMaxim Patlasov 			if (!fc->blocked)
166722d2beaSMaxim Patlasov 				wake_up(&fc->blocked_waitq);
167ae2dffa3SKirill Tkhai 			spin_unlock(&fc->bg_lock);
168722d2beaSMaxim Patlasov 		}
169722d2beaSMaxim Patlasov 
170825d6d33SMiklos Szeredi 		if (test_bit(FR_WAITING, &req->flags)) {
171825d6d33SMiklos Szeredi 			__clear_bit(FR_WAITING, &req->flags);
172b8f95e5dSMiklos Szeredi 			fuse_drop_waiting(fc);
17373e0e738SMiklos Szeredi 		}
17433649c91SMiklos Szeredi 
175ce1d5a49SMiklos Szeredi 		fuse_request_free(req);
1767128ec2aSMiklos Szeredi 	}
1777128ec2aSMiklos Szeredi }
1787128ec2aSMiklos Szeredi 
17914d46d7aSStefan Hajnoczi unsigned int fuse_len_args(unsigned int numargs, struct fuse_arg *args)
180d12def1bSMiklos Szeredi {
181d12def1bSMiklos Szeredi 	unsigned nbytes = 0;
182d12def1bSMiklos Szeredi 	unsigned i;
183d12def1bSMiklos Szeredi 
184d12def1bSMiklos Szeredi 	for (i = 0; i < numargs; i++)
185d12def1bSMiklos Szeredi 		nbytes += args[i].size;
186d12def1bSMiklos Szeredi 
187d12def1bSMiklos Szeredi 	return nbytes;
188d12def1bSMiklos Szeredi }
18914d46d7aSStefan Hajnoczi EXPORT_SYMBOL_GPL(fuse_len_args);
190d12def1bSMiklos Szeredi 
19179d96effSStefan Hajnoczi u64 fuse_get_unique(struct fuse_iqueue *fiq)
192d12def1bSMiklos Szeredi {
193c59fd85eSKirill Tkhai 	fiq->reqctr += FUSE_REQ_ID_STEP;
194c59fd85eSKirill Tkhai 	return fiq->reqctr;
195d12def1bSMiklos Szeredi }
19679d96effSStefan Hajnoczi EXPORT_SYMBOL_GPL(fuse_get_unique);
197d12def1bSMiklos Szeredi 
198be2ff42cSKirill Tkhai static unsigned int fuse_req_hash(u64 unique)
199be2ff42cSKirill Tkhai {
200be2ff42cSKirill Tkhai 	return hash_long(unique & ~FUSE_INT_REQ_BIT, FUSE_PQ_HASH_BITS);
201be2ff42cSKirill Tkhai }
202be2ff42cSKirill Tkhai 
203ae3aad77SStefan Hajnoczi /**
204ae3aad77SStefan Hajnoczi  * A new request is available, wake fiq->waitq
205ae3aad77SStefan Hajnoczi  */
206ae3aad77SStefan Hajnoczi static void fuse_dev_wake_and_unlock(struct fuse_iqueue *fiq)
207ae3aad77SStefan Hajnoczi __releases(fiq->lock)
208ae3aad77SStefan Hajnoczi {
209ae3aad77SStefan Hajnoczi 	wake_up(&fiq->waitq);
210ae3aad77SStefan Hajnoczi 	kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
211ae3aad77SStefan Hajnoczi 	spin_unlock(&fiq->lock);
212ae3aad77SStefan Hajnoczi }
213ae3aad77SStefan Hajnoczi 
214ae3aad77SStefan Hajnoczi const struct fuse_iqueue_ops fuse_dev_fiq_ops = {
215ae3aad77SStefan Hajnoczi 	.wake_forget_and_unlock		= fuse_dev_wake_and_unlock,
216ae3aad77SStefan Hajnoczi 	.wake_interrupt_and_unlock	= fuse_dev_wake_and_unlock,
217ae3aad77SStefan Hajnoczi 	.wake_pending_and_unlock	= fuse_dev_wake_and_unlock,
218ae3aad77SStefan Hajnoczi };
219ae3aad77SStefan Hajnoczi EXPORT_SYMBOL_GPL(fuse_dev_fiq_ops);
220ae3aad77SStefan Hajnoczi 
221ae3aad77SStefan Hajnoczi static void queue_request_and_unlock(struct fuse_iqueue *fiq,
222ae3aad77SStefan Hajnoczi 				     struct fuse_req *req)
223ae3aad77SStefan Hajnoczi __releases(fiq->lock)
224d12def1bSMiklos Szeredi {
225d12def1bSMiklos Szeredi 	req->in.h.len = sizeof(struct fuse_in_header) +
22614d46d7aSStefan Hajnoczi 		fuse_len_args(req->args->in_numargs,
227d4993774SMiklos Szeredi 			      (struct fuse_arg *) req->args->in_args);
228f88996a9SMiklos Szeredi 	list_add_tail(&req->list, &fiq->pending);
229ae3aad77SStefan Hajnoczi 	fiq->ops->wake_pending_and_unlock(fiq);
230d12def1bSMiklos Szeredi }
231d12def1bSMiklos Szeredi 
23207e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
23307e77dcaSMiklos Szeredi 		       u64 nodeid, u64 nlookup)
23407e77dcaSMiklos Szeredi {
235f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
236f88996a9SMiklos Szeredi 
23702c048b9SMiklos Szeredi 	forget->forget_one.nodeid = nodeid;
23802c048b9SMiklos Szeredi 	forget->forget_one.nlookup = nlookup;
23907e77dcaSMiklos Szeredi 
24076e43c8cSEric Biggers 	spin_lock(&fiq->lock);
241e16714d8SMiklos Szeredi 	if (fiq->connected) {
242f88996a9SMiklos Szeredi 		fiq->forget_list_tail->next = forget;
243f88996a9SMiklos Szeredi 		fiq->forget_list_tail = forget;
244ae3aad77SStefan Hajnoczi 		fiq->ops->wake_forget_and_unlock(fiq);
2455dfcc87fSMiklos Szeredi 	} else {
2465dfcc87fSMiklos Szeredi 		kfree(forget);
24776e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
24807e77dcaSMiklos Szeredi 	}
249ae3aad77SStefan Hajnoczi }
25007e77dcaSMiklos Szeredi 
251d12def1bSMiklos Szeredi static void flush_bg_queue(struct fuse_conn *fc)
252d12def1bSMiklos Szeredi {
253e287179aSKirill Tkhai 	struct fuse_iqueue *fiq = &fc->iq;
254e287179aSKirill Tkhai 
2557a6d3c8bSCsaba Henk 	while (fc->active_background < fc->max_background &&
256d12def1bSMiklos Szeredi 	       !list_empty(&fc->bg_queue)) {
257d12def1bSMiklos Szeredi 		struct fuse_req *req;
258d12def1bSMiklos Szeredi 
259e287179aSKirill Tkhai 		req = list_first_entry(&fc->bg_queue, struct fuse_req, list);
260d12def1bSMiklos Szeredi 		list_del(&req->list);
261d12def1bSMiklos Szeredi 		fc->active_background++;
26276e43c8cSEric Biggers 		spin_lock(&fiq->lock);
263f88996a9SMiklos Szeredi 		req->in.h.unique = fuse_get_unique(fiq);
264ae3aad77SStefan Hajnoczi 		queue_request_and_unlock(fiq, req);
265d12def1bSMiklos Szeredi 	}
266d12def1bSMiklos Szeredi }
267d12def1bSMiklos Szeredi 
2686dbbcb12SMiklos Szeredi /*
269334f485dSMiklos Szeredi  * This function is called when a request is finished.  Either a reply
270f9a2842eSMiklos Szeredi  * has arrived or it was aborted (and not yet sent) or some error
271f43b155aSMiklos Szeredi  * occurred during communication with userspace, or the device file
27251eb01e7SMiklos Szeredi  * was closed.  The requester thread is woken up (if still waiting),
27351eb01e7SMiklos Szeredi  * the 'end' callback is called if given, else the reference to the
27451eb01e7SMiklos Szeredi  * request is released
275334f485dSMiklos Szeredi  */
27604ec5af0SStefan Hajnoczi void fuse_request_end(struct fuse_conn *fc, struct fuse_req *req)
277334f485dSMiklos Szeredi {
2784ce60812SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
279d4993774SMiklos Szeredi 	bool async = req->args->end;
280365ae710SMiklos Szeredi 
281efe2800fSMiklos Szeredi 	if (test_and_set_bit(FR_FINISHED, &req->flags))
282b8f95e5dSMiklos Szeredi 		goto put_request;
283217316a6SKirill Tkhai 	/*
284217316a6SKirill Tkhai 	 * test_and_set_bit() implies smp_mb() between bit
285217316a6SKirill Tkhai 	 * changing and below intr_entry check. Pairs with
286217316a6SKirill Tkhai 	 * smp_mb() from queue_interrupt().
287217316a6SKirill Tkhai 	 */
288217316a6SKirill Tkhai 	if (!list_empty(&req->intr_entry)) {
28976e43c8cSEric Biggers 		spin_lock(&fiq->lock);
2900d8e84b0SMiklos Szeredi 		list_del_init(&req->intr_entry);
29176e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
292217316a6SKirill Tkhai 	}
29333e14b4dSMiklos Szeredi 	WARN_ON(test_bit(FR_PENDING, &req->flags));
29433e14b4dSMiklos Szeredi 	WARN_ON(test_bit(FR_SENT, &req->flags));
295825d6d33SMiklos Szeredi 	if (test_bit(FR_BACKGROUND, &req->flags)) {
296ae2dffa3SKirill Tkhai 		spin_lock(&fc->bg_lock);
297825d6d33SMiklos Szeredi 		clear_bit(FR_BACKGROUND, &req->flags);
298908a572bSMiklos Szeredi 		if (fc->num_background == fc->max_background) {
29951eb01e7SMiklos Szeredi 			fc->blocked = 0;
300722d2beaSMaxim Patlasov 			wake_up(&fc->blocked_waitq);
301908a572bSMiklos Szeredi 		} else if (!fc->blocked) {
302908a572bSMiklos Szeredi 			/*
303908a572bSMiklos Szeredi 			 * Wake up next waiter, if any.  It's okay to use
304908a572bSMiklos Szeredi 			 * waitqueue_active(), as we've already synced up
305908a572bSMiklos Szeredi 			 * fc->blocked with waiters with the wake_up() call
306908a572bSMiklos Szeredi 			 * above.
307908a572bSMiklos Szeredi 			 */
308908a572bSMiklos Szeredi 			if (waitqueue_active(&fc->blocked_waitq))
309908a572bSMiklos Szeredi 				wake_up(&fc->blocked_waitq);
310908a572bSMiklos Szeredi 		}
311722d2beaSMaxim Patlasov 
3128a301eb1STejun Heo 		if (fc->num_background == fc->congestion_threshold && fc->sb) {
3135f7f7543SJan Kara 			clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
3145f7f7543SJan Kara 			clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
315f92b99b9SMiklos Szeredi 		}
31651eb01e7SMiklos Szeredi 		fc->num_background--;
317d12def1bSMiklos Szeredi 		fc->active_background--;
318d12def1bSMiklos Szeredi 		flush_bg_queue(fc);
319ae2dffa3SKirill Tkhai 		spin_unlock(&fc->bg_lock);
3205e0fed71SKirill Tkhai 	} else {
3215e0fed71SKirill Tkhai 		/* Wake up waiter sleeping in request_wait_answer() */
32251eb01e7SMiklos Szeredi 		wake_up(&req->waitq);
3235e0fed71SKirill Tkhai 	}
3245e0fed71SKirill Tkhai 
325d4993774SMiklos Szeredi 	if (async)
326d4993774SMiklos Szeredi 		req->args->end(fc, req->args, req->out.h.error);
327b8f95e5dSMiklos Szeredi put_request:
328f43b155aSMiklos Szeredi 	fuse_put_request(fc, req);
329334f485dSMiklos Szeredi }
33004ec5af0SStefan Hajnoczi EXPORT_SYMBOL_GPL(fuse_request_end);
331334f485dSMiklos Szeredi 
332b782911bSKirill Tkhai static int queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
333a4d27e75SMiklos Szeredi {
33476e43c8cSEric Biggers 	spin_lock(&fiq->lock);
335b782911bSKirill Tkhai 	/* Check for we've sent request to interrupt this req */
336b782911bSKirill Tkhai 	if (unlikely(!test_bit(FR_INTERRUPTED, &req->flags))) {
33776e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
338b782911bSKirill Tkhai 		return -EINVAL;
339b782911bSKirill Tkhai 	}
340b782911bSKirill Tkhai 
341217316a6SKirill Tkhai 	if (list_empty(&req->intr_entry)) {
342217316a6SKirill Tkhai 		list_add_tail(&req->intr_entry, &fiq->interrupts);
343217316a6SKirill Tkhai 		/*
344217316a6SKirill Tkhai 		 * Pairs with smp_mb() implied by test_and_set_bit()
345217316a6SKirill Tkhai 		 * from request_end().
346217316a6SKirill Tkhai 		 */
347217316a6SKirill Tkhai 		smp_mb();
3486ba4d272SSahitya Tummala 		if (test_bit(FR_FINISHED, &req->flags)) {
349217316a6SKirill Tkhai 			list_del_init(&req->intr_entry);
35076e43c8cSEric Biggers 			spin_unlock(&fiq->lock);
351b782911bSKirill Tkhai 			return 0;
3526ba4d272SSahitya Tummala 		}
353ae3aad77SStefan Hajnoczi 		fiq->ops->wake_interrupt_and_unlock(fiq);
354ae3aad77SStefan Hajnoczi 	} else {
35576e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
356ae3aad77SStefan Hajnoczi 	}
357b782911bSKirill Tkhai 	return 0;
358a4d27e75SMiklos Szeredi }
359a4d27e75SMiklos Szeredi 
3607c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
361334f485dSMiklos Szeredi {
3624ce60812SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
363c4775267SMiklos Szeredi 	int err;
364c4775267SMiklos Szeredi 
365a4d27e75SMiklos Szeredi 	if (!fc->no_interrupt) {
366a4d27e75SMiklos Szeredi 		/* Any signal may interrupt this */
367c4775267SMiklos Szeredi 		err = wait_event_interruptible(req->waitq,
36833e14b4dSMiklos Szeredi 					test_bit(FR_FINISHED, &req->flags));
369c4775267SMiklos Szeredi 		if (!err)
370334f485dSMiklos Szeredi 			return;
371334f485dSMiklos Szeredi 
372825d6d33SMiklos Szeredi 		set_bit(FR_INTERRUPTED, &req->flags);
3738f7bb368SMiklos Szeredi 		/* matches barrier in fuse_dev_do_read() */
3748f7bb368SMiklos Szeredi 		smp_mb__after_atomic();
37533e14b4dSMiklos Szeredi 		if (test_bit(FR_SENT, &req->flags))
3764ce60812SMiklos Szeredi 			queue_interrupt(fiq, req);
377a4d27e75SMiklos Szeredi 	}
378a4d27e75SMiklos Szeredi 
379825d6d33SMiklos Szeredi 	if (!test_bit(FR_FORCE, &req->flags)) {
380a4d27e75SMiklos Szeredi 		/* Only fatal signals may interrupt this */
3817d3a07fcSAl Viro 		err = wait_event_killable(req->waitq,
38233e14b4dSMiklos Szeredi 					test_bit(FR_FINISHED, &req->flags));
383c4775267SMiklos Szeredi 		if (!err)
384a4d27e75SMiklos Szeredi 			return;
385a4d27e75SMiklos Szeredi 
38676e43c8cSEric Biggers 		spin_lock(&fiq->lock);
387a131de0aSMiklos Szeredi 		/* Request is not yet in userspace, bail out */
38833e14b4dSMiklos Szeredi 		if (test_bit(FR_PENDING, &req->flags)) {
389a131de0aSMiklos Szeredi 			list_del(&req->list);
39076e43c8cSEric Biggers 			spin_unlock(&fiq->lock);
391a131de0aSMiklos Szeredi 			__fuse_put_request(req);
392334f485dSMiklos Szeredi 			req->out.h.error = -EINTR;
393a131de0aSMiklos Szeredi 			return;
394a131de0aSMiklos Szeredi 		}
39576e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
396a131de0aSMiklos Szeredi 	}
397a131de0aSMiklos Szeredi 
398a131de0aSMiklos Szeredi 	/*
399a131de0aSMiklos Szeredi 	 * Either request is already in userspace, or it was forced.
400a131de0aSMiklos Szeredi 	 * Wait it out.
401a131de0aSMiklos Szeredi 	 */
40233e14b4dSMiklos Szeredi 	wait_event(req->waitq, test_bit(FR_FINISHED, &req->flags));
403334f485dSMiklos Szeredi }
404334f485dSMiklos Szeredi 
4056a4e922cSEric Wong static void __fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
406334f485dSMiklos Szeredi {
407e16714d8SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
408e16714d8SMiklos Szeredi 
409825d6d33SMiklos Szeredi 	BUG_ON(test_bit(FR_BACKGROUND, &req->flags));
41076e43c8cSEric Biggers 	spin_lock(&fiq->lock);
411e16714d8SMiklos Szeredi 	if (!fiq->connected) {
41276e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
413334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
414c4775267SMiklos Szeredi 	} else {
415f88996a9SMiklos Szeredi 		req->in.h.unique = fuse_get_unique(fiq);
416334f485dSMiklos Szeredi 		/* acquire extra reference, since request is still needed
41704ec5af0SStefan Hajnoczi 		   after fuse_request_end() */
418334f485dSMiklos Szeredi 		__fuse_get_request(req);
419ae3aad77SStefan Hajnoczi 		queue_request_and_unlock(fiq, req);
420334f485dSMiklos Szeredi 
4217c352bdfSMiklos Szeredi 		request_wait_answer(fc, req);
42204ec5af0SStefan Hajnoczi 		/* Pairs with smp_wmb() in fuse_request_end() */
423c4775267SMiklos Szeredi 		smp_rmb();
424334f485dSMiklos Szeredi 	}
425334f485dSMiklos Szeredi }
4266a4e922cSEric Wong 
42721f62174SMiklos Szeredi static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args)
42821f62174SMiklos Szeredi {
429d5b48543SMiklos Szeredi 	if (fc->minor < 4 && args->opcode == FUSE_STATFS)
430d5b48543SMiklos Szeredi 		args->out_args[0].size = FUSE_COMPAT_STATFS_SIZE;
43121f62174SMiklos Szeredi 
43221f62174SMiklos Szeredi 	if (fc->minor < 9) {
433d5b48543SMiklos Szeredi 		switch (args->opcode) {
43421f62174SMiklos Szeredi 		case FUSE_LOOKUP:
43521f62174SMiklos Szeredi 		case FUSE_CREATE:
43621f62174SMiklos Szeredi 		case FUSE_MKNOD:
43721f62174SMiklos Szeredi 		case FUSE_MKDIR:
43821f62174SMiklos Szeredi 		case FUSE_SYMLINK:
43921f62174SMiklos Szeredi 		case FUSE_LINK:
440d5b48543SMiklos Szeredi 			args->out_args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
44121f62174SMiklos Szeredi 			break;
44221f62174SMiklos Szeredi 		case FUSE_GETATTR:
44321f62174SMiklos Szeredi 		case FUSE_SETATTR:
444d5b48543SMiklos Szeredi 			args->out_args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
44521f62174SMiklos Szeredi 			break;
44621f62174SMiklos Szeredi 		}
44721f62174SMiklos Szeredi 	}
44821f62174SMiklos Szeredi 	if (fc->minor < 12) {
449d5b48543SMiklos Szeredi 		switch (args->opcode) {
45021f62174SMiklos Szeredi 		case FUSE_CREATE:
451d5b48543SMiklos Szeredi 			args->in_args[0].size = sizeof(struct fuse_open_in);
45221f62174SMiklos Szeredi 			break;
45321f62174SMiklos Szeredi 		case FUSE_MKNOD:
454d5b48543SMiklos Szeredi 			args->in_args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE;
45521f62174SMiklos Szeredi 			break;
45621f62174SMiklos Szeredi 		}
45721f62174SMiklos Szeredi 	}
45821f62174SMiklos Szeredi }
45921f62174SMiklos Szeredi 
460e413754bSMiklos Szeredi static void fuse_force_creds(struct fuse_conn *fc, struct fuse_req *req)
461e413754bSMiklos Szeredi {
462e413754bSMiklos Szeredi 	req->in.h.uid = from_kuid_munged(fc->user_ns, current_fsuid());
463e413754bSMiklos Szeredi 	req->in.h.gid = from_kgid_munged(fc->user_ns, current_fsgid());
464e413754bSMiklos Szeredi 	req->in.h.pid = pid_nr_ns(task_pid(current), fc->pid_ns);
465e413754bSMiklos Szeredi }
466e413754bSMiklos Szeredi 
4675addcd5dSYueHaibing static void fuse_args_to_req(struct fuse_req *req, struct fuse_args *args)
46868583165SMiklos Szeredi {
46968583165SMiklos Szeredi 	req->in.h.opcode = args->opcode;
47068583165SMiklos Szeredi 	req->in.h.nodeid = args->nodeid;
471d4993774SMiklos Szeredi 	req->args = args;
47268583165SMiklos Szeredi }
47368583165SMiklos Szeredi 
4747078187aSMiklos Szeredi ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args)
4757078187aSMiklos Szeredi {
4767078187aSMiklos Szeredi 	struct fuse_req *req;
4777078187aSMiklos Szeredi 	ssize_t ret;
4787078187aSMiklos Szeredi 
479c500ebaaSMiklos Szeredi 	if (args->force) {
480e413754bSMiklos Szeredi 		atomic_inc(&fc->num_waiting);
4817213394cSMiklos Szeredi 		req = fuse_request_alloc(GFP_KERNEL | __GFP_NOFAIL);
482e413754bSMiklos Szeredi 
483e413754bSMiklos Szeredi 		if (!args->nocreds)
484e413754bSMiklos Szeredi 			fuse_force_creds(fc, req);
485e413754bSMiklos Szeredi 
486e413754bSMiklos Szeredi 		__set_bit(FR_WAITING, &req->flags);
487c500ebaaSMiklos Szeredi 		__set_bit(FR_FORCE, &req->flags);
488c500ebaaSMiklos Szeredi 	} else {
489e413754bSMiklos Szeredi 		WARN_ON(args->nocreds);
4907213394cSMiklos Szeredi 		req = fuse_get_req(fc, false);
4917078187aSMiklos Szeredi 		if (IS_ERR(req))
4927078187aSMiklos Szeredi 			return PTR_ERR(req);
493c500ebaaSMiklos Szeredi 	}
4947078187aSMiklos Szeredi 
49521f62174SMiklos Szeredi 	/* Needs to be done after fuse_get_req() so that fc->minor is valid */
49621f62174SMiklos Szeredi 	fuse_adjust_compat(fc, args);
49768583165SMiklos Szeredi 	fuse_args_to_req(req, args);
49821f62174SMiklos Szeredi 
499454a7613SMiklos Szeredi 	if (!args->noreply)
500454a7613SMiklos Szeredi 		__set_bit(FR_ISREPLY, &req->flags);
501454a7613SMiklos Szeredi 	__fuse_request_send(fc, req);
5027078187aSMiklos Szeredi 	ret = req->out.h.error;
503d5b48543SMiklos Szeredi 	if (!ret && args->out_argvar) {
504093f38a2SMiklos Szeredi 		BUG_ON(args->out_numargs == 0);
505d4993774SMiklos Szeredi 		ret = args->out_args[args->out_numargs - 1].size;
5067078187aSMiklos Szeredi 	}
5077078187aSMiklos Szeredi 	fuse_put_request(fc, req);
5087078187aSMiklos Szeredi 
5097078187aSMiklos Szeredi 	return ret;
5107078187aSMiklos Szeredi }
5117078187aSMiklos Szeredi 
51266abc359SMiklos Szeredi static bool fuse_request_queue_background(struct fuse_conn *fc,
51366abc359SMiklos Szeredi 					  struct fuse_req *req)
514334f485dSMiklos Szeredi {
51563825b4eSKirill Tkhai 	bool queued = false;
51663825b4eSKirill Tkhai 
51763825b4eSKirill Tkhai 	WARN_ON(!test_bit(FR_BACKGROUND, &req->flags));
518825d6d33SMiklos Szeredi 	if (!test_bit(FR_WAITING, &req->flags)) {
519825d6d33SMiklos Szeredi 		__set_bit(FR_WAITING, &req->flags);
5205437f241SMiklos Szeredi 		atomic_inc(&fc->num_waiting);
5215437f241SMiklos Szeredi 	}
522825d6d33SMiklos Szeredi 	__set_bit(FR_ISREPLY, &req->flags);
523ae2dffa3SKirill Tkhai 	spin_lock(&fc->bg_lock);
52463825b4eSKirill Tkhai 	if (likely(fc->connected)) {
52551eb01e7SMiklos Szeredi 		fc->num_background++;
5267a6d3c8bSCsaba Henk 		if (fc->num_background == fc->max_background)
52751eb01e7SMiklos Szeredi 			fc->blocked = 1;
5287fbbe972SJan Kara 		if (fc->num_background == fc->congestion_threshold && fc->sb) {
5295f7f7543SJan Kara 			set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC);
5305f7f7543SJan Kara 			set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC);
531f92b99b9SMiklos Szeredi 		}
532d12def1bSMiklos Szeredi 		list_add_tail(&req->list, &fc->bg_queue);
533d12def1bSMiklos Szeredi 		flush_bg_queue(fc);
53463825b4eSKirill Tkhai 		queued = true;
53563825b4eSKirill Tkhai 	}
536ae2dffa3SKirill Tkhai 	spin_unlock(&fc->bg_lock);
53763825b4eSKirill Tkhai 
53863825b4eSKirill Tkhai 	return queued;
539d12def1bSMiklos Szeredi }
54051eb01e7SMiklos Szeredi 
54112597287SMiklos Szeredi int fuse_simple_background(struct fuse_conn *fc, struct fuse_args *args,
54212597287SMiklos Szeredi 			    gfp_t gfp_flags)
54312597287SMiklos Szeredi {
54412597287SMiklos Szeredi 	struct fuse_req *req;
54512597287SMiklos Szeredi 
54612597287SMiklos Szeredi 	if (args->force) {
54712597287SMiklos Szeredi 		WARN_ON(!args->nocreds);
5487213394cSMiklos Szeredi 		req = fuse_request_alloc(gfp_flags);
54912597287SMiklos Szeredi 		if (!req)
55012597287SMiklos Szeredi 			return -ENOMEM;
55112597287SMiklos Szeredi 		__set_bit(FR_BACKGROUND, &req->flags);
55212597287SMiklos Szeredi 	} else {
55312597287SMiklos Szeredi 		WARN_ON(args->nocreds);
5547213394cSMiklos Szeredi 		req = fuse_get_req(fc, true);
55512597287SMiklos Szeredi 		if (IS_ERR(req))
55612597287SMiklos Szeredi 			return PTR_ERR(req);
55712597287SMiklos Szeredi 	}
55812597287SMiklos Szeredi 
55912597287SMiklos Szeredi 	fuse_args_to_req(req, args);
56012597287SMiklos Szeredi 
56112597287SMiklos Szeredi 	if (!fuse_request_queue_background(fc, req)) {
56212597287SMiklos Szeredi 		fuse_put_request(fc, req);
56312597287SMiklos Szeredi 		return -ENOTCONN;
56412597287SMiklos Szeredi 	}
56512597287SMiklos Szeredi 
56612597287SMiklos Szeredi 	return 0;
56712597287SMiklos Szeredi }
56812597287SMiklos Szeredi EXPORT_SYMBOL_GPL(fuse_simple_background);
56912597287SMiklos Szeredi 
57075b399ddSMiklos Szeredi static int fuse_simple_notify_reply(struct fuse_conn *fc,
57175b399ddSMiklos Szeredi 				    struct fuse_args *args, u64 unique)
5722d45ba38SMiklos Szeredi {
57375b399ddSMiklos Szeredi 	struct fuse_req *req;
574f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
57575b399ddSMiklos Szeredi 	int err = 0;
57675b399ddSMiklos Szeredi 
5777213394cSMiklos Szeredi 	req = fuse_get_req(fc, false);
57875b399ddSMiklos Szeredi 	if (IS_ERR(req))
57975b399ddSMiklos Szeredi 		return PTR_ERR(req);
5802d45ba38SMiklos Szeredi 
581825d6d33SMiklos Szeredi 	__clear_bit(FR_ISREPLY, &req->flags);
5822d45ba38SMiklos Szeredi 	req->in.h.unique = unique;
58375b399ddSMiklos Szeredi 
58475b399ddSMiklos Szeredi 	fuse_args_to_req(req, args);
58575b399ddSMiklos Szeredi 
58676e43c8cSEric Biggers 	spin_lock(&fiq->lock);
587e16714d8SMiklos Szeredi 	if (fiq->connected) {
588ae3aad77SStefan Hajnoczi 		queue_request_and_unlock(fiq, req);
58975b399ddSMiklos Szeredi 	} else {
59075b399ddSMiklos Szeredi 		err = -ENODEV;
59175b399ddSMiklos Szeredi 		spin_unlock(&fiq->lock);
59275b399ddSMiklos Szeredi 		fuse_put_request(fc, req);
5932d45ba38SMiklos Szeredi 	}
5942d45ba38SMiklos Szeredi 
5952d45ba38SMiklos Szeredi 	return err;
5962d45ba38SMiklos Szeredi }
5972d45ba38SMiklos Szeredi 
5983be5a52bSMiklos Szeredi /*
599334f485dSMiklos Szeredi  * Lock the request.  Up to the next unlock_request() there mustn't be
600334f485dSMiklos Szeredi  * anything that could cause a page-fault.  If the request was already
601f9a2842eSMiklos Szeredi  * aborted bail out.
602334f485dSMiklos Szeredi  */
603dc00809aSMiklos Szeredi static int lock_request(struct fuse_req *req)
604334f485dSMiklos Szeredi {
605334f485dSMiklos Szeredi 	int err = 0;
606334f485dSMiklos Szeredi 	if (req) {
607dc00809aSMiklos Szeredi 		spin_lock(&req->waitq.lock);
608825d6d33SMiklos Szeredi 		if (test_bit(FR_ABORTED, &req->flags))
609334f485dSMiklos Szeredi 			err = -ENOENT;
610334f485dSMiklos Szeredi 		else
611825d6d33SMiklos Szeredi 			set_bit(FR_LOCKED, &req->flags);
612dc00809aSMiklos Szeredi 		spin_unlock(&req->waitq.lock);
613334f485dSMiklos Szeredi 	}
614334f485dSMiklos Szeredi 	return err;
615334f485dSMiklos Szeredi }
616334f485dSMiklos Szeredi 
617334f485dSMiklos Szeredi /*
6180d8e84b0SMiklos Szeredi  * Unlock request.  If it was aborted while locked, caller is responsible
6190d8e84b0SMiklos Szeredi  * for unlocking and ending the request.
620334f485dSMiklos Szeredi  */
621dc00809aSMiklos Szeredi static int unlock_request(struct fuse_req *req)
622334f485dSMiklos Szeredi {
6230d8e84b0SMiklos Szeredi 	int err = 0;
624334f485dSMiklos Szeredi 	if (req) {
625dc00809aSMiklos Szeredi 		spin_lock(&req->waitq.lock);
626825d6d33SMiklos Szeredi 		if (test_bit(FR_ABORTED, &req->flags))
6270d8e84b0SMiklos Szeredi 			err = -ENOENT;
6280d8e84b0SMiklos Szeredi 		else
629825d6d33SMiklos Szeredi 			clear_bit(FR_LOCKED, &req->flags);
630dc00809aSMiklos Szeredi 		spin_unlock(&req->waitq.lock);
631334f485dSMiklos Szeredi 	}
6320d8e84b0SMiklos Szeredi 	return err;
633334f485dSMiklos Szeredi }
634334f485dSMiklos Szeredi 
635334f485dSMiklos Szeredi struct fuse_copy_state {
636334f485dSMiklos Szeredi 	int write;
637334f485dSMiklos Szeredi 	struct fuse_req *req;
6386c09e94aSAl Viro 	struct iov_iter *iter;
639dd3bb14fSMiklos Szeredi 	struct pipe_buffer *pipebufs;
640dd3bb14fSMiklos Szeredi 	struct pipe_buffer *currbuf;
641dd3bb14fSMiklos Szeredi 	struct pipe_inode_info *pipe;
642334f485dSMiklos Szeredi 	unsigned long nr_segs;
643334f485dSMiklos Szeredi 	struct page *pg;
644334f485dSMiklos Szeredi 	unsigned len;
645c55a01d3SMiklos Szeredi 	unsigned offset;
646ce534fb0SMiklos Szeredi 	unsigned move_pages:1;
647334f485dSMiklos Szeredi };
648334f485dSMiklos Szeredi 
649dc00809aSMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, int write,
6506c09e94aSAl Viro 			   struct iov_iter *iter)
651334f485dSMiklos Szeredi {
652334f485dSMiklos Szeredi 	memset(cs, 0, sizeof(*cs));
653334f485dSMiklos Szeredi 	cs->write = write;
6546c09e94aSAl Viro 	cs->iter = iter;
655334f485dSMiklos Szeredi }
656334f485dSMiklos Szeredi 
657334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */
6588bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs)
659334f485dSMiklos Szeredi {
660dd3bb14fSMiklos Szeredi 	if (cs->currbuf) {
661dd3bb14fSMiklos Szeredi 		struct pipe_buffer *buf = cs->currbuf;
662dd3bb14fSMiklos Szeredi 
663c55a01d3SMiklos Szeredi 		if (cs->write)
664c3021629SMiklos Szeredi 			buf->len = PAGE_SIZE - cs->len;
665dd3bb14fSMiklos Szeredi 		cs->currbuf = NULL;
666c55a01d3SMiklos Szeredi 	} else if (cs->pg) {
667334f485dSMiklos Szeredi 		if (cs->write) {
668334f485dSMiklos Szeredi 			flush_dcache_page(cs->pg);
669334f485dSMiklos Szeredi 			set_page_dirty_lock(cs->pg);
670334f485dSMiklos Szeredi 		}
671334f485dSMiklos Szeredi 		put_page(cs->pg);
672334f485dSMiklos Szeredi 	}
673c55a01d3SMiklos Szeredi 	cs->pg = NULL;
674334f485dSMiklos Szeredi }
675334f485dSMiklos Szeredi 
676334f485dSMiklos Szeredi /*
677334f485dSMiklos Szeredi  * Get another pagefull of userspace buffer, and map it to kernel
678334f485dSMiklos Szeredi  * address space, and lock request
679334f485dSMiklos Szeredi  */
680334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs)
681334f485dSMiklos Szeredi {
682c55a01d3SMiklos Szeredi 	struct page *page;
683334f485dSMiklos Szeredi 	int err;
684334f485dSMiklos Szeredi 
685dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
6860d8e84b0SMiklos Szeredi 	if (err)
6870d8e84b0SMiklos Szeredi 		return err;
6880d8e84b0SMiklos Szeredi 
689334f485dSMiklos Szeredi 	fuse_copy_finish(cs);
690dd3bb14fSMiklos Szeredi 	if (cs->pipebufs) {
691dd3bb14fSMiklos Szeredi 		struct pipe_buffer *buf = cs->pipebufs;
692dd3bb14fSMiklos Szeredi 
693c3021629SMiklos Szeredi 		if (!cs->write) {
694fba597dbSMiklos Szeredi 			err = pipe_buf_confirm(cs->pipe, buf);
695dd3bb14fSMiklos Szeredi 			if (err)
696dd3bb14fSMiklos Szeredi 				return err;
697dd3bb14fSMiklos Szeredi 
698dd3bb14fSMiklos Szeredi 			BUG_ON(!cs->nr_segs);
699dd3bb14fSMiklos Szeredi 			cs->currbuf = buf;
700c55a01d3SMiklos Szeredi 			cs->pg = buf->page;
701c55a01d3SMiklos Szeredi 			cs->offset = buf->offset;
702dd3bb14fSMiklos Szeredi 			cs->len = buf->len;
703dd3bb14fSMiklos Szeredi 			cs->pipebufs++;
704dd3bb14fSMiklos Szeredi 			cs->nr_segs--;
705dd3bb14fSMiklos Szeredi 		} else {
706c3021629SMiklos Szeredi 			if (cs->nr_segs == cs->pipe->buffers)
707c3021629SMiklos Szeredi 				return -EIO;
708c3021629SMiklos Szeredi 
709c3021629SMiklos Szeredi 			page = alloc_page(GFP_HIGHUSER);
710c3021629SMiklos Szeredi 			if (!page)
711c3021629SMiklos Szeredi 				return -ENOMEM;
712c3021629SMiklos Szeredi 
713c3021629SMiklos Szeredi 			buf->page = page;
714c3021629SMiklos Szeredi 			buf->offset = 0;
715c3021629SMiklos Szeredi 			buf->len = 0;
716c3021629SMiklos Szeredi 
717c3021629SMiklos Szeredi 			cs->currbuf = buf;
718c55a01d3SMiklos Szeredi 			cs->pg = page;
719c55a01d3SMiklos Szeredi 			cs->offset = 0;
720c3021629SMiklos Szeredi 			cs->len = PAGE_SIZE;
721c3021629SMiklos Szeredi 			cs->pipebufs++;
722c3021629SMiklos Szeredi 			cs->nr_segs++;
723c3021629SMiklos Szeredi 		}
724c3021629SMiklos Szeredi 	} else {
7256c09e94aSAl Viro 		size_t off;
7266c09e94aSAl Viro 		err = iov_iter_get_pages(cs->iter, &page, PAGE_SIZE, 1, &off);
727334f485dSMiklos Szeredi 		if (err < 0)
728334f485dSMiklos Szeredi 			return err;
7296c09e94aSAl Viro 		BUG_ON(!err);
7306c09e94aSAl Viro 		cs->len = err;
7316c09e94aSAl Viro 		cs->offset = off;
732c55a01d3SMiklos Szeredi 		cs->pg = page;
7336c09e94aSAl Viro 		iov_iter_advance(cs->iter, err);
734dd3bb14fSMiklos Szeredi 	}
735334f485dSMiklos Szeredi 
736dc00809aSMiklos Szeredi 	return lock_request(cs->req);
737334f485dSMiklos Szeredi }
738334f485dSMiklos Szeredi 
739334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */
7408bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
741334f485dSMiklos Szeredi {
742334f485dSMiklos Szeredi 	unsigned ncpy = min(*size, cs->len);
743334f485dSMiklos Szeredi 	if (val) {
744c55a01d3SMiklos Szeredi 		void *pgaddr = kmap_atomic(cs->pg);
745c55a01d3SMiklos Szeredi 		void *buf = pgaddr + cs->offset;
746c55a01d3SMiklos Szeredi 
747334f485dSMiklos Szeredi 		if (cs->write)
748c55a01d3SMiklos Szeredi 			memcpy(buf, *val, ncpy);
749334f485dSMiklos Szeredi 		else
750c55a01d3SMiklos Szeredi 			memcpy(*val, buf, ncpy);
751c55a01d3SMiklos Szeredi 
752c55a01d3SMiklos Szeredi 		kunmap_atomic(pgaddr);
753334f485dSMiklos Szeredi 		*val += ncpy;
754334f485dSMiklos Szeredi 	}
755334f485dSMiklos Szeredi 	*size -= ncpy;
756334f485dSMiklos Szeredi 	cs->len -= ncpy;
757c55a01d3SMiklos Szeredi 	cs->offset += ncpy;
758334f485dSMiklos Szeredi 	return ncpy;
759334f485dSMiklos Szeredi }
760334f485dSMiklos Szeredi 
761ce534fb0SMiklos Szeredi static int fuse_check_page(struct page *page)
762ce534fb0SMiklos Szeredi {
763ce534fb0SMiklos Szeredi 	if (page_mapcount(page) ||
764ce534fb0SMiklos Szeredi 	    page->mapping != NULL ||
765ce534fb0SMiklos Szeredi 	    page_count(page) != 1 ||
766ce534fb0SMiklos Szeredi 	    (page->flags & PAGE_FLAGS_CHECK_AT_PREP &
767ce534fb0SMiklos Szeredi 	     ~(1 << PG_locked |
768ce534fb0SMiklos Szeredi 	       1 << PG_referenced |
769ce534fb0SMiklos Szeredi 	       1 << PG_uptodate |
770ce534fb0SMiklos Szeredi 	       1 << PG_lru |
771ce534fb0SMiklos Szeredi 	       1 << PG_active |
772ce534fb0SMiklos Szeredi 	       1 << PG_reclaim))) {
773f2294482SKirill Smelkov 		pr_warn("trying to steal weird page\n");
774f2294482SKirill Smelkov 		pr_warn("  page=%p index=%li flags=%08lx, count=%i, mapcount=%i, mapping=%p\n", page, page->index, page->flags, page_count(page), page_mapcount(page), page->mapping);
775ce534fb0SMiklos Szeredi 		return 1;
776ce534fb0SMiklos Szeredi 	}
777ce534fb0SMiklos Szeredi 	return 0;
778ce534fb0SMiklos Szeredi }
779ce534fb0SMiklos Szeredi 
780ce534fb0SMiklos Szeredi static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
781ce534fb0SMiklos Szeredi {
782ce534fb0SMiklos Szeredi 	int err;
783ce534fb0SMiklos Szeredi 	struct page *oldpage = *pagep;
784ce534fb0SMiklos Szeredi 	struct page *newpage;
785ce534fb0SMiklos Szeredi 	struct pipe_buffer *buf = cs->pipebufs;
786ce534fb0SMiklos Szeredi 
787dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
7880d8e84b0SMiklos Szeredi 	if (err)
7890d8e84b0SMiklos Szeredi 		return err;
7900d8e84b0SMiklos Szeredi 
791ce534fb0SMiklos Szeredi 	fuse_copy_finish(cs);
792ce534fb0SMiklos Szeredi 
793fba597dbSMiklos Szeredi 	err = pipe_buf_confirm(cs->pipe, buf);
794ce534fb0SMiklos Szeredi 	if (err)
795ce534fb0SMiklos Szeredi 		return err;
796ce534fb0SMiklos Szeredi 
797ce534fb0SMiklos Szeredi 	BUG_ON(!cs->nr_segs);
798ce534fb0SMiklos Szeredi 	cs->currbuf = buf;
799ce534fb0SMiklos Szeredi 	cs->len = buf->len;
800ce534fb0SMiklos Szeredi 	cs->pipebufs++;
801ce534fb0SMiklos Szeredi 	cs->nr_segs--;
802ce534fb0SMiklos Szeredi 
803ce534fb0SMiklos Szeredi 	if (cs->len != PAGE_SIZE)
804ce534fb0SMiklos Szeredi 		goto out_fallback;
805ce534fb0SMiklos Szeredi 
806ca76f5b6SMiklos Szeredi 	if (pipe_buf_steal(cs->pipe, buf) != 0)
807ce534fb0SMiklos Szeredi 		goto out_fallback;
808ce534fb0SMiklos Szeredi 
809ce534fb0SMiklos Szeredi 	newpage = buf->page;
810ce534fb0SMiklos Szeredi 
811aa991b3bSMiklos Szeredi 	if (!PageUptodate(newpage))
812aa991b3bSMiklos Szeredi 		SetPageUptodate(newpage);
813ce534fb0SMiklos Szeredi 
814ce534fb0SMiklos Szeredi 	ClearPageMappedToDisk(newpage);
815ce534fb0SMiklos Szeredi 
816ce534fb0SMiklos Szeredi 	if (fuse_check_page(newpage) != 0)
817ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
818ce534fb0SMiklos Szeredi 
819ce534fb0SMiklos Szeredi 	/*
820ce534fb0SMiklos Szeredi 	 * This is a new and locked page, it shouldn't be mapped or
821ce534fb0SMiklos Szeredi 	 * have any special flags on it
822ce534fb0SMiklos Szeredi 	 */
823ce534fb0SMiklos Szeredi 	if (WARN_ON(page_mapped(oldpage)))
824ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
825ce534fb0SMiklos Szeredi 	if (WARN_ON(page_has_private(oldpage)))
826ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
827ce534fb0SMiklos Szeredi 	if (WARN_ON(PageDirty(oldpage) || PageWriteback(oldpage)))
828ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
829ce534fb0SMiklos Szeredi 	if (WARN_ON(PageMlocked(oldpage)))
830ce534fb0SMiklos Szeredi 		goto out_fallback_unlock;
831ce534fb0SMiklos Szeredi 
832ef6a3c63SMiklos Szeredi 	err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL);
833ce534fb0SMiklos Szeredi 	if (err) {
834ef6a3c63SMiklos Szeredi 		unlock_page(newpage);
835ef6a3c63SMiklos Szeredi 		return err;
836ce534fb0SMiklos Szeredi 	}
837ef6a3c63SMiklos Szeredi 
83809cbfeafSKirill A. Shutemov 	get_page(newpage);
839ce534fb0SMiklos Szeredi 
840ce534fb0SMiklos Szeredi 	if (!(buf->flags & PIPE_BUF_FLAG_LRU))
841ce534fb0SMiklos Szeredi 		lru_cache_add_file(newpage);
842ce534fb0SMiklos Szeredi 
843ce534fb0SMiklos Szeredi 	err = 0;
844dc00809aSMiklos Szeredi 	spin_lock(&cs->req->waitq.lock);
845825d6d33SMiklos Szeredi 	if (test_bit(FR_ABORTED, &cs->req->flags))
846ce534fb0SMiklos Szeredi 		err = -ENOENT;
847ce534fb0SMiklos Szeredi 	else
848ce534fb0SMiklos Szeredi 		*pagep = newpage;
849dc00809aSMiklos Szeredi 	spin_unlock(&cs->req->waitq.lock);
850ce534fb0SMiklos Szeredi 
851ce534fb0SMiklos Szeredi 	if (err) {
852ce534fb0SMiklos Szeredi 		unlock_page(newpage);
85309cbfeafSKirill A. Shutemov 		put_page(newpage);
854ce534fb0SMiklos Szeredi 		return err;
855ce534fb0SMiklos Szeredi 	}
856ce534fb0SMiklos Szeredi 
857ce534fb0SMiklos Szeredi 	unlock_page(oldpage);
85809cbfeafSKirill A. Shutemov 	put_page(oldpage);
859ce534fb0SMiklos Szeredi 	cs->len = 0;
860ce534fb0SMiklos Szeredi 
861ce534fb0SMiklos Szeredi 	return 0;
862ce534fb0SMiklos Szeredi 
863ce534fb0SMiklos Szeredi out_fallback_unlock:
864ce534fb0SMiklos Szeredi 	unlock_page(newpage);
865ce534fb0SMiklos Szeredi out_fallback:
866c55a01d3SMiklos Szeredi 	cs->pg = buf->page;
867c55a01d3SMiklos Szeredi 	cs->offset = buf->offset;
868ce534fb0SMiklos Szeredi 
869dc00809aSMiklos Szeredi 	err = lock_request(cs->req);
870ce534fb0SMiklos Szeredi 	if (err)
871ce534fb0SMiklos Szeredi 		return err;
872ce534fb0SMiklos Szeredi 
873ce534fb0SMiklos Szeredi 	return 1;
874ce534fb0SMiklos Szeredi }
875ce534fb0SMiklos Szeredi 
876c3021629SMiklos Szeredi static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
877c3021629SMiklos Szeredi 			 unsigned offset, unsigned count)
878c3021629SMiklos Szeredi {
879c3021629SMiklos Szeredi 	struct pipe_buffer *buf;
8800d8e84b0SMiklos Szeredi 	int err;
881c3021629SMiklos Szeredi 
882c3021629SMiklos Szeredi 	if (cs->nr_segs == cs->pipe->buffers)
883c3021629SMiklos Szeredi 		return -EIO;
884c3021629SMiklos Szeredi 
885dc00809aSMiklos Szeredi 	err = unlock_request(cs->req);
8860d8e84b0SMiklos Szeredi 	if (err)
8870d8e84b0SMiklos Szeredi 		return err;
8880d8e84b0SMiklos Szeredi 
889c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
890c3021629SMiklos Szeredi 
891c3021629SMiklos Szeredi 	buf = cs->pipebufs;
89209cbfeafSKirill A. Shutemov 	get_page(page);
893c3021629SMiklos Szeredi 	buf->page = page;
894c3021629SMiklos Szeredi 	buf->offset = offset;
895c3021629SMiklos Szeredi 	buf->len = count;
896c3021629SMiklos Szeredi 
897c3021629SMiklos Szeredi 	cs->pipebufs++;
898c3021629SMiklos Szeredi 	cs->nr_segs++;
899c3021629SMiklos Szeredi 	cs->len = 0;
900c3021629SMiklos Szeredi 
901c3021629SMiklos Szeredi 	return 0;
902c3021629SMiklos Szeredi }
903c3021629SMiklos Szeredi 
904334f485dSMiklos Szeredi /*
905334f485dSMiklos Szeredi  * Copy a page in the request to/from the userspace buffer.  Must be
906334f485dSMiklos Szeredi  * done atomically
907334f485dSMiklos Szeredi  */
908ce534fb0SMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
909334f485dSMiklos Szeredi 			  unsigned offset, unsigned count, int zeroing)
910334f485dSMiklos Szeredi {
911ce534fb0SMiklos Szeredi 	int err;
912ce534fb0SMiklos Szeredi 	struct page *page = *pagep;
913ce534fb0SMiklos Szeredi 
914b6777c40SMiklos Szeredi 	if (page && zeroing && count < PAGE_SIZE)
915b6777c40SMiklos Szeredi 		clear_highpage(page);
916b6777c40SMiklos Szeredi 
917334f485dSMiklos Szeredi 	while (count) {
918c3021629SMiklos Szeredi 		if (cs->write && cs->pipebufs && page) {
919c3021629SMiklos Szeredi 			return fuse_ref_page(cs, page, offset, count);
920c3021629SMiklos Szeredi 		} else if (!cs->len) {
921ce534fb0SMiklos Szeredi 			if (cs->move_pages && page &&
922ce534fb0SMiklos Szeredi 			    offset == 0 && count == PAGE_SIZE) {
923ce534fb0SMiklos Szeredi 				err = fuse_try_move_page(cs, pagep);
924ce534fb0SMiklos Szeredi 				if (err <= 0)
925ce534fb0SMiklos Szeredi 					return err;
926ce534fb0SMiklos Szeredi 			} else {
927ce534fb0SMiklos Szeredi 				err = fuse_copy_fill(cs);
9281729a16cSMiklos Szeredi 				if (err)
929334f485dSMiklos Szeredi 					return err;
9301729a16cSMiklos Szeredi 			}
931ce534fb0SMiklos Szeredi 		}
932334f485dSMiklos Szeredi 		if (page) {
9332408f6efSCong Wang 			void *mapaddr = kmap_atomic(page);
934334f485dSMiklos Szeredi 			void *buf = mapaddr + offset;
935334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, &buf, &count);
9362408f6efSCong Wang 			kunmap_atomic(mapaddr);
937334f485dSMiklos Szeredi 		} else
938334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, NULL, &count);
939334f485dSMiklos Szeredi 	}
940334f485dSMiklos Szeredi 	if (page && !cs->write)
941334f485dSMiklos Szeredi 		flush_dcache_page(page);
942334f485dSMiklos Szeredi 	return 0;
943334f485dSMiklos Szeredi }
944334f485dSMiklos Szeredi 
945334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */
946334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
947334f485dSMiklos Szeredi 			   int zeroing)
948334f485dSMiklos Szeredi {
949334f485dSMiklos Szeredi 	unsigned i;
950334f485dSMiklos Szeredi 	struct fuse_req *req = cs->req;
95105ea48ccSMiklos Szeredi 	struct fuse_args_pages *ap = container_of(req->args, typeof(*ap), args);
952334f485dSMiklos Szeredi 
95305ea48ccSMiklos Szeredi 
95405ea48ccSMiklos Szeredi 	for (i = 0; i < ap->num_pages && (nbytes || zeroing); i++) {
955ce534fb0SMiklos Szeredi 		int err;
95605ea48ccSMiklos Szeredi 		unsigned int offset = ap->descs[i].offset;
95705ea48ccSMiklos Szeredi 		unsigned int count = min(nbytes, ap->descs[i].length);
958ce534fb0SMiklos Szeredi 
95905ea48ccSMiklos Szeredi 		err = fuse_copy_page(cs, &ap->pages[i], offset, count, zeroing);
960334f485dSMiklos Szeredi 		if (err)
961334f485dSMiklos Szeredi 			return err;
962334f485dSMiklos Szeredi 
963334f485dSMiklos Szeredi 		nbytes -= count;
964334f485dSMiklos Szeredi 	}
965334f485dSMiklos Szeredi 	return 0;
966334f485dSMiklos Szeredi }
967334f485dSMiklos Szeredi 
968334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */
969334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
970334f485dSMiklos Szeredi {
971334f485dSMiklos Szeredi 	while (size) {
9721729a16cSMiklos Szeredi 		if (!cs->len) {
9731729a16cSMiklos Szeredi 			int err = fuse_copy_fill(cs);
9741729a16cSMiklos Szeredi 			if (err)
975334f485dSMiklos Szeredi 				return err;
9761729a16cSMiklos Szeredi 		}
977334f485dSMiklos Szeredi 		fuse_copy_do(cs, &val, &size);
978334f485dSMiklos Szeredi 	}
979334f485dSMiklos Szeredi 	return 0;
980334f485dSMiklos Szeredi }
981334f485dSMiklos Szeredi 
982334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */
983334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
984334f485dSMiklos Szeredi 			  unsigned argpages, struct fuse_arg *args,
985334f485dSMiklos Szeredi 			  int zeroing)
986334f485dSMiklos Szeredi {
987334f485dSMiklos Szeredi 	int err = 0;
988334f485dSMiklos Szeredi 	unsigned i;
989334f485dSMiklos Szeredi 
990334f485dSMiklos Szeredi 	for (i = 0; !err && i < numargs; i++)  {
991334f485dSMiklos Szeredi 		struct fuse_arg *arg = &args[i];
992334f485dSMiklos Szeredi 		if (i == numargs - 1 && argpages)
993334f485dSMiklos Szeredi 			err = fuse_copy_pages(cs, arg->size, zeroing);
994334f485dSMiklos Szeredi 		else
995334f485dSMiklos Szeredi 			err = fuse_copy_one(cs, arg->value, arg->size);
996334f485dSMiklos Szeredi 	}
997334f485dSMiklos Szeredi 	return err;
998334f485dSMiklos Szeredi }
999334f485dSMiklos Szeredi 
1000f88996a9SMiklos Szeredi static int forget_pending(struct fuse_iqueue *fiq)
100107e77dcaSMiklos Szeredi {
1002f88996a9SMiklos Szeredi 	return fiq->forget_list_head.next != NULL;
100307e77dcaSMiklos Szeredi }
100407e77dcaSMiklos Szeredi 
1005f88996a9SMiklos Szeredi static int request_pending(struct fuse_iqueue *fiq)
1006a4d27e75SMiklos Szeredi {
1007f88996a9SMiklos Szeredi 	return !list_empty(&fiq->pending) || !list_empty(&fiq->interrupts) ||
1008f88996a9SMiklos Szeredi 		forget_pending(fiq);
1009a4d27e75SMiklos Szeredi }
1010a4d27e75SMiklos Szeredi 
1011334f485dSMiklos Szeredi /*
1012a4d27e75SMiklos Szeredi  * Transfer an interrupt request to userspace
1013a4d27e75SMiklos Szeredi  *
1014a4d27e75SMiklos Szeredi  * Unlike other requests this is assembled on demand, without a need
1015a4d27e75SMiklos Szeredi  * to allocate a separate fuse_req structure.
1016a4d27e75SMiklos Szeredi  *
101776e43c8cSEric Biggers  * Called with fiq->lock held, releases it
1018a4d27e75SMiklos Szeredi  */
1019fd22d62eSMiklos Szeredi static int fuse_read_interrupt(struct fuse_iqueue *fiq,
1020fd22d62eSMiklos Szeredi 			       struct fuse_copy_state *cs,
1021c3021629SMiklos Szeredi 			       size_t nbytes, struct fuse_req *req)
102276e43c8cSEric Biggers __releases(fiq->lock)
1023a4d27e75SMiklos Szeredi {
1024a4d27e75SMiklos Szeredi 	struct fuse_in_header ih;
1025a4d27e75SMiklos Szeredi 	struct fuse_interrupt_in arg;
1026a4d27e75SMiklos Szeredi 	unsigned reqsize = sizeof(ih) + sizeof(arg);
1027a4d27e75SMiklos Szeredi 	int err;
1028a4d27e75SMiklos Szeredi 
1029a4d27e75SMiklos Szeredi 	list_del_init(&req->intr_entry);
1030a4d27e75SMiklos Szeredi 	memset(&ih, 0, sizeof(ih));
1031a4d27e75SMiklos Szeredi 	memset(&arg, 0, sizeof(arg));
1032a4d27e75SMiklos Szeredi 	ih.len = reqsize;
1033a4d27e75SMiklos Szeredi 	ih.opcode = FUSE_INTERRUPT;
10343a5358d1SKirill Tkhai 	ih.unique = (req->in.h.unique | FUSE_INT_REQ_BIT);
1035a4d27e75SMiklos Szeredi 	arg.unique = req->in.h.unique;
1036a4d27e75SMiklos Szeredi 
103776e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
1038c3021629SMiklos Szeredi 	if (nbytes < reqsize)
1039a4d27e75SMiklos Szeredi 		return -EINVAL;
1040a4d27e75SMiklos Szeredi 
1041c3021629SMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
1042a4d27e75SMiklos Szeredi 	if (!err)
1043c3021629SMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
1044c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
1045a4d27e75SMiklos Szeredi 
1046a4d27e75SMiklos Szeredi 	return err ? err : reqsize;
1047a4d27e75SMiklos Szeredi }
1048a4d27e75SMiklos Szeredi 
10494388c5aaSVivek Goyal struct fuse_forget_link *fuse_dequeue_forget(struct fuse_iqueue *fiq,
10504388c5aaSVivek Goyal 					     unsigned int max,
10514388c5aaSVivek Goyal 					     unsigned int *countp)
105207e77dcaSMiklos Szeredi {
1053f88996a9SMiklos Szeredi 	struct fuse_forget_link *head = fiq->forget_list_head.next;
105402c048b9SMiklos Szeredi 	struct fuse_forget_link **newhead = &head;
105502c048b9SMiklos Szeredi 	unsigned count;
105607e77dcaSMiklos Szeredi 
105702c048b9SMiklos Szeredi 	for (count = 0; *newhead != NULL && count < max; count++)
105802c048b9SMiklos Szeredi 		newhead = &(*newhead)->next;
105902c048b9SMiklos Szeredi 
1060f88996a9SMiklos Szeredi 	fiq->forget_list_head.next = *newhead;
106102c048b9SMiklos Szeredi 	*newhead = NULL;
1062f88996a9SMiklos Szeredi 	if (fiq->forget_list_head.next == NULL)
1063f88996a9SMiklos Szeredi 		fiq->forget_list_tail = &fiq->forget_list_head;
106407e77dcaSMiklos Szeredi 
106502c048b9SMiklos Szeredi 	if (countp != NULL)
106602c048b9SMiklos Szeredi 		*countp = count;
106702c048b9SMiklos Szeredi 
106802c048b9SMiklos Szeredi 	return head;
106907e77dcaSMiklos Szeredi }
10704388c5aaSVivek Goyal EXPORT_SYMBOL(fuse_dequeue_forget);
107107e77dcaSMiklos Szeredi 
1072fd22d62eSMiklos Szeredi static int fuse_read_single_forget(struct fuse_iqueue *fiq,
107307e77dcaSMiklos Szeredi 				   struct fuse_copy_state *cs,
107407e77dcaSMiklos Szeredi 				   size_t nbytes)
107576e43c8cSEric Biggers __releases(fiq->lock)
107607e77dcaSMiklos Szeredi {
107707e77dcaSMiklos Szeredi 	int err;
10784388c5aaSVivek Goyal 	struct fuse_forget_link *forget = fuse_dequeue_forget(fiq, 1, NULL);
107907e77dcaSMiklos Szeredi 	struct fuse_forget_in arg = {
108002c048b9SMiklos Szeredi 		.nlookup = forget->forget_one.nlookup,
108107e77dcaSMiklos Szeredi 	};
108207e77dcaSMiklos Szeredi 	struct fuse_in_header ih = {
108307e77dcaSMiklos Szeredi 		.opcode = FUSE_FORGET,
108402c048b9SMiklos Szeredi 		.nodeid = forget->forget_one.nodeid,
1085f88996a9SMiklos Szeredi 		.unique = fuse_get_unique(fiq),
108607e77dcaSMiklos Szeredi 		.len = sizeof(ih) + sizeof(arg),
108707e77dcaSMiklos Szeredi 	};
108807e77dcaSMiklos Szeredi 
108976e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
109007e77dcaSMiklos Szeredi 	kfree(forget);
109107e77dcaSMiklos Szeredi 	if (nbytes < ih.len)
109207e77dcaSMiklos Szeredi 		return -EINVAL;
109307e77dcaSMiklos Szeredi 
109407e77dcaSMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
109507e77dcaSMiklos Szeredi 	if (!err)
109607e77dcaSMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
109707e77dcaSMiklos Szeredi 	fuse_copy_finish(cs);
109807e77dcaSMiklos Szeredi 
109907e77dcaSMiklos Szeredi 	if (err)
110007e77dcaSMiklos Szeredi 		return err;
110107e77dcaSMiklos Szeredi 
110207e77dcaSMiklos Szeredi 	return ih.len;
110307e77dcaSMiklos Szeredi }
110407e77dcaSMiklos Szeredi 
1105fd22d62eSMiklos Szeredi static int fuse_read_batch_forget(struct fuse_iqueue *fiq,
110602c048b9SMiklos Szeredi 				   struct fuse_copy_state *cs, size_t nbytes)
110776e43c8cSEric Biggers __releases(fiq->lock)
110802c048b9SMiklos Szeredi {
110902c048b9SMiklos Szeredi 	int err;
111002c048b9SMiklos Szeredi 	unsigned max_forgets;
111102c048b9SMiklos Szeredi 	unsigned count;
111202c048b9SMiklos Szeredi 	struct fuse_forget_link *head;
111302c048b9SMiklos Szeredi 	struct fuse_batch_forget_in arg = { .count = 0 };
111402c048b9SMiklos Szeredi 	struct fuse_in_header ih = {
111502c048b9SMiklos Szeredi 		.opcode = FUSE_BATCH_FORGET,
1116f88996a9SMiklos Szeredi 		.unique = fuse_get_unique(fiq),
111702c048b9SMiklos Szeredi 		.len = sizeof(ih) + sizeof(arg),
111802c048b9SMiklos Szeredi 	};
111902c048b9SMiklos Szeredi 
112002c048b9SMiklos Szeredi 	if (nbytes < ih.len) {
112176e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
112202c048b9SMiklos Szeredi 		return -EINVAL;
112302c048b9SMiklos Szeredi 	}
112402c048b9SMiklos Szeredi 
112502c048b9SMiklos Szeredi 	max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one);
11264388c5aaSVivek Goyal 	head = fuse_dequeue_forget(fiq, max_forgets, &count);
112776e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
112802c048b9SMiklos Szeredi 
112902c048b9SMiklos Szeredi 	arg.count = count;
113002c048b9SMiklos Szeredi 	ih.len += count * sizeof(struct fuse_forget_one);
113102c048b9SMiklos Szeredi 	err = fuse_copy_one(cs, &ih, sizeof(ih));
113202c048b9SMiklos Szeredi 	if (!err)
113302c048b9SMiklos Szeredi 		err = fuse_copy_one(cs, &arg, sizeof(arg));
113402c048b9SMiklos Szeredi 
113502c048b9SMiklos Szeredi 	while (head) {
113602c048b9SMiklos Szeredi 		struct fuse_forget_link *forget = head;
113702c048b9SMiklos Szeredi 
113802c048b9SMiklos Szeredi 		if (!err) {
113902c048b9SMiklos Szeredi 			err = fuse_copy_one(cs, &forget->forget_one,
114002c048b9SMiklos Szeredi 					    sizeof(forget->forget_one));
114102c048b9SMiklos Szeredi 		}
114202c048b9SMiklos Szeredi 		head = forget->next;
114302c048b9SMiklos Szeredi 		kfree(forget);
114402c048b9SMiklos Szeredi 	}
114502c048b9SMiklos Szeredi 
114602c048b9SMiklos Szeredi 	fuse_copy_finish(cs);
114702c048b9SMiklos Szeredi 
114802c048b9SMiklos Szeredi 	if (err)
114902c048b9SMiklos Szeredi 		return err;
115002c048b9SMiklos Szeredi 
115102c048b9SMiklos Szeredi 	return ih.len;
115202c048b9SMiklos Szeredi }
115302c048b9SMiklos Szeredi 
1154fd22d62eSMiklos Szeredi static int fuse_read_forget(struct fuse_conn *fc, struct fuse_iqueue *fiq,
1155fd22d62eSMiklos Szeredi 			    struct fuse_copy_state *cs,
115602c048b9SMiklos Szeredi 			    size_t nbytes)
115776e43c8cSEric Biggers __releases(fiq->lock)
115802c048b9SMiklos Szeredi {
1159f88996a9SMiklos Szeredi 	if (fc->minor < 16 || fiq->forget_list_head.next->next == NULL)
1160fd22d62eSMiklos Szeredi 		return fuse_read_single_forget(fiq, cs, nbytes);
116102c048b9SMiklos Szeredi 	else
1162fd22d62eSMiklos Szeredi 		return fuse_read_batch_forget(fiq, cs, nbytes);
116302c048b9SMiklos Szeredi }
116402c048b9SMiklos Szeredi 
1165a4d27e75SMiklos Szeredi /*
1166334f485dSMiklos Szeredi  * Read a single request into the userspace filesystem's buffer.  This
1167334f485dSMiklos Szeredi  * function waits until a request is available, then removes it from
1168334f485dSMiklos Szeredi  * the pending list and copies request data to userspace buffer.  If
1169f9a2842eSMiklos Szeredi  * no reply is needed (FORGET) or request has been aborted or there
1170f9a2842eSMiklos Szeredi  * was an error during the copying then it's finished by calling
117104ec5af0SStefan Hajnoczi  * fuse_request_end().  Otherwise add it to the processing list, and set
1172334f485dSMiklos Szeredi  * the 'sent' flag.
1173334f485dSMiklos Szeredi  */
1174c3696046SMiklos Szeredi static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
1175c3021629SMiklos Szeredi 				struct fuse_copy_state *cs, size_t nbytes)
1176334f485dSMiklos Szeredi {
117782cbdcd3SMiklos Szeredi 	ssize_t err;
1178c3696046SMiklos Szeredi 	struct fuse_conn *fc = fud->fc;
1179f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
1180c3696046SMiklos Szeredi 	struct fuse_pqueue *fpq = &fud->pq;
1181334f485dSMiklos Szeredi 	struct fuse_req *req;
1182d4993774SMiklos Szeredi 	struct fuse_args *args;
1183334f485dSMiklos Szeredi 	unsigned reqsize;
1184be2ff42cSKirill Tkhai 	unsigned int hash;
1185334f485dSMiklos Szeredi 
11861fb027d7SKirill Smelkov 	/*
11871fb027d7SKirill Smelkov 	 * Require sane minimum read buffer - that has capacity for fixed part
11881fb027d7SKirill Smelkov 	 * of any request header + negotiated max_write room for data.
11891fb027d7SKirill Smelkov 	 *
11901fb027d7SKirill Smelkov 	 * Historically libfuse reserves 4K for fixed header room, but e.g.
11911fb027d7SKirill Smelkov 	 * GlusterFS reserves only 80 bytes
11921fb027d7SKirill Smelkov 	 *
11931fb027d7SKirill Smelkov 	 *	= `sizeof(fuse_in_header) + sizeof(fuse_write_in)`
11941fb027d7SKirill Smelkov 	 *
11951fb027d7SKirill Smelkov 	 * which is the absolute minimum any sane filesystem should be using
11961fb027d7SKirill Smelkov 	 * for header room.
11971fb027d7SKirill Smelkov 	 */
11981fb027d7SKirill Smelkov 	if (nbytes < max_t(size_t, FUSE_MIN_READ_BUFFER,
11991fb027d7SKirill Smelkov 			   sizeof(struct fuse_in_header) +
12001fb027d7SKirill Smelkov 			   sizeof(struct fuse_write_in) +
12011fb027d7SKirill Smelkov 			   fc->max_write))
12021fb027d7SKirill Smelkov 		return -EINVAL;
12031fb027d7SKirill Smelkov 
12041d3d752bSMiklos Szeredi  restart:
120576e43c8cSEric Biggers 	for (;;) {
120676e43c8cSEric Biggers 		spin_lock(&fiq->lock);
120776e43c8cSEric Biggers 		if (!fiq->connected || request_pending(fiq))
120876e43c8cSEric Biggers 			break;
120976e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
1210e5ac1d1eSJeff Dike 
121176e43c8cSEric Biggers 		if (file->f_flags & O_NONBLOCK)
121276e43c8cSEric Biggers 			return -EAGAIN;
121376e43c8cSEric Biggers 		err = wait_event_interruptible_exclusive(fiq->waitq,
12145250921bSMiklos Szeredi 				!fiq->connected || request_pending(fiq));
12155250921bSMiklos Szeredi 		if (err)
121676e43c8cSEric Biggers 			return err;
121776e43c8cSEric Biggers 	}
12185250921bSMiklos Szeredi 
12193b7008b2SSzymon Lukasz 	if (!fiq->connected) {
1220eb98e3bdSMiklos Szeredi 		err = fc->aborted ? -ECONNABORTED : -ENODEV;
1221334f485dSMiklos Szeredi 		goto err_unlock;
12223b7008b2SSzymon Lukasz 	}
1223334f485dSMiklos Szeredi 
1224f88996a9SMiklos Szeredi 	if (!list_empty(&fiq->interrupts)) {
1225f88996a9SMiklos Szeredi 		req = list_entry(fiq->interrupts.next, struct fuse_req,
1226a4d27e75SMiklos Szeredi 				 intr_entry);
1227fd22d62eSMiklos Szeredi 		return fuse_read_interrupt(fiq, cs, nbytes, req);
1228a4d27e75SMiklos Szeredi 	}
1229a4d27e75SMiklos Szeredi 
1230f88996a9SMiklos Szeredi 	if (forget_pending(fiq)) {
1231f88996a9SMiklos Szeredi 		if (list_empty(&fiq->pending) || fiq->forget_batch-- > 0)
1232fd22d62eSMiklos Szeredi 			return fuse_read_forget(fc, fiq, cs, nbytes);
123307e77dcaSMiklos Szeredi 
1234f88996a9SMiklos Szeredi 		if (fiq->forget_batch <= -8)
1235f88996a9SMiklos Szeredi 			fiq->forget_batch = 16;
123607e77dcaSMiklos Szeredi 	}
123707e77dcaSMiklos Szeredi 
1238f88996a9SMiklos Szeredi 	req = list_entry(fiq->pending.next, struct fuse_req, list);
123933e14b4dSMiklos Szeredi 	clear_bit(FR_PENDING, &req->flags);
1240ef759258SMiklos Szeredi 	list_del_init(&req->list);
124176e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
12424ce60812SMiklos Szeredi 
1243d4993774SMiklos Szeredi 	args = req->args;
1244d4993774SMiklos Szeredi 	reqsize = req->in.h.len;
12455d6d3a30SMiklos Szeredi 
12461d3d752bSMiklos Szeredi 	/* If request is too large, reply with an error and restart the read */
1247c3021629SMiklos Szeredi 	if (nbytes < reqsize) {
12481d3d752bSMiklos Szeredi 		req->out.h.error = -EIO;
12491d3d752bSMiklos Szeredi 		/* SETXATTR is special, since it may contain too large data */
1250d4993774SMiklos Szeredi 		if (args->opcode == FUSE_SETXATTR)
12511d3d752bSMiklos Szeredi 			req->out.h.error = -E2BIG;
125204ec5af0SStefan Hajnoczi 		fuse_request_end(fc, req);
12531d3d752bSMiklos Szeredi 		goto restart;
12541d3d752bSMiklos Szeredi 	}
125545a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
125682cbdcd3SMiklos Szeredi 	list_add(&req->list, &fpq->io);
125745a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1258c3021629SMiklos Szeredi 	cs->req = req;
1259d4993774SMiklos Szeredi 	err = fuse_copy_one(cs, &req->in.h, sizeof(req->in.h));
1260334f485dSMiklos Szeredi 	if (!err)
1261d4993774SMiklos Szeredi 		err = fuse_copy_args(cs, args->in_numargs, args->in_pages,
1262d4993774SMiklos Szeredi 				     (struct fuse_arg *) args->in_args, 0);
1263c3021629SMiklos Szeredi 	fuse_copy_finish(cs);
126445a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1265825d6d33SMiklos Szeredi 	clear_bit(FR_LOCKED, &req->flags);
1266e96edd94SMiklos Szeredi 	if (!fpq->connected) {
1267eb98e3bdSMiklos Szeredi 		err = fc->aborted ? -ECONNABORTED : -ENODEV;
126882cbdcd3SMiklos Szeredi 		goto out_end;
1269c9c9d7dfSMiklos Szeredi 	}
1270334f485dSMiklos Szeredi 	if (err) {
1271334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
127282cbdcd3SMiklos Szeredi 		goto out_end;
1273334f485dSMiklos Szeredi 	}
1274825d6d33SMiklos Szeredi 	if (!test_bit(FR_ISREPLY, &req->flags)) {
127582cbdcd3SMiklos Szeredi 		err = reqsize;
127682cbdcd3SMiklos Szeredi 		goto out_end;
127782cbdcd3SMiklos Szeredi 	}
1278be2ff42cSKirill Tkhai 	hash = fuse_req_hash(req->in.h.unique);
1279be2ff42cSKirill Tkhai 	list_move_tail(&req->list, &fpq->processing[hash]);
1280bc78abbdSKirill Tkhai 	__fuse_get_request(req);
12818f7bb368SMiklos Szeredi 	set_bit(FR_SENT, &req->flags);
12824c316f2fSMiklos Szeredi 	spin_unlock(&fpq->lock);
12838f7bb368SMiklos Szeredi 	/* matches barrier in request_wait_answer() */
12848f7bb368SMiklos Szeredi 	smp_mb__after_atomic();
1285825d6d33SMiklos Szeredi 	if (test_bit(FR_INTERRUPTED, &req->flags))
1286f88996a9SMiklos Szeredi 		queue_interrupt(fiq, req);
1287bc78abbdSKirill Tkhai 	fuse_put_request(fc, req);
128882cbdcd3SMiklos Szeredi 
1289334f485dSMiklos Szeredi 	return reqsize;
1290334f485dSMiklos Szeredi 
129182cbdcd3SMiklos Szeredi out_end:
129277cd9d48SMiklos Szeredi 	if (!test_bit(FR_PRIVATE, &req->flags))
129382cbdcd3SMiklos Szeredi 		list_del_init(&req->list);
129445a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
129504ec5af0SStefan Hajnoczi 	fuse_request_end(fc, req);
129682cbdcd3SMiklos Szeredi 	return err;
129782cbdcd3SMiklos Szeredi 
1298334f485dSMiklos Szeredi  err_unlock:
129976e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
1300334f485dSMiklos Szeredi 	return err;
1301334f485dSMiklos Szeredi }
1302334f485dSMiklos Szeredi 
130394e4fe2cSTom Van Braeckel static int fuse_dev_open(struct inode *inode, struct file *file)
130494e4fe2cSTom Van Braeckel {
130594e4fe2cSTom Van Braeckel 	/*
130694e4fe2cSTom Van Braeckel 	 * The fuse device's file's private_data is used to hold
130794e4fe2cSTom Van Braeckel 	 * the fuse_conn(ection) when it is mounted, and is used to
130894e4fe2cSTom Van Braeckel 	 * keep track of whether the file has been mounted already.
130994e4fe2cSTom Van Braeckel 	 */
131094e4fe2cSTom Van Braeckel 	file->private_data = NULL;
131194e4fe2cSTom Van Braeckel 	return 0;
131294e4fe2cSTom Van Braeckel }
131394e4fe2cSTom Van Braeckel 
1314fbdbaccaSAl Viro static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to)
1315c3021629SMiklos Szeredi {
1316c3021629SMiklos Szeredi 	struct fuse_copy_state cs;
1317c3021629SMiklos Szeredi 	struct file *file = iocb->ki_filp;
1318cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
1319cc080e9eSMiklos Szeredi 
1320cc080e9eSMiklos Szeredi 	if (!fud)
1321c3021629SMiklos Szeredi 		return -EPERM;
1322c3021629SMiklos Szeredi 
1323fbdbaccaSAl Viro 	if (!iter_is_iovec(to))
1324fbdbaccaSAl Viro 		return -EINVAL;
1325c3021629SMiklos Szeredi 
1326dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 1, to);
1327fbdbaccaSAl Viro 
1328c3696046SMiklos Szeredi 	return fuse_dev_do_read(fud, file, &cs, iov_iter_count(to));
1329c3021629SMiklos Szeredi }
1330c3021629SMiklos Szeredi 
1331c3021629SMiklos Szeredi static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
1332c3021629SMiklos Szeredi 				    struct pipe_inode_info *pipe,
1333c3021629SMiklos Szeredi 				    size_t len, unsigned int flags)
1334c3021629SMiklos Szeredi {
1335d82718e3SAl Viro 	int total, ret;
1336c3021629SMiklos Szeredi 	int page_nr = 0;
1337c3021629SMiklos Szeredi 	struct pipe_buffer *bufs;
1338c3021629SMiklos Szeredi 	struct fuse_copy_state cs;
1339cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(in);
1340cc080e9eSMiklos Szeredi 
1341cc080e9eSMiklos Szeredi 	if (!fud)
1342c3021629SMiklos Szeredi 		return -EPERM;
1343c3021629SMiklos Szeredi 
1344d6d931adSAndrey Ryabinin 	bufs = kvmalloc_array(pipe->buffers, sizeof(struct pipe_buffer),
13456da2ec56SKees Cook 			      GFP_KERNEL);
1346c3021629SMiklos Szeredi 	if (!bufs)
1347c3021629SMiklos Szeredi 		return -ENOMEM;
1348c3021629SMiklos Szeredi 
1349dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 1, NULL);
1350c3021629SMiklos Szeredi 	cs.pipebufs = bufs;
1351c3021629SMiklos Szeredi 	cs.pipe = pipe;
1352c3696046SMiklos Szeredi 	ret = fuse_dev_do_read(fud, in, &cs, len);
1353c3021629SMiklos Szeredi 	if (ret < 0)
1354c3021629SMiklos Szeredi 		goto out;
1355c3021629SMiklos Szeredi 
1356c3021629SMiklos Szeredi 	if (pipe->nrbufs + cs.nr_segs > pipe->buffers) {
1357c3021629SMiklos Szeredi 		ret = -EIO;
1358d82718e3SAl Viro 		goto out;
1359c3021629SMiklos Szeredi 	}
1360c3021629SMiklos Szeredi 
1361d82718e3SAl Viro 	for (ret = total = 0; page_nr < cs.nr_segs; total += ret) {
136228a625cbSMiklos Szeredi 		/*
136328a625cbSMiklos Szeredi 		 * Need to be careful about this.  Having buf->ops in module
136428a625cbSMiklos Szeredi 		 * code can Oops if the buffer persists after module unload.
136528a625cbSMiklos Szeredi 		 */
1366d82718e3SAl Viro 		bufs[page_nr].ops = &nosteal_pipe_buf_ops;
136784588a93SMiklos Szeredi 		bufs[page_nr].flags = 0;
1368d82718e3SAl Viro 		ret = add_to_pipe(pipe, &bufs[page_nr++]);
1369d82718e3SAl Viro 		if (unlikely(ret < 0))
1370d82718e3SAl Viro 			break;
1371c3021629SMiklos Szeredi 	}
1372d82718e3SAl Viro 	if (total)
1373d82718e3SAl Viro 		ret = total;
1374c3021629SMiklos Szeredi out:
1375c3021629SMiklos Szeredi 	for (; page_nr < cs.nr_segs; page_nr++)
137609cbfeafSKirill A. Shutemov 		put_page(bufs[page_nr].page);
1377c3021629SMiklos Szeredi 
1378d6d931adSAndrey Ryabinin 	kvfree(bufs);
1379c3021629SMiklos Szeredi 	return ret;
1380c3021629SMiklos Szeredi }
1381c3021629SMiklos Szeredi 
138295668a69STejun Heo static int fuse_notify_poll(struct fuse_conn *fc, unsigned int size,
138395668a69STejun Heo 			    struct fuse_copy_state *cs)
138495668a69STejun Heo {
138595668a69STejun Heo 	struct fuse_notify_poll_wakeup_out outarg;
1386f6d47a17SMiklos Szeredi 	int err = -EINVAL;
138795668a69STejun Heo 
138895668a69STejun Heo 	if (size != sizeof(outarg))
1389f6d47a17SMiklos Szeredi 		goto err;
139095668a69STejun Heo 
139195668a69STejun Heo 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
139295668a69STejun Heo 	if (err)
1393f6d47a17SMiklos Szeredi 		goto err;
139495668a69STejun Heo 
1395f6d47a17SMiklos Szeredi 	fuse_copy_finish(cs);
139695668a69STejun Heo 	return fuse_notify_poll_wakeup(fc, &outarg);
1397f6d47a17SMiklos Szeredi 
1398f6d47a17SMiklos Szeredi err:
1399f6d47a17SMiklos Szeredi 	fuse_copy_finish(cs);
1400f6d47a17SMiklos Szeredi 	return err;
140195668a69STejun Heo }
140295668a69STejun Heo 
14033b463ae0SJohn Muir static int fuse_notify_inval_inode(struct fuse_conn *fc, unsigned int size,
14043b463ae0SJohn Muir 				   struct fuse_copy_state *cs)
14053b463ae0SJohn Muir {
14063b463ae0SJohn Muir 	struct fuse_notify_inval_inode_out outarg;
14073b463ae0SJohn Muir 	int err = -EINVAL;
14083b463ae0SJohn Muir 
14093b463ae0SJohn Muir 	if (size != sizeof(outarg))
14103b463ae0SJohn Muir 		goto err;
14113b463ae0SJohn Muir 
14123b463ae0SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
14133b463ae0SJohn Muir 	if (err)
14143b463ae0SJohn Muir 		goto err;
14153b463ae0SJohn Muir 	fuse_copy_finish(cs);
14163b463ae0SJohn Muir 
14173b463ae0SJohn Muir 	down_read(&fc->killsb);
14183b463ae0SJohn Muir 	err = -ENOENT;
1419b21dda43SMiklos Szeredi 	if (fc->sb) {
14203b463ae0SJohn Muir 		err = fuse_reverse_inval_inode(fc->sb, outarg.ino,
14213b463ae0SJohn Muir 					       outarg.off, outarg.len);
1422b21dda43SMiklos Szeredi 	}
14233b463ae0SJohn Muir 	up_read(&fc->killsb);
14243b463ae0SJohn Muir 	return err;
14253b463ae0SJohn Muir 
14263b463ae0SJohn Muir err:
14273b463ae0SJohn Muir 	fuse_copy_finish(cs);
14283b463ae0SJohn Muir 	return err;
14293b463ae0SJohn Muir }
14303b463ae0SJohn Muir 
14313b463ae0SJohn Muir static int fuse_notify_inval_entry(struct fuse_conn *fc, unsigned int size,
14323b463ae0SJohn Muir 				   struct fuse_copy_state *cs)
14333b463ae0SJohn Muir {
14343b463ae0SJohn Muir 	struct fuse_notify_inval_entry_out outarg;
1435b2d82ee3SFang Wenqi 	int err = -ENOMEM;
1436b2d82ee3SFang Wenqi 	char *buf;
14373b463ae0SJohn Muir 	struct qstr name;
14383b463ae0SJohn Muir 
1439b2d82ee3SFang Wenqi 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
1440b2d82ee3SFang Wenqi 	if (!buf)
1441b2d82ee3SFang Wenqi 		goto err;
1442b2d82ee3SFang Wenqi 
1443b2d82ee3SFang Wenqi 	err = -EINVAL;
14443b463ae0SJohn Muir 	if (size < sizeof(outarg))
14453b463ae0SJohn Muir 		goto err;
14463b463ae0SJohn Muir 
14473b463ae0SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
14483b463ae0SJohn Muir 	if (err)
14493b463ae0SJohn Muir 		goto err;
14503b463ae0SJohn Muir 
14513b463ae0SJohn Muir 	err = -ENAMETOOLONG;
14523b463ae0SJohn Muir 	if (outarg.namelen > FUSE_NAME_MAX)
14533b463ae0SJohn Muir 		goto err;
14543b463ae0SJohn Muir 
1455c2183d1eSMiklos Szeredi 	err = -EINVAL;
1456c2183d1eSMiklos Szeredi 	if (size != sizeof(outarg) + outarg.namelen + 1)
1457c2183d1eSMiklos Szeredi 		goto err;
1458c2183d1eSMiklos Szeredi 
14593b463ae0SJohn Muir 	name.name = buf;
14603b463ae0SJohn Muir 	name.len = outarg.namelen;
14613b463ae0SJohn Muir 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
14623b463ae0SJohn Muir 	if (err)
14633b463ae0SJohn Muir 		goto err;
14643b463ae0SJohn Muir 	fuse_copy_finish(cs);
14653b463ae0SJohn Muir 	buf[outarg.namelen] = 0;
14663b463ae0SJohn Muir 
14673b463ae0SJohn Muir 	down_read(&fc->killsb);
14683b463ae0SJohn Muir 	err = -ENOENT;
1469b21dda43SMiklos Szeredi 	if (fc->sb)
1470451d0f59SJohn Muir 		err = fuse_reverse_inval_entry(fc->sb, outarg.parent, 0, &name);
1471451d0f59SJohn Muir 	up_read(&fc->killsb);
1472451d0f59SJohn Muir 	kfree(buf);
1473451d0f59SJohn Muir 	return err;
1474451d0f59SJohn Muir 
1475451d0f59SJohn Muir err:
1476451d0f59SJohn Muir 	kfree(buf);
1477451d0f59SJohn Muir 	fuse_copy_finish(cs);
1478451d0f59SJohn Muir 	return err;
1479451d0f59SJohn Muir }
1480451d0f59SJohn Muir 
1481451d0f59SJohn Muir static int fuse_notify_delete(struct fuse_conn *fc, unsigned int size,
1482451d0f59SJohn Muir 			      struct fuse_copy_state *cs)
1483451d0f59SJohn Muir {
1484451d0f59SJohn Muir 	struct fuse_notify_delete_out outarg;
1485451d0f59SJohn Muir 	int err = -ENOMEM;
1486451d0f59SJohn Muir 	char *buf;
1487451d0f59SJohn Muir 	struct qstr name;
1488451d0f59SJohn Muir 
1489451d0f59SJohn Muir 	buf = kzalloc(FUSE_NAME_MAX + 1, GFP_KERNEL);
1490451d0f59SJohn Muir 	if (!buf)
1491451d0f59SJohn Muir 		goto err;
1492451d0f59SJohn Muir 
1493451d0f59SJohn Muir 	err = -EINVAL;
1494451d0f59SJohn Muir 	if (size < sizeof(outarg))
1495451d0f59SJohn Muir 		goto err;
1496451d0f59SJohn Muir 
1497451d0f59SJohn Muir 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
1498451d0f59SJohn Muir 	if (err)
1499451d0f59SJohn Muir 		goto err;
1500451d0f59SJohn Muir 
1501451d0f59SJohn Muir 	err = -ENAMETOOLONG;
1502451d0f59SJohn Muir 	if (outarg.namelen > FUSE_NAME_MAX)
1503451d0f59SJohn Muir 		goto err;
1504451d0f59SJohn Muir 
1505451d0f59SJohn Muir 	err = -EINVAL;
1506451d0f59SJohn Muir 	if (size != sizeof(outarg) + outarg.namelen + 1)
1507451d0f59SJohn Muir 		goto err;
1508451d0f59SJohn Muir 
1509451d0f59SJohn Muir 	name.name = buf;
1510451d0f59SJohn Muir 	name.len = outarg.namelen;
1511451d0f59SJohn Muir 	err = fuse_copy_one(cs, buf, outarg.namelen + 1);
1512451d0f59SJohn Muir 	if (err)
1513451d0f59SJohn Muir 		goto err;
1514451d0f59SJohn Muir 	fuse_copy_finish(cs);
1515451d0f59SJohn Muir 	buf[outarg.namelen] = 0;
1516451d0f59SJohn Muir 
1517451d0f59SJohn Muir 	down_read(&fc->killsb);
1518451d0f59SJohn Muir 	err = -ENOENT;
1519451d0f59SJohn Muir 	if (fc->sb)
1520451d0f59SJohn Muir 		err = fuse_reverse_inval_entry(fc->sb, outarg.parent,
1521451d0f59SJohn Muir 					       outarg.child, &name);
15223b463ae0SJohn Muir 	up_read(&fc->killsb);
1523b2d82ee3SFang Wenqi 	kfree(buf);
15243b463ae0SJohn Muir 	return err;
15253b463ae0SJohn Muir 
15263b463ae0SJohn Muir err:
1527b2d82ee3SFang Wenqi 	kfree(buf);
15283b463ae0SJohn Muir 	fuse_copy_finish(cs);
15293b463ae0SJohn Muir 	return err;
15303b463ae0SJohn Muir }
15313b463ae0SJohn Muir 
1532a1d75f25SMiklos Szeredi static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
1533a1d75f25SMiklos Szeredi 			     struct fuse_copy_state *cs)
1534a1d75f25SMiklos Szeredi {
1535a1d75f25SMiklos Szeredi 	struct fuse_notify_store_out outarg;
1536a1d75f25SMiklos Szeredi 	struct inode *inode;
1537a1d75f25SMiklos Szeredi 	struct address_space *mapping;
1538a1d75f25SMiklos Szeredi 	u64 nodeid;
1539a1d75f25SMiklos Szeredi 	int err;
1540a1d75f25SMiklos Szeredi 	pgoff_t index;
1541a1d75f25SMiklos Szeredi 	unsigned int offset;
1542a1d75f25SMiklos Szeredi 	unsigned int num;
1543a1d75f25SMiklos Szeredi 	loff_t file_size;
1544a1d75f25SMiklos Szeredi 	loff_t end;
1545a1d75f25SMiklos Szeredi 
1546a1d75f25SMiklos Szeredi 	err = -EINVAL;
1547a1d75f25SMiklos Szeredi 	if (size < sizeof(outarg))
1548a1d75f25SMiklos Szeredi 		goto out_finish;
1549a1d75f25SMiklos Szeredi 
1550a1d75f25SMiklos Szeredi 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
1551a1d75f25SMiklos Szeredi 	if (err)
1552a1d75f25SMiklos Szeredi 		goto out_finish;
1553a1d75f25SMiklos Szeredi 
1554a1d75f25SMiklos Szeredi 	err = -EINVAL;
1555a1d75f25SMiklos Szeredi 	if (size - sizeof(outarg) != outarg.size)
1556a1d75f25SMiklos Szeredi 		goto out_finish;
1557a1d75f25SMiklos Szeredi 
1558a1d75f25SMiklos Szeredi 	nodeid = outarg.nodeid;
1559a1d75f25SMiklos Szeredi 
1560a1d75f25SMiklos Szeredi 	down_read(&fc->killsb);
1561a1d75f25SMiklos Szeredi 
1562a1d75f25SMiklos Szeredi 	err = -ENOENT;
1563a1d75f25SMiklos Szeredi 	if (!fc->sb)
1564a1d75f25SMiklos Szeredi 		goto out_up_killsb;
1565a1d75f25SMiklos Szeredi 
1566a1d75f25SMiklos Szeredi 	inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
1567a1d75f25SMiklos Szeredi 	if (!inode)
1568a1d75f25SMiklos Szeredi 		goto out_up_killsb;
1569a1d75f25SMiklos Szeredi 
1570a1d75f25SMiklos Szeredi 	mapping = inode->i_mapping;
157109cbfeafSKirill A. Shutemov 	index = outarg.offset >> PAGE_SHIFT;
157209cbfeafSKirill A. Shutemov 	offset = outarg.offset & ~PAGE_MASK;
1573a1d75f25SMiklos Szeredi 	file_size = i_size_read(inode);
1574a1d75f25SMiklos Szeredi 	end = outarg.offset + outarg.size;
1575a1d75f25SMiklos Szeredi 	if (end > file_size) {
1576a1d75f25SMiklos Szeredi 		file_size = end;
1577a1d75f25SMiklos Szeredi 		fuse_write_update_size(inode, file_size);
1578a1d75f25SMiklos Szeredi 	}
1579a1d75f25SMiklos Szeredi 
1580a1d75f25SMiklos Szeredi 	num = outarg.size;
1581a1d75f25SMiklos Szeredi 	while (num) {
1582a1d75f25SMiklos Szeredi 		struct page *page;
1583a1d75f25SMiklos Szeredi 		unsigned int this_num;
1584a1d75f25SMiklos Szeredi 
1585a1d75f25SMiklos Szeredi 		err = -ENOMEM;
1586a1d75f25SMiklos Szeredi 		page = find_or_create_page(mapping, index,
1587a1d75f25SMiklos Szeredi 					   mapping_gfp_mask(mapping));
1588a1d75f25SMiklos Szeredi 		if (!page)
1589a1d75f25SMiklos Szeredi 			goto out_iput;
1590a1d75f25SMiklos Szeredi 
159109cbfeafSKirill A. Shutemov 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
1592a1d75f25SMiklos Szeredi 		err = fuse_copy_page(cs, &page, offset, this_num, 0);
1593063ec1e5SMiklos Szeredi 		if (!err && offset == 0 &&
159409cbfeafSKirill A. Shutemov 		    (this_num == PAGE_SIZE || file_size == end))
1595a1d75f25SMiklos Szeredi 			SetPageUptodate(page);
1596a1d75f25SMiklos Szeredi 		unlock_page(page);
159709cbfeafSKirill A. Shutemov 		put_page(page);
1598a1d75f25SMiklos Szeredi 
1599a1d75f25SMiklos Szeredi 		if (err)
1600a1d75f25SMiklos Szeredi 			goto out_iput;
1601a1d75f25SMiklos Szeredi 
1602a1d75f25SMiklos Szeredi 		num -= this_num;
1603a1d75f25SMiklos Szeredi 		offset = 0;
1604a1d75f25SMiklos Szeredi 		index++;
1605a1d75f25SMiklos Szeredi 	}
1606a1d75f25SMiklos Szeredi 
1607a1d75f25SMiklos Szeredi 	err = 0;
1608a1d75f25SMiklos Szeredi 
1609a1d75f25SMiklos Szeredi out_iput:
1610a1d75f25SMiklos Szeredi 	iput(inode);
1611a1d75f25SMiklos Szeredi out_up_killsb:
1612a1d75f25SMiklos Szeredi 	up_read(&fc->killsb);
1613a1d75f25SMiklos Szeredi out_finish:
1614a1d75f25SMiklos Szeredi 	fuse_copy_finish(cs);
1615a1d75f25SMiklos Szeredi 	return err;
1616a1d75f25SMiklos Szeredi }
1617a1d75f25SMiklos Szeredi 
161875b399ddSMiklos Szeredi struct fuse_retrieve_args {
161975b399ddSMiklos Szeredi 	struct fuse_args_pages ap;
162075b399ddSMiklos Szeredi 	struct fuse_notify_retrieve_in inarg;
162175b399ddSMiklos Szeredi };
162275b399ddSMiklos Szeredi 
162375b399ddSMiklos Szeredi static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_args *args,
162475b399ddSMiklos Szeredi 			      int error)
16252d45ba38SMiklos Szeredi {
162675b399ddSMiklos Szeredi 	struct fuse_retrieve_args *ra =
162775b399ddSMiklos Szeredi 		container_of(args, typeof(*ra), ap.args);
162875b399ddSMiklos Szeredi 
162975b399ddSMiklos Szeredi 	release_pages(ra->ap.pages, ra->ap.num_pages);
163075b399ddSMiklos Szeredi 	kfree(ra);
16312d45ba38SMiklos Szeredi }
16322d45ba38SMiklos Szeredi 
16332d45ba38SMiklos Szeredi static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
16342d45ba38SMiklos Szeredi 			 struct fuse_notify_retrieve_out *outarg)
16352d45ba38SMiklos Szeredi {
16362d45ba38SMiklos Szeredi 	int err;
16372d45ba38SMiklos Szeredi 	struct address_space *mapping = inode->i_mapping;
16382d45ba38SMiklos Szeredi 	pgoff_t index;
16392d45ba38SMiklos Szeredi 	loff_t file_size;
16402d45ba38SMiklos Szeredi 	unsigned int num;
16412d45ba38SMiklos Szeredi 	unsigned int offset;
16420157443cSGeert Uytterhoeven 	size_t total_len = 0;
16435da784ccSConstantine Shulyupin 	unsigned int num_pages;
164475b399ddSMiklos Szeredi 	struct fuse_retrieve_args *ra;
164575b399ddSMiklos Szeredi 	size_t args_size = sizeof(*ra);
164675b399ddSMiklos Szeredi 	struct fuse_args_pages *ap;
164775b399ddSMiklos Szeredi 	struct fuse_args *args;
16482d45ba38SMiklos Szeredi 
164909cbfeafSKirill A. Shutemov 	offset = outarg->offset & ~PAGE_MASK;
16504d53dc99SMaxim Patlasov 	file_size = i_size_read(inode);
16514d53dc99SMaxim Patlasov 
16527640682eSKirill Smelkov 	num = min(outarg->size, fc->max_write);
16534d53dc99SMaxim Patlasov 	if (outarg->offset > file_size)
16544d53dc99SMaxim Patlasov 		num = 0;
16554d53dc99SMaxim Patlasov 	else if (outarg->offset + num > file_size)
16564d53dc99SMaxim Patlasov 		num = file_size - outarg->offset;
16574d53dc99SMaxim Patlasov 
16584d53dc99SMaxim Patlasov 	num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
16595da784ccSConstantine Shulyupin 	num_pages = min(num_pages, fc->max_pages);
16604d53dc99SMaxim Patlasov 
166175b399ddSMiklos Szeredi 	args_size += num_pages * (sizeof(ap->pages[0]) + sizeof(ap->descs[0]));
16622d45ba38SMiklos Szeredi 
166375b399ddSMiklos Szeredi 	ra = kzalloc(args_size, GFP_KERNEL);
166475b399ddSMiklos Szeredi 	if (!ra)
166575b399ddSMiklos Szeredi 		return -ENOMEM;
166675b399ddSMiklos Szeredi 
166775b399ddSMiklos Szeredi 	ap = &ra->ap;
166875b399ddSMiklos Szeredi 	ap->pages = (void *) (ra + 1);
166975b399ddSMiklos Szeredi 	ap->descs = (void *) (ap->pages + num_pages);
167075b399ddSMiklos Szeredi 
167175b399ddSMiklos Szeredi 	args = &ap->args;
167275b399ddSMiklos Szeredi 	args->nodeid = outarg->nodeid;
167375b399ddSMiklos Szeredi 	args->opcode = FUSE_NOTIFY_REPLY;
167475b399ddSMiklos Szeredi 	args->in_numargs = 2;
167575b399ddSMiklos Szeredi 	args->in_pages = true;
167675b399ddSMiklos Szeredi 	args->end = fuse_retrieve_end;
16772d45ba38SMiklos Szeredi 
167809cbfeafSKirill A. Shutemov 	index = outarg->offset >> PAGE_SHIFT;
16792d45ba38SMiklos Szeredi 
168075b399ddSMiklos Szeredi 	while (num && ap->num_pages < num_pages) {
16812d45ba38SMiklos Szeredi 		struct page *page;
16822d45ba38SMiklos Szeredi 		unsigned int this_num;
16832d45ba38SMiklos Szeredi 
16842d45ba38SMiklos Szeredi 		page = find_get_page(mapping, index);
16852d45ba38SMiklos Szeredi 		if (!page)
16862d45ba38SMiklos Szeredi 			break;
16872d45ba38SMiklos Szeredi 
168809cbfeafSKirill A. Shutemov 		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
168975b399ddSMiklos Szeredi 		ap->pages[ap->num_pages] = page;
169075b399ddSMiklos Szeredi 		ap->descs[ap->num_pages].offset = offset;
169175b399ddSMiklos Szeredi 		ap->descs[ap->num_pages].length = this_num;
169275b399ddSMiklos Szeredi 		ap->num_pages++;
16932d45ba38SMiklos Szeredi 
1694c9e67d48SMiklos Szeredi 		offset = 0;
16952d45ba38SMiklos Szeredi 		num -= this_num;
16962d45ba38SMiklos Szeredi 		total_len += this_num;
169748706d0aSMiklos Szeredi 		index++;
16982d45ba38SMiklos Szeredi 	}
169975b399ddSMiklos Szeredi 	ra->inarg.offset = outarg->offset;
170075b399ddSMiklos Szeredi 	ra->inarg.size = total_len;
170175b399ddSMiklos Szeredi 	args->in_args[0].size = sizeof(ra->inarg);
170275b399ddSMiklos Szeredi 	args->in_args[0].value = &ra->inarg;
170375b399ddSMiklos Szeredi 	args->in_args[1].size = total_len;
17042d45ba38SMiklos Szeredi 
170575b399ddSMiklos Szeredi 	err = fuse_simple_notify_reply(fc, args, outarg->notify_unique);
170675b399ddSMiklos Szeredi 	if (err)
170775b399ddSMiklos Szeredi 		fuse_retrieve_end(fc, args, err);
17082d45ba38SMiklos Szeredi 
17092d45ba38SMiklos Szeredi 	return err;
17102d45ba38SMiklos Szeredi }
17112d45ba38SMiklos Szeredi 
17122d45ba38SMiklos Szeredi static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size,
17132d45ba38SMiklos Szeredi 				struct fuse_copy_state *cs)
17142d45ba38SMiklos Szeredi {
17152d45ba38SMiklos Szeredi 	struct fuse_notify_retrieve_out outarg;
17162d45ba38SMiklos Szeredi 	struct inode *inode;
17172d45ba38SMiklos Szeredi 	int err;
17182d45ba38SMiklos Szeredi 
17192d45ba38SMiklos Szeredi 	err = -EINVAL;
17202d45ba38SMiklos Szeredi 	if (size != sizeof(outarg))
17212d45ba38SMiklos Szeredi 		goto copy_finish;
17222d45ba38SMiklos Szeredi 
17232d45ba38SMiklos Szeredi 	err = fuse_copy_one(cs, &outarg, sizeof(outarg));
17242d45ba38SMiklos Szeredi 	if (err)
17252d45ba38SMiklos Szeredi 		goto copy_finish;
17262d45ba38SMiklos Szeredi 
17272d45ba38SMiklos Szeredi 	fuse_copy_finish(cs);
17282d45ba38SMiklos Szeredi 
17292d45ba38SMiklos Szeredi 	down_read(&fc->killsb);
17302d45ba38SMiklos Szeredi 	err = -ENOENT;
17312d45ba38SMiklos Szeredi 	if (fc->sb) {
17322d45ba38SMiklos Szeredi 		u64 nodeid = outarg.nodeid;
17332d45ba38SMiklos Szeredi 
17342d45ba38SMiklos Szeredi 		inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
17352d45ba38SMiklos Szeredi 		if (inode) {
17362d45ba38SMiklos Szeredi 			err = fuse_retrieve(fc, inode, &outarg);
17372d45ba38SMiklos Szeredi 			iput(inode);
17382d45ba38SMiklos Szeredi 		}
17392d45ba38SMiklos Szeredi 	}
17402d45ba38SMiklos Szeredi 	up_read(&fc->killsb);
17412d45ba38SMiklos Szeredi 
17422d45ba38SMiklos Szeredi 	return err;
17432d45ba38SMiklos Szeredi 
17442d45ba38SMiklos Szeredi copy_finish:
17452d45ba38SMiklos Szeredi 	fuse_copy_finish(cs);
17462d45ba38SMiklos Szeredi 	return err;
17472d45ba38SMiklos Szeredi }
17482d45ba38SMiklos Szeredi 
17498599396bSTejun Heo static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
17508599396bSTejun Heo 		       unsigned int size, struct fuse_copy_state *cs)
17518599396bSTejun Heo {
17520d278362SMiklos Szeredi 	/* Don't try to move pages (yet) */
17530d278362SMiklos Szeredi 	cs->move_pages = 0;
17540d278362SMiklos Szeredi 
17558599396bSTejun Heo 	switch (code) {
175695668a69STejun Heo 	case FUSE_NOTIFY_POLL:
175795668a69STejun Heo 		return fuse_notify_poll(fc, size, cs);
175895668a69STejun Heo 
17593b463ae0SJohn Muir 	case FUSE_NOTIFY_INVAL_INODE:
17603b463ae0SJohn Muir 		return fuse_notify_inval_inode(fc, size, cs);
17613b463ae0SJohn Muir 
17623b463ae0SJohn Muir 	case FUSE_NOTIFY_INVAL_ENTRY:
17633b463ae0SJohn Muir 		return fuse_notify_inval_entry(fc, size, cs);
17643b463ae0SJohn Muir 
1765a1d75f25SMiklos Szeredi 	case FUSE_NOTIFY_STORE:
1766a1d75f25SMiklos Szeredi 		return fuse_notify_store(fc, size, cs);
1767a1d75f25SMiklos Szeredi 
17682d45ba38SMiklos Szeredi 	case FUSE_NOTIFY_RETRIEVE:
17692d45ba38SMiklos Szeredi 		return fuse_notify_retrieve(fc, size, cs);
17702d45ba38SMiklos Szeredi 
1771451d0f59SJohn Muir 	case FUSE_NOTIFY_DELETE:
1772451d0f59SJohn Muir 		return fuse_notify_delete(fc, size, cs);
1773451d0f59SJohn Muir 
17748599396bSTejun Heo 	default:
1775f6d47a17SMiklos Szeredi 		fuse_copy_finish(cs);
17768599396bSTejun Heo 		return -EINVAL;
17778599396bSTejun Heo 	}
17788599396bSTejun Heo }
17798599396bSTejun Heo 
1780334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */
17813a2b5b9cSMiklos Szeredi static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique)
1782334f485dSMiklos Szeredi {
1783be2ff42cSKirill Tkhai 	unsigned int hash = fuse_req_hash(unique);
1784334f485dSMiklos Szeredi 	struct fuse_req *req;
178505726acaSDong Fang 
1786be2ff42cSKirill Tkhai 	list_for_each_entry(req, &fpq->processing[hash], list) {
17873a5358d1SKirill Tkhai 		if (req->in.h.unique == unique)
1788334f485dSMiklos Szeredi 			return req;
1789334f485dSMiklos Szeredi 	}
1790334f485dSMiklos Szeredi 	return NULL;
1791334f485dSMiklos Szeredi }
1792334f485dSMiklos Szeredi 
1793d4993774SMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_args *args,
1794334f485dSMiklos Szeredi 			 unsigned nbytes)
1795334f485dSMiklos Szeredi {
1796334f485dSMiklos Szeredi 	unsigned reqsize = sizeof(struct fuse_out_header);
1797334f485dSMiklos Szeredi 
179814d46d7aSStefan Hajnoczi 	reqsize += fuse_len_args(args->out_numargs, args->out_args);
1799334f485dSMiklos Szeredi 
1800d4993774SMiklos Szeredi 	if (reqsize < nbytes || (reqsize > nbytes && !args->out_argvar))
1801334f485dSMiklos Szeredi 		return -EINVAL;
1802334f485dSMiklos Szeredi 	else if (reqsize > nbytes) {
1803d4993774SMiklos Szeredi 		struct fuse_arg *lastarg = &args->out_args[args->out_numargs-1];
1804334f485dSMiklos Szeredi 		unsigned diffsize = reqsize - nbytes;
1805d4993774SMiklos Szeredi 
1806334f485dSMiklos Szeredi 		if (diffsize > lastarg->size)
1807334f485dSMiklos Szeredi 			return -EINVAL;
1808334f485dSMiklos Szeredi 		lastarg->size -= diffsize;
1809334f485dSMiklos Szeredi 	}
1810d4993774SMiklos Szeredi 	return fuse_copy_args(cs, args->out_numargs, args->out_pages,
1811d4993774SMiklos Szeredi 			      args->out_args, args->page_zeroing);
1812334f485dSMiklos Szeredi }
1813334f485dSMiklos Szeredi 
1814334f485dSMiklos Szeredi /*
1815334f485dSMiklos Szeredi  * Write a single reply to a request.  First the header is copied from
1816334f485dSMiklos Szeredi  * the write buffer.  The request is then searched on the processing
1817334f485dSMiklos Szeredi  * list by the unique ID found in the header.  If found, then remove
1818334f485dSMiklos Szeredi  * it from the list and copy the rest of the buffer to the request.
181904ec5af0SStefan Hajnoczi  * The request is finished by calling fuse_request_end().
1820334f485dSMiklos Szeredi  */
1821c3696046SMiklos Szeredi static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
1822dd3bb14fSMiklos Szeredi 				 struct fuse_copy_state *cs, size_t nbytes)
1823334f485dSMiklos Szeredi {
1824334f485dSMiklos Szeredi 	int err;
1825c3696046SMiklos Szeredi 	struct fuse_conn *fc = fud->fc;
1826c3696046SMiklos Szeredi 	struct fuse_pqueue *fpq = &fud->pq;
1827334f485dSMiklos Szeredi 	struct fuse_req *req;
1828334f485dSMiklos Szeredi 	struct fuse_out_header oh;
1829334f485dSMiklos Szeredi 
18307407a10dSKirill Tkhai 	err = -EINVAL;
1831334f485dSMiklos Szeredi 	if (nbytes < sizeof(struct fuse_out_header))
18327407a10dSKirill Tkhai 		goto out;
1833334f485dSMiklos Szeredi 
1834dd3bb14fSMiklos Szeredi 	err = fuse_copy_one(cs, &oh, sizeof(oh));
1835334f485dSMiklos Szeredi 	if (err)
18367407a10dSKirill Tkhai 		goto copy_finish;
18378599396bSTejun Heo 
1838334f485dSMiklos Szeredi 	err = -EINVAL;
18398599396bSTejun Heo 	if (oh.len != nbytes)
18407407a10dSKirill Tkhai 		goto copy_finish;
18418599396bSTejun Heo 
18428599396bSTejun Heo 	/*
18438599396bSTejun Heo 	 * Zero oh.unique indicates unsolicited notification message
18448599396bSTejun Heo 	 * and error contains notification code.
18458599396bSTejun Heo 	 */
18468599396bSTejun Heo 	if (!oh.unique) {
1847dd3bb14fSMiklos Szeredi 		err = fuse_notify(fc, oh.error, nbytes - sizeof(oh), cs);
18487407a10dSKirill Tkhai 		goto out;
18498599396bSTejun Heo 	}
18508599396bSTejun Heo 
18518599396bSTejun Heo 	err = -EINVAL;
18528599396bSTejun Heo 	if (oh.error <= -1000 || oh.error > 0)
18537407a10dSKirill Tkhai 		goto copy_finish;
1854334f485dSMiklos Szeredi 
185545a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
18567407a10dSKirill Tkhai 	req = NULL;
18577407a10dSKirill Tkhai 	if (fpq->connected)
18583a5358d1SKirill Tkhai 		req = request_find(fpq, oh.unique & ~FUSE_INT_REQ_BIT);
18597407a10dSKirill Tkhai 
18607407a10dSKirill Tkhai 	err = -ENOENT;
18617407a10dSKirill Tkhai 	if (!req) {
18627407a10dSKirill Tkhai 		spin_unlock(&fpq->lock);
18637407a10dSKirill Tkhai 		goto copy_finish;
18647407a10dSKirill Tkhai 	}
1865334f485dSMiklos Szeredi 
18663a5358d1SKirill Tkhai 	/* Is it an interrupt reply ID? */
18673a5358d1SKirill Tkhai 	if (oh.unique & FUSE_INT_REQ_BIT) {
1868d2d2d4fbSKirill Tkhai 		__fuse_get_request(req);
186945a91cb1SMiklos Szeredi 		spin_unlock(&fpq->lock);
187045a91cb1SMiklos Szeredi 
18717407a10dSKirill Tkhai 		err = 0;
18727407a10dSKirill Tkhai 		if (nbytes != sizeof(struct fuse_out_header))
1873a4d27e75SMiklos Szeredi 			err = -EINVAL;
18747407a10dSKirill Tkhai 		else if (oh.error == -ENOSYS)
1875a4d27e75SMiklos Szeredi 			fc->no_interrupt = 1;
1876a4d27e75SMiklos Szeredi 		else if (oh.error == -EAGAIN)
1877b782911bSKirill Tkhai 			err = queue_interrupt(&fc->iq, req);
18787407a10dSKirill Tkhai 
1879d2d2d4fbSKirill Tkhai 		fuse_put_request(fc, req);
1880a4d27e75SMiklos Szeredi 
18817407a10dSKirill Tkhai 		goto copy_finish;
1882a4d27e75SMiklos Szeredi 	}
1883a4d27e75SMiklos Szeredi 
188433e14b4dSMiklos Szeredi 	clear_bit(FR_SENT, &req->flags);
18853a2b5b9cSMiklos Szeredi 	list_move(&req->list, &fpq->io);
1886334f485dSMiklos Szeredi 	req->out.h = oh;
1887825d6d33SMiklos Szeredi 	set_bit(FR_LOCKED, &req->flags);
188845a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
1889dd3bb14fSMiklos Szeredi 	cs->req = req;
1890d4993774SMiklos Szeredi 	if (!req->args->page_replace)
1891ce534fb0SMiklos Szeredi 		cs->move_pages = 0;
1892334f485dSMiklos Szeredi 
1893d4993774SMiklos Szeredi 	if (oh.error)
1894d4993774SMiklos Szeredi 		err = nbytes != sizeof(oh) ? -EINVAL : 0;
1895d4993774SMiklos Szeredi 	else
1896d4993774SMiklos Szeredi 		err = copy_out_args(cs, req->args, nbytes);
1897dd3bb14fSMiklos Szeredi 	fuse_copy_finish(cs);
1898334f485dSMiklos Szeredi 
189945a91cb1SMiklos Szeredi 	spin_lock(&fpq->lock);
1900825d6d33SMiklos Szeredi 	clear_bit(FR_LOCKED, &req->flags);
1901e96edd94SMiklos Szeredi 	if (!fpq->connected)
1902334f485dSMiklos Szeredi 		err = -ENOENT;
19030d8e84b0SMiklos Szeredi 	else if (err)
1904334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
190577cd9d48SMiklos Szeredi 	if (!test_bit(FR_PRIVATE, &req->flags))
1906f377cb79SMiklos Szeredi 		list_del_init(&req->list);
190745a91cb1SMiklos Szeredi 	spin_unlock(&fpq->lock);
190846c34a34SMiklos Szeredi 
190904ec5af0SStefan Hajnoczi 	fuse_request_end(fc, req);
19107407a10dSKirill Tkhai out:
1911334f485dSMiklos Szeredi 	return err ? err : nbytes;
1912334f485dSMiklos Szeredi 
19137407a10dSKirill Tkhai copy_finish:
1914dd3bb14fSMiklos Szeredi 	fuse_copy_finish(cs);
19157407a10dSKirill Tkhai 	goto out;
1916334f485dSMiklos Szeredi }
1917334f485dSMiklos Szeredi 
1918fbdbaccaSAl Viro static ssize_t fuse_dev_write(struct kiocb *iocb, struct iov_iter *from)
1919dd3bb14fSMiklos Szeredi {
1920dd3bb14fSMiklos Szeredi 	struct fuse_copy_state cs;
1921cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(iocb->ki_filp);
1922cc080e9eSMiklos Szeredi 
1923cc080e9eSMiklos Szeredi 	if (!fud)
1924dd3bb14fSMiklos Szeredi 		return -EPERM;
1925dd3bb14fSMiklos Szeredi 
1926fbdbaccaSAl Viro 	if (!iter_is_iovec(from))
1927fbdbaccaSAl Viro 		return -EINVAL;
1928dd3bb14fSMiklos Szeredi 
1929dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 0, from);
1930fbdbaccaSAl Viro 
1931c3696046SMiklos Szeredi 	return fuse_dev_do_write(fud, &cs, iov_iter_count(from));
1932dd3bb14fSMiklos Szeredi }
1933dd3bb14fSMiklos Szeredi 
1934dd3bb14fSMiklos Szeredi static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
1935dd3bb14fSMiklos Szeredi 				     struct file *out, loff_t *ppos,
1936dd3bb14fSMiklos Szeredi 				     size_t len, unsigned int flags)
1937dd3bb14fSMiklos Szeredi {
1938dd3bb14fSMiklos Szeredi 	unsigned nbuf;
1939dd3bb14fSMiklos Szeredi 	unsigned idx;
1940dd3bb14fSMiklos Szeredi 	struct pipe_buffer *bufs;
1941dd3bb14fSMiklos Szeredi 	struct fuse_copy_state cs;
1942cc080e9eSMiklos Szeredi 	struct fuse_dev *fud;
1943dd3bb14fSMiklos Szeredi 	size_t rem;
1944dd3bb14fSMiklos Szeredi 	ssize_t ret;
1945dd3bb14fSMiklos Szeredi 
1946cc080e9eSMiklos Szeredi 	fud = fuse_get_dev(out);
1947cc080e9eSMiklos Szeredi 	if (!fud)
1948dd3bb14fSMiklos Szeredi 		return -EPERM;
1949dd3bb14fSMiklos Szeredi 
1950a2477b0eSAndrey Ryabinin 	pipe_lock(pipe);
1951a2477b0eSAndrey Ryabinin 
195296354535SAndrey Ryabinin 	bufs = kvmalloc_array(pipe->nrbufs, sizeof(struct pipe_buffer),
19536da2ec56SKees Cook 			      GFP_KERNEL);
1954a2477b0eSAndrey Ryabinin 	if (!bufs) {
1955a2477b0eSAndrey Ryabinin 		pipe_unlock(pipe);
1956dd3bb14fSMiklos Szeredi 		return -ENOMEM;
1957a2477b0eSAndrey Ryabinin 	}
1958dd3bb14fSMiklos Szeredi 
1959dd3bb14fSMiklos Szeredi 	nbuf = 0;
1960dd3bb14fSMiklos Szeredi 	rem = 0;
1961dd3bb14fSMiklos Szeredi 	for (idx = 0; idx < pipe->nrbufs && rem < len; idx++)
1962dd3bb14fSMiklos Szeredi 		rem += pipe->bufs[(pipe->curbuf + idx) & (pipe->buffers - 1)].len;
1963dd3bb14fSMiklos Szeredi 
1964dd3bb14fSMiklos Szeredi 	ret = -EINVAL;
196515fab63eSMatthew Wilcox 	if (rem < len)
196615fab63eSMatthew Wilcox 		goto out_free;
1967dd3bb14fSMiklos Szeredi 
1968dd3bb14fSMiklos Szeredi 	rem = len;
1969dd3bb14fSMiklos Szeredi 	while (rem) {
1970dd3bb14fSMiklos Szeredi 		struct pipe_buffer *ibuf;
1971dd3bb14fSMiklos Szeredi 		struct pipe_buffer *obuf;
1972dd3bb14fSMiklos Szeredi 
1973dd3bb14fSMiklos Szeredi 		BUG_ON(nbuf >= pipe->buffers);
1974dd3bb14fSMiklos Szeredi 		BUG_ON(!pipe->nrbufs);
1975dd3bb14fSMiklos Szeredi 		ibuf = &pipe->bufs[pipe->curbuf];
1976dd3bb14fSMiklos Szeredi 		obuf = &bufs[nbuf];
1977dd3bb14fSMiklos Szeredi 
1978dd3bb14fSMiklos Szeredi 		if (rem >= ibuf->len) {
1979dd3bb14fSMiklos Szeredi 			*obuf = *ibuf;
1980dd3bb14fSMiklos Szeredi 			ibuf->ops = NULL;
1981dd3bb14fSMiklos Szeredi 			pipe->curbuf = (pipe->curbuf + 1) & (pipe->buffers - 1);
1982dd3bb14fSMiklos Szeredi 			pipe->nrbufs--;
1983dd3bb14fSMiklos Szeredi 		} else {
198415fab63eSMatthew Wilcox 			if (!pipe_buf_get(pipe, ibuf))
198515fab63eSMatthew Wilcox 				goto out_free;
198615fab63eSMatthew Wilcox 
1987dd3bb14fSMiklos Szeredi 			*obuf = *ibuf;
1988dd3bb14fSMiklos Szeredi 			obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
1989dd3bb14fSMiklos Szeredi 			obuf->len = rem;
1990dd3bb14fSMiklos Szeredi 			ibuf->offset += obuf->len;
1991dd3bb14fSMiklos Szeredi 			ibuf->len -= obuf->len;
1992dd3bb14fSMiklos Szeredi 		}
1993dd3bb14fSMiklos Szeredi 		nbuf++;
1994dd3bb14fSMiklos Szeredi 		rem -= obuf->len;
1995dd3bb14fSMiklos Szeredi 	}
1996dd3bb14fSMiklos Szeredi 	pipe_unlock(pipe);
1997dd3bb14fSMiklos Szeredi 
1998dc00809aSMiklos Szeredi 	fuse_copy_init(&cs, 0, NULL);
1999dd3bb14fSMiklos Szeredi 	cs.pipebufs = bufs;
20006c09e94aSAl Viro 	cs.nr_segs = nbuf;
2001dd3bb14fSMiklos Szeredi 	cs.pipe = pipe;
2002dd3bb14fSMiklos Szeredi 
2003ce534fb0SMiklos Szeredi 	if (flags & SPLICE_F_MOVE)
2004ce534fb0SMiklos Szeredi 		cs.move_pages = 1;
2005ce534fb0SMiklos Szeredi 
2006c3696046SMiklos Szeredi 	ret = fuse_dev_do_write(fud, &cs, len);
2007dd3bb14fSMiklos Szeredi 
20089509941eSJann Horn 	pipe_lock(pipe);
200915fab63eSMatthew Wilcox out_free:
2010a779638cSMiklos Szeredi 	for (idx = 0; idx < nbuf; idx++)
2011a779638cSMiklos Szeredi 		pipe_buf_release(pipe, &bufs[idx]);
20129509941eSJann Horn 	pipe_unlock(pipe);
2013a779638cSMiklos Szeredi 
2014d6d931adSAndrey Ryabinin 	kvfree(bufs);
2015dd3bb14fSMiklos Szeredi 	return ret;
2016dd3bb14fSMiklos Szeredi }
2017dd3bb14fSMiklos Szeredi 
2018076ccb76SAl Viro static __poll_t fuse_dev_poll(struct file *file, poll_table *wait)
2019334f485dSMiklos Szeredi {
2020a9a08845SLinus Torvalds 	__poll_t mask = EPOLLOUT | EPOLLWRNORM;
2021f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq;
2022cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2023cc080e9eSMiklos Szeredi 
2024cc080e9eSMiklos Szeredi 	if (!fud)
2025a9a08845SLinus Torvalds 		return EPOLLERR;
2026334f485dSMiklos Szeredi 
2027cc080e9eSMiklos Szeredi 	fiq = &fud->fc->iq;
2028f88996a9SMiklos Szeredi 	poll_wait(file, &fiq->waitq, wait);
2029334f485dSMiklos Szeredi 
203076e43c8cSEric Biggers 	spin_lock(&fiq->lock);
2031e16714d8SMiklos Szeredi 	if (!fiq->connected)
2032a9a08845SLinus Torvalds 		mask = EPOLLERR;
2033f88996a9SMiklos Szeredi 	else if (request_pending(fiq))
2034a9a08845SLinus Torvalds 		mask |= EPOLLIN | EPOLLRDNORM;
203576e43c8cSEric Biggers 	spin_unlock(&fiq->lock);
2036334f485dSMiklos Szeredi 
2037334f485dSMiklos Szeredi 	return mask;
2038334f485dSMiklos Szeredi }
2039334f485dSMiklos Szeredi 
204034061750SKirill Tkhai /* Abort all requests on the given list (pending or processing) */
2041334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head)
2042334f485dSMiklos Szeredi {
2043334f485dSMiklos Szeredi 	while (!list_empty(head)) {
2044334f485dSMiklos Szeredi 		struct fuse_req *req;
2045334f485dSMiklos Szeredi 		req = list_entry(head->next, struct fuse_req, list);
2046334f485dSMiklos Szeredi 		req->out.h.error = -ECONNABORTED;
204733e14b4dSMiklos Szeredi 		clear_bit(FR_SENT, &req->flags);
2048f377cb79SMiklos Szeredi 		list_del_init(&req->list);
204904ec5af0SStefan Hajnoczi 		fuse_request_end(fc, req);
2050334f485dSMiklos Szeredi 	}
2051334f485dSMiklos Szeredi }
2052334f485dSMiklos Szeredi 
2053357ccf2bSBryan Green static void end_polls(struct fuse_conn *fc)
2054357ccf2bSBryan Green {
2055357ccf2bSBryan Green 	struct rb_node *p;
2056357ccf2bSBryan Green 
2057357ccf2bSBryan Green 	p = rb_first(&fc->polled_files);
2058357ccf2bSBryan Green 
2059357ccf2bSBryan Green 	while (p) {
2060357ccf2bSBryan Green 		struct fuse_file *ff;
2061357ccf2bSBryan Green 		ff = rb_entry(p, struct fuse_file, polled_node);
2062357ccf2bSBryan Green 		wake_up_interruptible_all(&ff->poll_wait);
2063357ccf2bSBryan Green 
2064357ccf2bSBryan Green 		p = rb_next(p);
2065357ccf2bSBryan Green 	}
2066357ccf2bSBryan Green }
2067357ccf2bSBryan Green 
206869a53bf2SMiklos Szeredi /*
206969a53bf2SMiklos Szeredi  * Abort all requests.
207069a53bf2SMiklos Szeredi  *
2071b716d425SMiklos Szeredi  * Emergency exit in case of a malicious or accidental deadlock, or just a hung
2072b716d425SMiklos Szeredi  * filesystem.
207369a53bf2SMiklos Szeredi  *
2074b716d425SMiklos Szeredi  * The same effect is usually achievable through killing the filesystem daemon
2075b716d425SMiklos Szeredi  * and all users of the filesystem.  The exception is the combination of an
2076b716d425SMiklos Szeredi  * asynchronous request and the tricky deadlock (see
2077b716d425SMiklos Szeredi  * Documentation/filesystems/fuse.txt).
207869a53bf2SMiklos Szeredi  *
2079b716d425SMiklos Szeredi  * Aborting requests under I/O goes as follows: 1: Separate out unlocked
2080b716d425SMiklos Szeredi  * requests, they should be finished off immediately.  Locked requests will be
2081b716d425SMiklos Szeredi  * finished after unlock; see unlock_request(). 2: Finish off the unlocked
2082b716d425SMiklos Szeredi  * requests.  It is possible that some request will finish before we can.  This
2083b716d425SMiklos Szeredi  * is OK, the request will in that case be removed from the list before we touch
2084b716d425SMiklos Szeredi  * it.
208569a53bf2SMiklos Szeredi  */
2086eb98e3bdSMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc)
208769a53bf2SMiklos Szeredi {
2088f88996a9SMiklos Szeredi 	struct fuse_iqueue *fiq = &fc->iq;
2089f88996a9SMiklos Szeredi 
2090d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
209169a53bf2SMiklos Szeredi 	if (fc->connected) {
2092c3696046SMiklos Szeredi 		struct fuse_dev *fud;
2093b716d425SMiklos Szeredi 		struct fuse_req *req, *next;
209475f3ee4cSMiklos Szeredi 		LIST_HEAD(to_end);
2095be2ff42cSKirill Tkhai 		unsigned int i;
2096b716d425SMiklos Szeredi 
209763825b4eSKirill Tkhai 		/* Background queuing checks fc->connected under bg_lock */
209863825b4eSKirill Tkhai 		spin_lock(&fc->bg_lock);
209969a53bf2SMiklos Szeredi 		fc->connected = 0;
210063825b4eSKirill Tkhai 		spin_unlock(&fc->bg_lock);
210163825b4eSKirill Tkhai 
21029759bd51SMiklos Szeredi 		fuse_set_initialized(fc);
2103c3696046SMiklos Szeredi 		list_for_each_entry(fud, &fc->devices, entry) {
2104c3696046SMiklos Szeredi 			struct fuse_pqueue *fpq = &fud->pq;
2105c3696046SMiklos Szeredi 
210645a91cb1SMiklos Szeredi 			spin_lock(&fpq->lock);
2107e96edd94SMiklos Szeredi 			fpq->connected = 0;
21083a2b5b9cSMiklos Szeredi 			list_for_each_entry_safe(req, next, &fpq->io, list) {
2109b716d425SMiklos Szeredi 				req->out.h.error = -ECONNABORTED;
2110b716d425SMiklos Szeredi 				spin_lock(&req->waitq.lock);
2111b716d425SMiklos Szeredi 				set_bit(FR_ABORTED, &req->flags);
211277cd9d48SMiklos Szeredi 				if (!test_bit(FR_LOCKED, &req->flags)) {
211377cd9d48SMiklos Szeredi 					set_bit(FR_PRIVATE, &req->flags);
211487114373SMiklos Szeredi 					__fuse_get_request(req);
211575f3ee4cSMiklos Szeredi 					list_move(&req->list, &to_end);
211677cd9d48SMiklos Szeredi 				}
2117b716d425SMiklos Szeredi 				spin_unlock(&req->waitq.lock);
2118b716d425SMiklos Szeredi 			}
2119be2ff42cSKirill Tkhai 			for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
2120be2ff42cSKirill Tkhai 				list_splice_tail_init(&fpq->processing[i],
2121be2ff42cSKirill Tkhai 						      &to_end);
212245a91cb1SMiklos Szeredi 			spin_unlock(&fpq->lock);
2123c3696046SMiklos Szeredi 		}
2124ae2dffa3SKirill Tkhai 		spin_lock(&fc->bg_lock);
2125ae2dffa3SKirill Tkhai 		fc->blocked = 0;
212641f98274SMiklos Szeredi 		fc->max_background = UINT_MAX;
212741f98274SMiklos Szeredi 		flush_bg_queue(fc);
2128ae2dffa3SKirill Tkhai 		spin_unlock(&fc->bg_lock);
21298c91189aSMiklos Szeredi 
213076e43c8cSEric Biggers 		spin_lock(&fiq->lock);
21318c91189aSMiklos Szeredi 		fiq->connected = 0;
213275f3ee4cSMiklos Szeredi 		list_for_each_entry(req, &fiq->pending, list)
2133a8a86d78STahsin Erdogan 			clear_bit(FR_PENDING, &req->flags);
213475f3ee4cSMiklos Szeredi 		list_splice_tail_init(&fiq->pending, &to_end);
21358c91189aSMiklos Szeredi 		while (forget_pending(fiq))
21364388c5aaSVivek Goyal 			kfree(fuse_dequeue_forget(fiq, 1, NULL));
213776e43c8cSEric Biggers 		wake_up_all(&fiq->waitq);
213876e43c8cSEric Biggers 		spin_unlock(&fiq->lock);
21398c91189aSMiklos Szeredi 		kill_fasync(&fiq->fasync, SIGIO, POLL_IN);
2140ee314a87SMiklos Szeredi 		end_polls(fc);
2141ee314a87SMiklos Szeredi 		wake_up_all(&fc->blocked_waitq);
2142ee314a87SMiklos Szeredi 		spin_unlock(&fc->lock);
21438c91189aSMiklos Szeredi 
214475f3ee4cSMiklos Szeredi 		end_requests(fc, &to_end);
2145ee314a87SMiklos Szeredi 	} else {
2146d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
214769a53bf2SMiklos Szeredi 	}
2148ee314a87SMiklos Szeredi }
214908cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_abort_conn);
215069a53bf2SMiklos Szeredi 
2151b8f95e5dSMiklos Szeredi void fuse_wait_aborted(struct fuse_conn *fc)
2152b8f95e5dSMiklos Szeredi {
21532d84a2d1SMiklos Szeredi 	/* matches implicit memory barrier in fuse_drop_waiting() */
21542d84a2d1SMiklos Szeredi 	smp_mb();
2155b8f95e5dSMiklos Szeredi 	wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
2156b8f95e5dSMiklos Szeredi }
2157b8f95e5dSMiklos Szeredi 
215808cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file)
2159334f485dSMiklos Szeredi {
2160cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2161cc080e9eSMiklos Szeredi 
2162cc080e9eSMiklos Szeredi 	if (fud) {
2163cc080e9eSMiklos Szeredi 		struct fuse_conn *fc = fud->fc;
2164c3696046SMiklos Szeredi 		struct fuse_pqueue *fpq = &fud->pq;
216545ff350bSMiklos Szeredi 		LIST_HEAD(to_end);
2166be2ff42cSKirill Tkhai 		unsigned int i;
2167cc080e9eSMiklos Szeredi 
216845ff350bSMiklos Szeredi 		spin_lock(&fpq->lock);
2169c3696046SMiklos Szeredi 		WARN_ON(!list_empty(&fpq->io));
2170be2ff42cSKirill Tkhai 		for (i = 0; i < FUSE_PQ_HASH_SIZE; i++)
2171be2ff42cSKirill Tkhai 			list_splice_init(&fpq->processing[i], &to_end);
217245ff350bSMiklos Szeredi 		spin_unlock(&fpq->lock);
217345ff350bSMiklos Szeredi 
217445ff350bSMiklos Szeredi 		end_requests(fc, &to_end);
217545ff350bSMiklos Szeredi 
2176c3696046SMiklos Szeredi 		/* Are we the last open device? */
2177c3696046SMiklos Szeredi 		if (atomic_dec_and_test(&fc->dev_count)) {
2178f88996a9SMiklos Szeredi 			WARN_ON(fc->iq.fasync != NULL);
2179eb98e3bdSMiklos Szeredi 			fuse_abort_conn(fc);
2180c3696046SMiklos Szeredi 		}
2181cc080e9eSMiklos Szeredi 		fuse_dev_free(fud);
2182385a17bfSJeff Dike 	}
2183334f485dSMiklos Szeredi 	return 0;
2184334f485dSMiklos Szeredi }
218508cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_release);
2186334f485dSMiklos Szeredi 
2187385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on)
2188385a17bfSJeff Dike {
2189cc080e9eSMiklos Szeredi 	struct fuse_dev *fud = fuse_get_dev(file);
2190cc080e9eSMiklos Szeredi 
2191cc080e9eSMiklos Szeredi 	if (!fud)
2192a87046d8SMiklos Szeredi 		return -EPERM;
2193385a17bfSJeff Dike 
2194385a17bfSJeff Dike 	/* No locking - fasync_helper does its own locking */
2195cc080e9eSMiklos Szeredi 	return fasync_helper(fd, file, on, &fud->fc->iq.fasync);
2196385a17bfSJeff Dike }
2197385a17bfSJeff Dike 
219800c570f4SMiklos Szeredi static int fuse_device_clone(struct fuse_conn *fc, struct file *new)
219900c570f4SMiklos Szeredi {
2200cc080e9eSMiklos Szeredi 	struct fuse_dev *fud;
2201cc080e9eSMiklos Szeredi 
220200c570f4SMiklos Szeredi 	if (new->private_data)
220300c570f4SMiklos Szeredi 		return -EINVAL;
220400c570f4SMiklos Szeredi 
22050cd1eb9aSVivek Goyal 	fud = fuse_dev_alloc_install(fc);
2206cc080e9eSMiklos Szeredi 	if (!fud)
2207cc080e9eSMiklos Szeredi 		return -ENOMEM;
2208cc080e9eSMiklos Szeredi 
2209cc080e9eSMiklos Szeredi 	new->private_data = fud;
2210c3696046SMiklos Szeredi 	atomic_inc(&fc->dev_count);
221100c570f4SMiklos Szeredi 
221200c570f4SMiklos Szeredi 	return 0;
221300c570f4SMiklos Szeredi }
221400c570f4SMiklos Szeredi 
221500c570f4SMiklos Szeredi static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
221600c570f4SMiklos Szeredi 			   unsigned long arg)
221700c570f4SMiklos Szeredi {
221800c570f4SMiklos Szeredi 	int err = -ENOTTY;
221900c570f4SMiklos Szeredi 
222000c570f4SMiklos Szeredi 	if (cmd == FUSE_DEV_IOC_CLONE) {
222100c570f4SMiklos Szeredi 		int oldfd;
222200c570f4SMiklos Szeredi 
222300c570f4SMiklos Szeredi 		err = -EFAULT;
222400c570f4SMiklos Szeredi 		if (!get_user(oldfd, (__u32 __user *) arg)) {
222500c570f4SMiklos Szeredi 			struct file *old = fget(oldfd);
222600c570f4SMiklos Szeredi 
222700c570f4SMiklos Szeredi 			err = -EINVAL;
222800c570f4SMiklos Szeredi 			if (old) {
22298ed1f0e2SJann Horn 				struct fuse_dev *fud = NULL;
22308ed1f0e2SJann Horn 
22318ed1f0e2SJann Horn 				/*
22328ed1f0e2SJann Horn 				 * Check against file->f_op because CUSE
22338ed1f0e2SJann Horn 				 * uses the same ioctl handler.
22348ed1f0e2SJann Horn 				 */
22358ed1f0e2SJann Horn 				if (old->f_op == file->f_op &&
22368ed1f0e2SJann Horn 				    old->f_cred->user_ns == file->f_cred->user_ns)
22378ed1f0e2SJann Horn 					fud = fuse_get_dev(old);
223800c570f4SMiklos Szeredi 
2239cc080e9eSMiklos Szeredi 				if (fud) {
224000c570f4SMiklos Szeredi 					mutex_lock(&fuse_mutex);
2241cc080e9eSMiklos Szeredi 					err = fuse_device_clone(fud->fc, file);
224200c570f4SMiklos Szeredi 					mutex_unlock(&fuse_mutex);
224300c570f4SMiklos Szeredi 				}
224400c570f4SMiklos Szeredi 				fput(old);
224500c570f4SMiklos Szeredi 			}
224600c570f4SMiklos Szeredi 		}
224700c570f4SMiklos Szeredi 	}
224800c570f4SMiklos Szeredi 	return err;
224900c570f4SMiklos Szeredi }
225000c570f4SMiklos Szeredi 
22514b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = {
2252334f485dSMiklos Szeredi 	.owner		= THIS_MODULE,
225394e4fe2cSTom Van Braeckel 	.open		= fuse_dev_open,
2254334f485dSMiklos Szeredi 	.llseek		= no_llseek,
2255fbdbaccaSAl Viro 	.read_iter	= fuse_dev_read,
2256c3021629SMiklos Szeredi 	.splice_read	= fuse_dev_splice_read,
2257fbdbaccaSAl Viro 	.write_iter	= fuse_dev_write,
2258dd3bb14fSMiklos Szeredi 	.splice_write	= fuse_dev_splice_write,
2259334f485dSMiklos Szeredi 	.poll		= fuse_dev_poll,
2260334f485dSMiklos Szeredi 	.release	= fuse_dev_release,
2261385a17bfSJeff Dike 	.fasync		= fuse_dev_fasync,
226200c570f4SMiklos Szeredi 	.unlocked_ioctl = fuse_dev_ioctl,
226300c570f4SMiklos Szeredi 	.compat_ioctl   = fuse_dev_ioctl,
2264334f485dSMiklos Szeredi };
226508cbf542STejun Heo EXPORT_SYMBOL_GPL(fuse_dev_operations);
2266334f485dSMiklos Szeredi 
2267334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = {
2268334f485dSMiklos Szeredi 	.minor = FUSE_MINOR,
2269334f485dSMiklos Szeredi 	.name  = "fuse",
2270334f485dSMiklos Szeredi 	.fops = &fuse_dev_operations,
2271334f485dSMiklos Szeredi };
2272334f485dSMiklos Szeredi 
2273334f485dSMiklos Szeredi int __init fuse_dev_init(void)
2274334f485dSMiklos Szeredi {
2275334f485dSMiklos Szeredi 	int err = -ENOMEM;
2276334f485dSMiklos Szeredi 	fuse_req_cachep = kmem_cache_create("fuse_request",
2277334f485dSMiklos Szeredi 					    sizeof(struct fuse_req),
227820c2df83SPaul Mundt 					    0, 0, NULL);
2279334f485dSMiklos Szeredi 	if (!fuse_req_cachep)
2280334f485dSMiklos Szeredi 		goto out;
2281334f485dSMiklos Szeredi 
2282334f485dSMiklos Szeredi 	err = misc_register(&fuse_miscdevice);
2283334f485dSMiklos Szeredi 	if (err)
2284334f485dSMiklos Szeredi 		goto out_cache_clean;
2285334f485dSMiklos Szeredi 
2286334f485dSMiklos Szeredi 	return 0;
2287334f485dSMiklos Szeredi 
2288334f485dSMiklos Szeredi  out_cache_clean:
2289334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
2290334f485dSMiklos Szeredi  out:
2291334f485dSMiklos Szeredi 	return err;
2292334f485dSMiklos Szeredi }
2293334f485dSMiklos Szeredi 
2294334f485dSMiklos Szeredi void fuse_dev_cleanup(void)
2295334f485dSMiklos Szeredi {
2296334f485dSMiklos Szeredi 	misc_deregister(&fuse_miscdevice);
2297334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
2298334f485dSMiklos Szeredi }
2299