xref: /openbmc/linux/fs/fuse/dev.c (revision e94b1766)
1334f485dSMiklos Szeredi /*
2334f485dSMiklos Szeredi   FUSE: Filesystem in Userspace
3d7133114SMiklos Szeredi   Copyright (C) 2001-2006  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>
14334f485dSMiklos Szeredi #include <linux/uio.h>
15334f485dSMiklos Szeredi #include <linux/miscdevice.h>
16334f485dSMiklos Szeredi #include <linux/pagemap.h>
17334f485dSMiklos Szeredi #include <linux/file.h>
18334f485dSMiklos Szeredi #include <linux/slab.h>
19334f485dSMiklos Szeredi 
20334f485dSMiklos Szeredi MODULE_ALIAS_MISCDEV(FUSE_MINOR);
21334f485dSMiklos Szeredi 
22334f485dSMiklos Szeredi static kmem_cache_t *fuse_req_cachep;
23334f485dSMiklos Szeredi 
248bfc016dSMiklos Szeredi static struct fuse_conn *fuse_get_conn(struct file *file)
25334f485dSMiklos Szeredi {
260720b315SMiklos Szeredi 	/*
270720b315SMiklos Szeredi 	 * Lockless access is OK, because file->private data is set
280720b315SMiklos Szeredi 	 * once during mount and is valid until the file is released.
290720b315SMiklos Szeredi 	 */
300720b315SMiklos Szeredi 	return file->private_data;
31334f485dSMiklos Szeredi }
32334f485dSMiklos Szeredi 
338bfc016dSMiklos Szeredi static void fuse_request_init(struct fuse_req *req)
34334f485dSMiklos Szeredi {
35334f485dSMiklos Szeredi 	memset(req, 0, sizeof(*req));
36334f485dSMiklos Szeredi 	INIT_LIST_HEAD(&req->list);
37a4d27e75SMiklos Szeredi 	INIT_LIST_HEAD(&req->intr_entry);
38334f485dSMiklos Szeredi 	init_waitqueue_head(&req->waitq);
39334f485dSMiklos Szeredi 	atomic_set(&req->count, 1);
40334f485dSMiklos Szeredi }
41334f485dSMiklos Szeredi 
42334f485dSMiklos Szeredi struct fuse_req *fuse_request_alloc(void)
43334f485dSMiklos Szeredi {
44e94b1766SChristoph Lameter 	struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_KERNEL);
45334f485dSMiklos Szeredi 	if (req)
46334f485dSMiklos Szeredi 		fuse_request_init(req);
47334f485dSMiklos Szeredi 	return req;
48334f485dSMiklos Szeredi }
49334f485dSMiklos Szeredi 
50334f485dSMiklos Szeredi void fuse_request_free(struct fuse_req *req)
51334f485dSMiklos Szeredi {
52334f485dSMiklos Szeredi 	kmem_cache_free(fuse_req_cachep, req);
53334f485dSMiklos Szeredi }
54334f485dSMiklos Szeredi 
558bfc016dSMiklos Szeredi static void block_sigs(sigset_t *oldset)
56334f485dSMiklos Szeredi {
57334f485dSMiklos Szeredi 	sigset_t mask;
58334f485dSMiklos Szeredi 
59334f485dSMiklos Szeredi 	siginitsetinv(&mask, sigmask(SIGKILL));
60334f485dSMiklos Szeredi 	sigprocmask(SIG_BLOCK, &mask, oldset);
61334f485dSMiklos Szeredi }
62334f485dSMiklos Szeredi 
638bfc016dSMiklos Szeredi static void restore_sigs(sigset_t *oldset)
64334f485dSMiklos Szeredi {
65334f485dSMiklos Szeredi 	sigprocmask(SIG_SETMASK, oldset, NULL);
66334f485dSMiklos Szeredi }
67334f485dSMiklos Szeredi 
68334f485dSMiklos Szeredi static void __fuse_get_request(struct fuse_req *req)
69334f485dSMiklos Szeredi {
70334f485dSMiklos Szeredi 	atomic_inc(&req->count);
71334f485dSMiklos Szeredi }
72334f485dSMiklos Szeredi 
73334f485dSMiklos Szeredi /* Must be called with > 1 refcount */
74334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req)
75334f485dSMiklos Szeredi {
76334f485dSMiklos Szeredi 	BUG_ON(atomic_read(&req->count) < 2);
77334f485dSMiklos Szeredi 	atomic_dec(&req->count);
78334f485dSMiklos Szeredi }
79334f485dSMiklos Szeredi 
8033649c91SMiklos Szeredi static void fuse_req_init_context(struct fuse_req *req)
8133649c91SMiklos Szeredi {
8233649c91SMiklos Szeredi 	req->in.h.uid = current->fsuid;
8333649c91SMiklos Szeredi 	req->in.h.gid = current->fsgid;
8433649c91SMiklos Szeredi 	req->in.h.pid = current->pid;
8533649c91SMiklos Szeredi }
8633649c91SMiklos Szeredi 
87ce1d5a49SMiklos Szeredi struct fuse_req *fuse_get_req(struct fuse_conn *fc)
88334f485dSMiklos Szeredi {
8908a53cdcSMiklos Szeredi 	struct fuse_req *req;
9008a53cdcSMiklos Szeredi 	sigset_t oldset;
919bc5dddaSMiklos Szeredi 	int intr;
9208a53cdcSMiklos Szeredi 	int err;
9308a53cdcSMiklos Szeredi 
949bc5dddaSMiklos Szeredi 	atomic_inc(&fc->num_waiting);
9508a53cdcSMiklos Szeredi 	block_sigs(&oldset);
969bc5dddaSMiklos Szeredi 	intr = wait_event_interruptible(fc->blocked_waitq, !fc->blocked);
9708a53cdcSMiklos Szeredi 	restore_sigs(&oldset);
989bc5dddaSMiklos Szeredi 	err = -EINTR;
999bc5dddaSMiklos Szeredi 	if (intr)
1009bc5dddaSMiklos Szeredi 		goto out;
10108a53cdcSMiklos Szeredi 
10251eb01e7SMiklos Szeredi 	err = -ENOTCONN;
10351eb01e7SMiklos Szeredi 	if (!fc->connected)
10451eb01e7SMiklos Szeredi 		goto out;
10551eb01e7SMiklos Szeredi 
10608a53cdcSMiklos Szeredi 	req = fuse_request_alloc();
1079bc5dddaSMiklos Szeredi 	err = -ENOMEM;
108ce1d5a49SMiklos Szeredi 	if (!req)
1099bc5dddaSMiklos Szeredi 		goto out;
110334f485dSMiklos Szeredi 
11133649c91SMiklos Szeredi 	fuse_req_init_context(req);
1129bc5dddaSMiklos Szeredi 	req->waiting = 1;
113334f485dSMiklos Szeredi 	return req;
1149bc5dddaSMiklos Szeredi 
1159bc5dddaSMiklos Szeredi  out:
1169bc5dddaSMiklos Szeredi 	atomic_dec(&fc->num_waiting);
1179bc5dddaSMiklos Szeredi 	return ERR_PTR(err);
118334f485dSMiklos Szeredi }
119334f485dSMiklos Szeredi 
12033649c91SMiklos Szeredi /*
12133649c91SMiklos Szeredi  * Return request in fuse_file->reserved_req.  However that may
12233649c91SMiklos Szeredi  * currently be in use.  If that is the case, wait for it to become
12333649c91SMiklos Szeredi  * available.
12433649c91SMiklos Szeredi  */
12533649c91SMiklos Szeredi static struct fuse_req *get_reserved_req(struct fuse_conn *fc,
12633649c91SMiklos Szeredi 					 struct file *file)
12733649c91SMiklos Szeredi {
12833649c91SMiklos Szeredi 	struct fuse_req *req = NULL;
12933649c91SMiklos Szeredi 	struct fuse_file *ff = file->private_data;
13033649c91SMiklos Szeredi 
13133649c91SMiklos Szeredi 	do {
13233649c91SMiklos Szeredi 		wait_event(fc->blocked_waitq, ff->reserved_req);
13333649c91SMiklos Szeredi 		spin_lock(&fc->lock);
13433649c91SMiklos Szeredi 		if (ff->reserved_req) {
13533649c91SMiklos Szeredi 			req = ff->reserved_req;
13633649c91SMiklos Szeredi 			ff->reserved_req = NULL;
13733649c91SMiklos Szeredi 			get_file(file);
13833649c91SMiklos Szeredi 			req->stolen_file = file;
13933649c91SMiklos Szeredi 		}
14033649c91SMiklos Szeredi 		spin_unlock(&fc->lock);
14133649c91SMiklos Szeredi 	} while (!req);
14233649c91SMiklos Szeredi 
14333649c91SMiklos Szeredi 	return req;
14433649c91SMiklos Szeredi }
14533649c91SMiklos Szeredi 
14633649c91SMiklos Szeredi /*
14733649c91SMiklos Szeredi  * Put stolen request back into fuse_file->reserved_req
14833649c91SMiklos Szeredi  */
14933649c91SMiklos Szeredi static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req)
15033649c91SMiklos Szeredi {
15133649c91SMiklos Szeredi 	struct file *file = req->stolen_file;
15233649c91SMiklos Szeredi 	struct fuse_file *ff = file->private_data;
15333649c91SMiklos Szeredi 
15433649c91SMiklos Szeredi 	spin_lock(&fc->lock);
15533649c91SMiklos Szeredi 	fuse_request_init(req);
15633649c91SMiklos Szeredi 	BUG_ON(ff->reserved_req);
15733649c91SMiklos Szeredi 	ff->reserved_req = req;
15833649c91SMiklos Szeredi 	wake_up(&fc->blocked_waitq);
15933649c91SMiklos Szeredi 	spin_unlock(&fc->lock);
16033649c91SMiklos Szeredi 	fput(file);
16133649c91SMiklos Szeredi }
16233649c91SMiklos Szeredi 
16333649c91SMiklos Szeredi /*
16433649c91SMiklos Szeredi  * Gets a requests for a file operation, always succeeds
16533649c91SMiklos Szeredi  *
16633649c91SMiklos Szeredi  * This is used for sending the FLUSH request, which must get to
16733649c91SMiklos Szeredi  * userspace, due to POSIX locks which may need to be unlocked.
16833649c91SMiklos Szeredi  *
16933649c91SMiklos Szeredi  * If allocation fails due to OOM, use the reserved request in
17033649c91SMiklos Szeredi  * fuse_file.
17133649c91SMiklos Szeredi  *
17233649c91SMiklos Szeredi  * This is very unlikely to deadlock accidentally, since the
17333649c91SMiklos Szeredi  * filesystem should not have it's own file open.  If deadlock is
17433649c91SMiklos Szeredi  * intentional, it can still be broken by "aborting" the filesystem.
17533649c91SMiklos Szeredi  */
17633649c91SMiklos Szeredi struct fuse_req *fuse_get_req_nofail(struct fuse_conn *fc, struct file *file)
17733649c91SMiklos Szeredi {
17833649c91SMiklos Szeredi 	struct fuse_req *req;
17933649c91SMiklos Szeredi 
18033649c91SMiklos Szeredi 	atomic_inc(&fc->num_waiting);
18133649c91SMiklos Szeredi 	wait_event(fc->blocked_waitq, !fc->blocked);
18233649c91SMiklos Szeredi 	req = fuse_request_alloc();
18333649c91SMiklos Szeredi 	if (!req)
18433649c91SMiklos Szeredi 		req = get_reserved_req(fc, file);
18533649c91SMiklos Szeredi 
18633649c91SMiklos Szeredi 	fuse_req_init_context(req);
18733649c91SMiklos Szeredi 	req->waiting = 1;
18833649c91SMiklos Szeredi 	return req;
18933649c91SMiklos Szeredi }
19033649c91SMiklos Szeredi 
191334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
192334f485dSMiklos Szeredi {
1937128ec2aSMiklos Szeredi 	if (atomic_dec_and_test(&req->count)) {
1949bc5dddaSMiklos Szeredi 		if (req->waiting)
195ce1d5a49SMiklos Szeredi 			atomic_dec(&fc->num_waiting);
19633649c91SMiklos Szeredi 
19733649c91SMiklos Szeredi 		if (req->stolen_file)
19833649c91SMiklos Szeredi 			put_reserved_req(fc, req);
19933649c91SMiklos Szeredi 		else
200ce1d5a49SMiklos Szeredi 			fuse_request_free(req);
2017128ec2aSMiklos Szeredi 	}
2027128ec2aSMiklos Szeredi }
2037128ec2aSMiklos Szeredi 
2046dbbcb12SMiklos Szeredi /*
205334f485dSMiklos Szeredi  * This function is called when a request is finished.  Either a reply
206f9a2842eSMiklos Szeredi  * has arrived or it was aborted (and not yet sent) or some error
207f43b155aSMiklos Szeredi  * occurred during communication with userspace, or the device file
20851eb01e7SMiklos Szeredi  * was closed.  The requester thread is woken up (if still waiting),
20951eb01e7SMiklos Szeredi  * the 'end' callback is called if given, else the reference to the
21051eb01e7SMiklos Szeredi  * request is released
2117128ec2aSMiklos Szeredi  *
212d7133114SMiklos Szeredi  * Called with fc->lock, unlocks it
213334f485dSMiklos Szeredi  */
214334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req)
215105f4d7aSJosh Triplett 	__releases(fc->lock)
216334f485dSMiklos Szeredi {
2177128ec2aSMiklos Szeredi 	void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
2187128ec2aSMiklos Szeredi 	req->end = NULL;
21951eb01e7SMiklos Szeredi 	list_del(&req->list);
220a4d27e75SMiklos Szeredi 	list_del(&req->intr_entry);
22151eb01e7SMiklos Szeredi 	req->state = FUSE_REQ_FINISHED;
22251eb01e7SMiklos Szeredi 	if (req->background) {
22351eb01e7SMiklos Szeredi 		if (fc->num_background == FUSE_MAX_BACKGROUND) {
22451eb01e7SMiklos Szeredi 			fc->blocked = 0;
22551eb01e7SMiklos Szeredi 			wake_up_all(&fc->blocked_waitq);
22651eb01e7SMiklos Szeredi 		}
22751eb01e7SMiklos Szeredi 		fc->num_background--;
22851eb01e7SMiklos Szeredi 	}
229d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
23051eb01e7SMiklos Szeredi 	dput(req->dentry);
23151eb01e7SMiklos Szeredi 	mntput(req->vfsmount);
2326dbbcb12SMiklos Szeredi 	if (req->file)
2336dbbcb12SMiklos Szeredi 		fput(req->file);
23451eb01e7SMiklos Szeredi 	wake_up(&req->waitq);
23564c6d8edSMiklos Szeredi 	if (end)
23664c6d8edSMiklos Szeredi 		end(fc, req);
23764c6d8edSMiklos Szeredi 	else
238f43b155aSMiklos Szeredi 		fuse_put_request(fc, req);
239334f485dSMiklos Szeredi }
240334f485dSMiklos Szeredi 
241a4d27e75SMiklos Szeredi static void wait_answer_interruptible(struct fuse_conn *fc,
242a4d27e75SMiklos Szeredi 				      struct fuse_req *req)
243a4d27e75SMiklos Szeredi {
244a4d27e75SMiklos Szeredi 	if (signal_pending(current))
245a4d27e75SMiklos Szeredi 		return;
246a4d27e75SMiklos Szeredi 
247a4d27e75SMiklos Szeredi 	spin_unlock(&fc->lock);
248a4d27e75SMiklos Szeredi 	wait_event_interruptible(req->waitq, req->state == FUSE_REQ_FINISHED);
249a4d27e75SMiklos Szeredi 	spin_lock(&fc->lock);
250a4d27e75SMiklos Szeredi }
251a4d27e75SMiklos Szeredi 
252a4d27e75SMiklos Szeredi static void queue_interrupt(struct fuse_conn *fc, struct fuse_req *req)
253a4d27e75SMiklos Szeredi {
254a4d27e75SMiklos Szeredi 	list_add_tail(&req->intr_entry, &fc->interrupts);
255a4d27e75SMiklos Szeredi 	wake_up(&fc->waitq);
256a4d27e75SMiklos Szeredi 	kill_fasync(&fc->fasync, SIGIO, POLL_IN);
257a4d27e75SMiklos Szeredi }
258a4d27e75SMiklos Szeredi 
259d7133114SMiklos Szeredi /* Called with fc->lock held.  Releases, and then reacquires it. */
2607c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
261334f485dSMiklos Szeredi {
262a4d27e75SMiklos Szeredi 	if (!fc->no_interrupt) {
263a4d27e75SMiklos Szeredi 		/* Any signal may interrupt this */
264a4d27e75SMiklos Szeredi 		wait_answer_interruptible(fc, req);
265334f485dSMiklos Szeredi 
266a4d27e75SMiklos Szeredi 		if (req->aborted)
267a4d27e75SMiklos Szeredi 			goto aborted;
268a4d27e75SMiklos Szeredi 		if (req->state == FUSE_REQ_FINISHED)
269334f485dSMiklos Szeredi 			return;
270334f485dSMiklos Szeredi 
271a4d27e75SMiklos Szeredi 		req->interrupted = 1;
272a4d27e75SMiklos Szeredi 		if (req->state == FUSE_REQ_SENT)
273a4d27e75SMiklos Szeredi 			queue_interrupt(fc, req);
274a4d27e75SMiklos Szeredi 	}
275a4d27e75SMiklos Szeredi 
276a4d27e75SMiklos Szeredi 	if (req->force) {
277a4d27e75SMiklos Szeredi 		spin_unlock(&fc->lock);
278a4d27e75SMiklos Szeredi 		wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
279a4d27e75SMiklos Szeredi 		spin_lock(&fc->lock);
280a4d27e75SMiklos Szeredi 	} else {
281a4d27e75SMiklos Szeredi 		sigset_t oldset;
282a4d27e75SMiklos Szeredi 
283a4d27e75SMiklos Szeredi 		/* Only fatal signals may interrupt this */
284a4d27e75SMiklos Szeredi 		block_sigs(&oldset);
285a4d27e75SMiklos Szeredi 		wait_answer_interruptible(fc, req);
286a4d27e75SMiklos Szeredi 		restore_sigs(&oldset);
287a4d27e75SMiklos Szeredi 	}
288a4d27e75SMiklos Szeredi 
289a4d27e75SMiklos Szeredi 	if (req->aborted)
290a4d27e75SMiklos Szeredi 		goto aborted;
291a4d27e75SMiklos Szeredi 	if (req->state == FUSE_REQ_FINISHED)
292a4d27e75SMiklos Szeredi  		return;
293a4d27e75SMiklos Szeredi 
294334f485dSMiklos Szeredi 	req->out.h.error = -EINTR;
295f9a2842eSMiklos Szeredi 	req->aborted = 1;
296a4d27e75SMiklos Szeredi 
297a4d27e75SMiklos Szeredi  aborted:
298334f485dSMiklos Szeredi 	if (req->locked) {
299334f485dSMiklos Szeredi 		/* This is uninterruptible sleep, because data is
300334f485dSMiklos Szeredi 		   being copied to/from the buffers of req.  During
301334f485dSMiklos Szeredi 		   locked state, there mustn't be any filesystem
302334f485dSMiklos Szeredi 		   operation (e.g. page fault), since that could lead
303334f485dSMiklos Szeredi 		   to deadlock */
304d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
305334f485dSMiklos Szeredi 		wait_event(req->waitq, !req->locked);
306d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
307334f485dSMiklos Szeredi 	}
30883cfd493SMiklos Szeredi 	if (req->state == FUSE_REQ_PENDING) {
309334f485dSMiklos Szeredi 		list_del(&req->list);
310334f485dSMiklos Szeredi 		__fuse_put_request(req);
31151eb01e7SMiklos Szeredi 	} else if (req->state == FUSE_REQ_SENT) {
31251eb01e7SMiklos Szeredi 		spin_unlock(&fc->lock);
31351eb01e7SMiklos Szeredi 		wait_event(req->waitq, req->state == FUSE_REQ_FINISHED);
31451eb01e7SMiklos Szeredi 		spin_lock(&fc->lock);
31551eb01e7SMiklos Szeredi 	}
316334f485dSMiklos Szeredi }
317334f485dSMiklos Szeredi 
318334f485dSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args)
319334f485dSMiklos Szeredi {
320334f485dSMiklos Szeredi 	unsigned nbytes = 0;
321334f485dSMiklos Szeredi 	unsigned i;
322334f485dSMiklos Szeredi 
323334f485dSMiklos Szeredi 	for (i = 0; i < numargs; i++)
324334f485dSMiklos Szeredi 		nbytes += args[i].size;
325334f485dSMiklos Szeredi 
326334f485dSMiklos Szeredi 	return nbytes;
327334f485dSMiklos Szeredi }
328334f485dSMiklos Szeredi 
329a4d27e75SMiklos Szeredi static u64 fuse_get_unique(struct fuse_conn *fc)
330334f485dSMiklos Szeredi  {
331334f485dSMiklos Szeredi  	fc->reqctr++;
332334f485dSMiklos Szeredi  	/* zero is special */
333334f485dSMiklos Szeredi  	if (fc->reqctr == 0)
334334f485dSMiklos Szeredi  		fc->reqctr = 1;
335a4d27e75SMiklos Szeredi 
336a4d27e75SMiklos Szeredi 	return fc->reqctr;
337a4d27e75SMiklos Szeredi }
338a4d27e75SMiklos Szeredi 
339a4d27e75SMiklos Szeredi static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
340a4d27e75SMiklos Szeredi {
341a4d27e75SMiklos Szeredi 	req->in.h.unique = fuse_get_unique(fc);
342334f485dSMiklos Szeredi 	req->in.h.len = sizeof(struct fuse_in_header) +
343334f485dSMiklos Szeredi 		len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
344334f485dSMiklos Szeredi 	list_add_tail(&req->list, &fc->pending);
34583cfd493SMiklos Szeredi 	req->state = FUSE_REQ_PENDING;
3469bc5dddaSMiklos Szeredi 	if (!req->waiting) {
3479bc5dddaSMiklos Szeredi 		req->waiting = 1;
3489bc5dddaSMiklos Szeredi 		atomic_inc(&fc->num_waiting);
3499bc5dddaSMiklos Szeredi 	}
350334f485dSMiklos Szeredi 	wake_up(&fc->waitq);
351385a17bfSJeff Dike 	kill_fasync(&fc->fasync, SIGIO, POLL_IN);
352334f485dSMiklos Szeredi }
353334f485dSMiklos Szeredi 
3547c352bdfSMiklos Szeredi void request_send(struct fuse_conn *fc, struct fuse_req *req)
355334f485dSMiklos Szeredi {
356334f485dSMiklos Szeredi 	req->isreply = 1;
357d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
3581e9a4ed9SMiklos Szeredi 	if (!fc->connected)
359334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
360334f485dSMiklos Szeredi 	else if (fc->conn_error)
361334f485dSMiklos Szeredi 		req->out.h.error = -ECONNREFUSED;
362334f485dSMiklos Szeredi 	else {
363334f485dSMiklos Szeredi 		queue_request(fc, req);
364334f485dSMiklos Szeredi 		/* acquire extra reference, since request is still needed
365334f485dSMiklos Szeredi 		   after request_end() */
366334f485dSMiklos Szeredi 		__fuse_get_request(req);
367334f485dSMiklos Szeredi 
3687c352bdfSMiklos Szeredi 		request_wait_answer(fc, req);
369334f485dSMiklos Szeredi 	}
370d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
371334f485dSMiklos Szeredi }
372334f485dSMiklos Szeredi 
373334f485dSMiklos Szeredi static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
374334f485dSMiklos Szeredi {
375d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
3761e9a4ed9SMiklos Szeredi 	if (fc->connected) {
37751eb01e7SMiklos Szeredi 		req->background = 1;
37851eb01e7SMiklos Szeredi 		fc->num_background++;
37951eb01e7SMiklos Szeredi 		if (fc->num_background == FUSE_MAX_BACKGROUND)
38051eb01e7SMiklos Szeredi 			fc->blocked = 1;
38151eb01e7SMiklos Szeredi 
382334f485dSMiklos Szeredi 		queue_request(fc, req);
383d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
384334f485dSMiklos Szeredi 	} else {
385334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
386334f485dSMiklos Szeredi 		request_end(fc, req);
387334f485dSMiklos Szeredi 	}
388334f485dSMiklos Szeredi }
389334f485dSMiklos Szeredi 
390334f485dSMiklos Szeredi void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req)
391334f485dSMiklos Szeredi {
392334f485dSMiklos Szeredi 	req->isreply = 0;
393334f485dSMiklos Szeredi 	request_send_nowait(fc, req);
394334f485dSMiklos Szeredi }
395334f485dSMiklos Szeredi 
396334f485dSMiklos Szeredi void request_send_background(struct fuse_conn *fc, struct fuse_req *req)
397334f485dSMiklos Szeredi {
398334f485dSMiklos Szeredi 	req->isreply = 1;
399334f485dSMiklos Szeredi 	request_send_nowait(fc, req);
400334f485dSMiklos Szeredi }
401334f485dSMiklos Szeredi 
402334f485dSMiklos Szeredi /*
403334f485dSMiklos Szeredi  * Lock the request.  Up to the next unlock_request() there mustn't be
404334f485dSMiklos Szeredi  * anything that could cause a page-fault.  If the request was already
405f9a2842eSMiklos Szeredi  * aborted bail out.
406334f485dSMiklos Szeredi  */
407d7133114SMiklos Szeredi static int lock_request(struct fuse_conn *fc, struct fuse_req *req)
408334f485dSMiklos Szeredi {
409334f485dSMiklos Szeredi 	int err = 0;
410334f485dSMiklos Szeredi 	if (req) {
411d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
412f9a2842eSMiklos Szeredi 		if (req->aborted)
413334f485dSMiklos Szeredi 			err = -ENOENT;
414334f485dSMiklos Szeredi 		else
415334f485dSMiklos Szeredi 			req->locked = 1;
416d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
417334f485dSMiklos Szeredi 	}
418334f485dSMiklos Szeredi 	return err;
419334f485dSMiklos Szeredi }
420334f485dSMiklos Szeredi 
421334f485dSMiklos Szeredi /*
422f9a2842eSMiklos Szeredi  * Unlock request.  If it was aborted during being locked, the
423334f485dSMiklos Szeredi  * requester thread is currently waiting for it to be unlocked, so
424334f485dSMiklos Szeredi  * wake it up.
425334f485dSMiklos Szeredi  */
426d7133114SMiklos Szeredi static void unlock_request(struct fuse_conn *fc, struct fuse_req *req)
427334f485dSMiklos Szeredi {
428334f485dSMiklos Szeredi 	if (req) {
429d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
430334f485dSMiklos Szeredi 		req->locked = 0;
431f9a2842eSMiklos Szeredi 		if (req->aborted)
432334f485dSMiklos Szeredi 			wake_up(&req->waitq);
433d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
434334f485dSMiklos Szeredi 	}
435334f485dSMiklos Szeredi }
436334f485dSMiklos Szeredi 
437334f485dSMiklos Szeredi struct fuse_copy_state {
438d7133114SMiklos Szeredi 	struct fuse_conn *fc;
439334f485dSMiklos Szeredi 	int write;
440334f485dSMiklos Szeredi 	struct fuse_req *req;
441334f485dSMiklos Szeredi 	const struct iovec *iov;
442334f485dSMiklos Szeredi 	unsigned long nr_segs;
443334f485dSMiklos Szeredi 	unsigned long seglen;
444334f485dSMiklos Szeredi 	unsigned long addr;
445334f485dSMiklos Szeredi 	struct page *pg;
446334f485dSMiklos Szeredi 	void *mapaddr;
447334f485dSMiklos Szeredi 	void *buf;
448334f485dSMiklos Szeredi 	unsigned len;
449334f485dSMiklos Szeredi };
450334f485dSMiklos Szeredi 
451d7133114SMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc,
452d7133114SMiklos Szeredi 			   int write, struct fuse_req *req,
453d7133114SMiklos Szeredi 			   const struct iovec *iov, unsigned long nr_segs)
454334f485dSMiklos Szeredi {
455334f485dSMiklos Szeredi 	memset(cs, 0, sizeof(*cs));
456d7133114SMiklos Szeredi 	cs->fc = fc;
457334f485dSMiklos Szeredi 	cs->write = write;
458334f485dSMiklos Szeredi 	cs->req = req;
459334f485dSMiklos Szeredi 	cs->iov = iov;
460334f485dSMiklos Szeredi 	cs->nr_segs = nr_segs;
461334f485dSMiklos Szeredi }
462334f485dSMiklos Szeredi 
463334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */
4648bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs)
465334f485dSMiklos Szeredi {
466334f485dSMiklos Szeredi 	if (cs->mapaddr) {
467334f485dSMiklos Szeredi 		kunmap_atomic(cs->mapaddr, KM_USER0);
468334f485dSMiklos Szeredi 		if (cs->write) {
469334f485dSMiklos Szeredi 			flush_dcache_page(cs->pg);
470334f485dSMiklos Szeredi 			set_page_dirty_lock(cs->pg);
471334f485dSMiklos Szeredi 		}
472334f485dSMiklos Szeredi 		put_page(cs->pg);
473334f485dSMiklos Szeredi 		cs->mapaddr = NULL;
474334f485dSMiklos Szeredi 	}
475334f485dSMiklos Szeredi }
476334f485dSMiklos Szeredi 
477334f485dSMiklos Szeredi /*
478334f485dSMiklos Szeredi  * Get another pagefull of userspace buffer, and map it to kernel
479334f485dSMiklos Szeredi  * address space, and lock request
480334f485dSMiklos Szeredi  */
481334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs)
482334f485dSMiklos Szeredi {
483334f485dSMiklos Szeredi 	unsigned long offset;
484334f485dSMiklos Szeredi 	int err;
485334f485dSMiklos Szeredi 
486d7133114SMiklos Szeredi 	unlock_request(cs->fc, cs->req);
487334f485dSMiklos Szeredi 	fuse_copy_finish(cs);
488334f485dSMiklos Szeredi 	if (!cs->seglen) {
489334f485dSMiklos Szeredi 		BUG_ON(!cs->nr_segs);
490334f485dSMiklos Szeredi 		cs->seglen = cs->iov[0].iov_len;
491334f485dSMiklos Szeredi 		cs->addr = (unsigned long) cs->iov[0].iov_base;
492334f485dSMiklos Szeredi 		cs->iov ++;
493334f485dSMiklos Szeredi 		cs->nr_segs --;
494334f485dSMiklos Szeredi 	}
495334f485dSMiklos Szeredi 	down_read(&current->mm->mmap_sem);
496334f485dSMiklos Szeredi 	err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
497334f485dSMiklos Szeredi 			     &cs->pg, NULL);
498334f485dSMiklos Szeredi 	up_read(&current->mm->mmap_sem);
499334f485dSMiklos Szeredi 	if (err < 0)
500334f485dSMiklos Szeredi 		return err;
501334f485dSMiklos Szeredi 	BUG_ON(err != 1);
502334f485dSMiklos Szeredi 	offset = cs->addr % PAGE_SIZE;
503334f485dSMiklos Szeredi 	cs->mapaddr = kmap_atomic(cs->pg, KM_USER0);
504334f485dSMiklos Szeredi 	cs->buf = cs->mapaddr + offset;
505334f485dSMiklos Szeredi 	cs->len = min(PAGE_SIZE - offset, cs->seglen);
506334f485dSMiklos Szeredi 	cs->seglen -= cs->len;
507334f485dSMiklos Szeredi 	cs->addr += cs->len;
508334f485dSMiklos Szeredi 
509d7133114SMiklos Szeredi 	return lock_request(cs->fc, cs->req);
510334f485dSMiklos Szeredi }
511334f485dSMiklos Szeredi 
512334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */
5138bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
514334f485dSMiklos Szeredi {
515334f485dSMiklos Szeredi 	unsigned ncpy = min(*size, cs->len);
516334f485dSMiklos Szeredi 	if (val) {
517334f485dSMiklos Szeredi 		if (cs->write)
518334f485dSMiklos Szeredi 			memcpy(cs->buf, *val, ncpy);
519334f485dSMiklos Szeredi 		else
520334f485dSMiklos Szeredi 			memcpy(*val, cs->buf, ncpy);
521334f485dSMiklos Szeredi 		*val += ncpy;
522334f485dSMiklos Szeredi 	}
523334f485dSMiklos Szeredi 	*size -= ncpy;
524334f485dSMiklos Szeredi 	cs->len -= ncpy;
525334f485dSMiklos Szeredi 	cs->buf += ncpy;
526334f485dSMiklos Szeredi 	return ncpy;
527334f485dSMiklos Szeredi }
528334f485dSMiklos Szeredi 
529334f485dSMiklos Szeredi /*
530334f485dSMiklos Szeredi  * Copy a page in the request to/from the userspace buffer.  Must be
531334f485dSMiklos Szeredi  * done atomically
532334f485dSMiklos Szeredi  */
5338bfc016dSMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page *page,
534334f485dSMiklos Szeredi 			  unsigned offset, unsigned count, int zeroing)
535334f485dSMiklos Szeredi {
536334f485dSMiklos Szeredi 	if (page && zeroing && count < PAGE_SIZE) {
537334f485dSMiklos Szeredi 		void *mapaddr = kmap_atomic(page, KM_USER1);
538334f485dSMiklos Szeredi 		memset(mapaddr, 0, PAGE_SIZE);
539334f485dSMiklos Szeredi 		kunmap_atomic(mapaddr, KM_USER1);
540334f485dSMiklos Szeredi 	}
541334f485dSMiklos Szeredi 	while (count) {
542334f485dSMiklos Szeredi 		int err;
543334f485dSMiklos Szeredi 		if (!cs->len && (err = fuse_copy_fill(cs)))
544334f485dSMiklos Szeredi 			return err;
545334f485dSMiklos Szeredi 		if (page) {
546334f485dSMiklos Szeredi 			void *mapaddr = kmap_atomic(page, KM_USER1);
547334f485dSMiklos Szeredi 			void *buf = mapaddr + offset;
548334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, &buf, &count);
549334f485dSMiklos Szeredi 			kunmap_atomic(mapaddr, KM_USER1);
550334f485dSMiklos Szeredi 		} else
551334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, NULL, &count);
552334f485dSMiklos Szeredi 	}
553334f485dSMiklos Szeredi 	if (page && !cs->write)
554334f485dSMiklos Szeredi 		flush_dcache_page(page);
555334f485dSMiklos Szeredi 	return 0;
556334f485dSMiklos Szeredi }
557334f485dSMiklos Szeredi 
558334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */
559334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
560334f485dSMiklos Szeredi 			   int zeroing)
561334f485dSMiklos Szeredi {
562334f485dSMiklos Szeredi 	unsigned i;
563334f485dSMiklos Szeredi 	struct fuse_req *req = cs->req;
564334f485dSMiklos Szeredi 	unsigned offset = req->page_offset;
565334f485dSMiklos Szeredi 	unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);
566334f485dSMiklos Szeredi 
567334f485dSMiklos Szeredi 	for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
568334f485dSMiklos Szeredi 		struct page *page = req->pages[i];
569334f485dSMiklos Szeredi 		int err = fuse_copy_page(cs, page, offset, count, zeroing);
570334f485dSMiklos Szeredi 		if (err)
571334f485dSMiklos Szeredi 			return err;
572334f485dSMiklos Szeredi 
573334f485dSMiklos Szeredi 		nbytes -= count;
574334f485dSMiklos Szeredi 		count = min(nbytes, (unsigned) PAGE_SIZE);
575334f485dSMiklos Szeredi 		offset = 0;
576334f485dSMiklos Szeredi 	}
577334f485dSMiklos Szeredi 	return 0;
578334f485dSMiklos Szeredi }
579334f485dSMiklos Szeredi 
580334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */
581334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
582334f485dSMiklos Szeredi {
583334f485dSMiklos Szeredi 	while (size) {
584334f485dSMiklos Szeredi 		int err;
585334f485dSMiklos Szeredi 		if (!cs->len && (err = fuse_copy_fill(cs)))
586334f485dSMiklos Szeredi 			return err;
587334f485dSMiklos Szeredi 		fuse_copy_do(cs, &val, &size);
588334f485dSMiklos Szeredi 	}
589334f485dSMiklos Szeredi 	return 0;
590334f485dSMiklos Szeredi }
591334f485dSMiklos Szeredi 
592334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */
593334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
594334f485dSMiklos Szeredi 			  unsigned argpages, struct fuse_arg *args,
595334f485dSMiklos Szeredi 			  int zeroing)
596334f485dSMiklos Szeredi {
597334f485dSMiklos Szeredi 	int err = 0;
598334f485dSMiklos Szeredi 	unsigned i;
599334f485dSMiklos Szeredi 
600334f485dSMiklos Szeredi 	for (i = 0; !err && i < numargs; i++)  {
601334f485dSMiklos Szeredi 		struct fuse_arg *arg = &args[i];
602334f485dSMiklos Szeredi 		if (i == numargs - 1 && argpages)
603334f485dSMiklos Szeredi 			err = fuse_copy_pages(cs, arg->size, zeroing);
604334f485dSMiklos Szeredi 		else
605334f485dSMiklos Szeredi 			err = fuse_copy_one(cs, arg->value, arg->size);
606334f485dSMiklos Szeredi 	}
607334f485dSMiklos Szeredi 	return err;
608334f485dSMiklos Szeredi }
609334f485dSMiklos Szeredi 
610a4d27e75SMiklos Szeredi static int request_pending(struct fuse_conn *fc)
611a4d27e75SMiklos Szeredi {
612a4d27e75SMiklos Szeredi 	return !list_empty(&fc->pending) || !list_empty(&fc->interrupts);
613a4d27e75SMiklos Szeredi }
614a4d27e75SMiklos Szeredi 
615334f485dSMiklos Szeredi /* Wait until a request is available on the pending list */
616334f485dSMiklos Szeredi static void request_wait(struct fuse_conn *fc)
617334f485dSMiklos Szeredi {
618334f485dSMiklos Szeredi 	DECLARE_WAITQUEUE(wait, current);
619334f485dSMiklos Szeredi 
620334f485dSMiklos Szeredi 	add_wait_queue_exclusive(&fc->waitq, &wait);
621a4d27e75SMiklos Szeredi 	while (fc->connected && !request_pending(fc)) {
622334f485dSMiklos Szeredi 		set_current_state(TASK_INTERRUPTIBLE);
623334f485dSMiklos Szeredi 		if (signal_pending(current))
624334f485dSMiklos Szeredi 			break;
625334f485dSMiklos Szeredi 
626d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
627334f485dSMiklos Szeredi 		schedule();
628d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
629334f485dSMiklos Szeredi 	}
630334f485dSMiklos Szeredi 	set_current_state(TASK_RUNNING);
631334f485dSMiklos Szeredi 	remove_wait_queue(&fc->waitq, &wait);
632334f485dSMiklos Szeredi }
633334f485dSMiklos Szeredi 
634334f485dSMiklos Szeredi /*
635a4d27e75SMiklos Szeredi  * Transfer an interrupt request to userspace
636a4d27e75SMiklos Szeredi  *
637a4d27e75SMiklos Szeredi  * Unlike other requests this is assembled on demand, without a need
638a4d27e75SMiklos Szeredi  * to allocate a separate fuse_req structure.
639a4d27e75SMiklos Szeredi  *
640a4d27e75SMiklos Szeredi  * Called with fc->lock held, releases it
641a4d27e75SMiklos Szeredi  */
642a4d27e75SMiklos Szeredi static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req,
643a4d27e75SMiklos Szeredi 			       const struct iovec *iov, unsigned long nr_segs)
644105f4d7aSJosh Triplett 	__releases(fc->lock)
645a4d27e75SMiklos Szeredi {
646a4d27e75SMiklos Szeredi 	struct fuse_copy_state cs;
647a4d27e75SMiklos Szeredi 	struct fuse_in_header ih;
648a4d27e75SMiklos Szeredi 	struct fuse_interrupt_in arg;
649a4d27e75SMiklos Szeredi 	unsigned reqsize = sizeof(ih) + sizeof(arg);
650a4d27e75SMiklos Szeredi 	int err;
651a4d27e75SMiklos Szeredi 
652a4d27e75SMiklos Szeredi 	list_del_init(&req->intr_entry);
653a4d27e75SMiklos Szeredi 	req->intr_unique = fuse_get_unique(fc);
654a4d27e75SMiklos Szeredi 	memset(&ih, 0, sizeof(ih));
655a4d27e75SMiklos Szeredi 	memset(&arg, 0, sizeof(arg));
656a4d27e75SMiklos Szeredi 	ih.len = reqsize;
657a4d27e75SMiklos Szeredi 	ih.opcode = FUSE_INTERRUPT;
658a4d27e75SMiklos Szeredi 	ih.unique = req->intr_unique;
659a4d27e75SMiklos Szeredi 	arg.unique = req->in.h.unique;
660a4d27e75SMiklos Szeredi 
661a4d27e75SMiklos Szeredi 	spin_unlock(&fc->lock);
662a4d27e75SMiklos Szeredi 	if (iov_length(iov, nr_segs) < reqsize)
663a4d27e75SMiklos Szeredi 		return -EINVAL;
664a4d27e75SMiklos Szeredi 
665a4d27e75SMiklos Szeredi 	fuse_copy_init(&cs, fc, 1, NULL, iov, nr_segs);
666a4d27e75SMiklos Szeredi 	err = fuse_copy_one(&cs, &ih, sizeof(ih));
667a4d27e75SMiklos Szeredi 	if (!err)
668a4d27e75SMiklos Szeredi 		err = fuse_copy_one(&cs, &arg, sizeof(arg));
669a4d27e75SMiklos Szeredi 	fuse_copy_finish(&cs);
670a4d27e75SMiklos Szeredi 
671a4d27e75SMiklos Szeredi 	return err ? err : reqsize;
672a4d27e75SMiklos Szeredi }
673a4d27e75SMiklos Szeredi 
674a4d27e75SMiklos Szeredi /*
675334f485dSMiklos Szeredi  * Read a single request into the userspace filesystem's buffer.  This
676334f485dSMiklos Szeredi  * function waits until a request is available, then removes it from
677334f485dSMiklos Szeredi  * the pending list and copies request data to userspace buffer.  If
678f9a2842eSMiklos Szeredi  * no reply is needed (FORGET) or request has been aborted or there
679f9a2842eSMiklos Szeredi  * was an error during the copying then it's finished by calling
680334f485dSMiklos Szeredi  * request_end().  Otherwise add it to the processing list, and set
681334f485dSMiklos Szeredi  * the 'sent' flag.
682334f485dSMiklos Szeredi  */
683ee0b3e67SBadari Pulavarty static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
684ee0b3e67SBadari Pulavarty 			      unsigned long nr_segs, loff_t pos)
685334f485dSMiklos Szeredi {
686334f485dSMiklos Szeredi 	int err;
687334f485dSMiklos Szeredi 	struct fuse_req *req;
688334f485dSMiklos Szeredi 	struct fuse_in *in;
689334f485dSMiklos Szeredi 	struct fuse_copy_state cs;
690334f485dSMiklos Szeredi 	unsigned reqsize;
691ee0b3e67SBadari Pulavarty 	struct file *file = iocb->ki_filp;
6920720b315SMiklos Szeredi 	struct fuse_conn *fc = fuse_get_conn(file);
6930720b315SMiklos Szeredi 	if (!fc)
6940720b315SMiklos Szeredi 		return -EPERM;
695334f485dSMiklos Szeredi 
6961d3d752bSMiklos Szeredi  restart:
697d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
698e5ac1d1eSJeff Dike 	err = -EAGAIN;
699e5ac1d1eSJeff Dike 	if ((file->f_flags & O_NONBLOCK) && fc->connected &&
700a4d27e75SMiklos Szeredi 	    !request_pending(fc))
701e5ac1d1eSJeff Dike 		goto err_unlock;
702e5ac1d1eSJeff Dike 
703334f485dSMiklos Szeredi 	request_wait(fc);
704334f485dSMiklos Szeredi 	err = -ENODEV;
7059ba7cbbaSMiklos Szeredi 	if (!fc->connected)
706334f485dSMiklos Szeredi 		goto err_unlock;
707334f485dSMiklos Szeredi 	err = -ERESTARTSYS;
708a4d27e75SMiklos Szeredi 	if (!request_pending(fc))
709334f485dSMiklos Szeredi 		goto err_unlock;
710334f485dSMiklos Szeredi 
711a4d27e75SMiklos Szeredi 	if (!list_empty(&fc->interrupts)) {
712a4d27e75SMiklos Szeredi 		req = list_entry(fc->interrupts.next, struct fuse_req,
713a4d27e75SMiklos Szeredi 				 intr_entry);
714a4d27e75SMiklos Szeredi 		return fuse_read_interrupt(fc, req, iov, nr_segs);
715a4d27e75SMiklos Szeredi 	}
716a4d27e75SMiklos Szeredi 
717334f485dSMiklos Szeredi 	req = list_entry(fc->pending.next, struct fuse_req, list);
71883cfd493SMiklos Szeredi 	req->state = FUSE_REQ_READING;
719d77a1d5bSMiklos Szeredi 	list_move(&req->list, &fc->io);
720334f485dSMiklos Szeredi 
721334f485dSMiklos Szeredi 	in = &req->in;
7221d3d752bSMiklos Szeredi 	reqsize = in->h.len;
7231d3d752bSMiklos Szeredi 	/* If request is too large, reply with an error and restart the read */
7241d3d752bSMiklos Szeredi 	if (iov_length(iov, nr_segs) < reqsize) {
7251d3d752bSMiklos Szeredi 		req->out.h.error = -EIO;
7261d3d752bSMiklos Szeredi 		/* SETXATTR is special, since it may contain too large data */
7271d3d752bSMiklos Szeredi 		if (in->h.opcode == FUSE_SETXATTR)
7281d3d752bSMiklos Szeredi 			req->out.h.error = -E2BIG;
7291d3d752bSMiklos Szeredi 		request_end(fc, req);
7301d3d752bSMiklos Szeredi 		goto restart;
7311d3d752bSMiklos Szeredi 	}
732d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
733d7133114SMiklos Szeredi 	fuse_copy_init(&cs, fc, 1, req, iov, nr_segs);
734334f485dSMiklos Szeredi 	err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
735334f485dSMiklos Szeredi 	if (!err)
736334f485dSMiklos Szeredi 		err = fuse_copy_args(&cs, in->numargs, in->argpages,
737334f485dSMiklos Szeredi 				     (struct fuse_arg *) in->args, 0);
738334f485dSMiklos Szeredi 	fuse_copy_finish(&cs);
739d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
740334f485dSMiklos Szeredi 	req->locked = 0;
741f9a2842eSMiklos Szeredi 	if (!err && req->aborted)
742334f485dSMiklos Szeredi 		err = -ENOENT;
743334f485dSMiklos Szeredi 	if (err) {
744f9a2842eSMiklos Szeredi 		if (!req->aborted)
745334f485dSMiklos Szeredi 			req->out.h.error = -EIO;
746334f485dSMiklos Szeredi 		request_end(fc, req);
747334f485dSMiklos Szeredi 		return err;
748334f485dSMiklos Szeredi 	}
749334f485dSMiklos Szeredi 	if (!req->isreply)
750334f485dSMiklos Szeredi 		request_end(fc, req);
751334f485dSMiklos Szeredi 	else {
75283cfd493SMiklos Szeredi 		req->state = FUSE_REQ_SENT;
753d77a1d5bSMiklos Szeredi 		list_move_tail(&req->list, &fc->processing);
754a4d27e75SMiklos Szeredi 		if (req->interrupted)
755a4d27e75SMiklos Szeredi 			queue_interrupt(fc, req);
756d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
757334f485dSMiklos Szeredi 	}
758334f485dSMiklos Szeredi 	return reqsize;
759334f485dSMiklos Szeredi 
760334f485dSMiklos Szeredi  err_unlock:
761d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
762334f485dSMiklos Szeredi 	return err;
763334f485dSMiklos Szeredi }
764334f485dSMiklos Szeredi 
765334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */
766334f485dSMiklos Szeredi static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
767334f485dSMiklos Szeredi {
768334f485dSMiklos Szeredi 	struct list_head *entry;
769334f485dSMiklos Szeredi 
770334f485dSMiklos Szeredi 	list_for_each(entry, &fc->processing) {
771334f485dSMiklos Szeredi 		struct fuse_req *req;
772334f485dSMiklos Szeredi 		req = list_entry(entry, struct fuse_req, list);
773a4d27e75SMiklos Szeredi 		if (req->in.h.unique == unique || req->intr_unique == unique)
774334f485dSMiklos Szeredi 			return req;
775334f485dSMiklos Szeredi 	}
776334f485dSMiklos Szeredi 	return NULL;
777334f485dSMiklos Szeredi }
778334f485dSMiklos Szeredi 
779334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
780334f485dSMiklos Szeredi 			 unsigned nbytes)
781334f485dSMiklos Szeredi {
782334f485dSMiklos Szeredi 	unsigned reqsize = sizeof(struct fuse_out_header);
783334f485dSMiklos Szeredi 
784334f485dSMiklos Szeredi 	if (out->h.error)
785334f485dSMiklos Szeredi 		return nbytes != reqsize ? -EINVAL : 0;
786334f485dSMiklos Szeredi 
787334f485dSMiklos Szeredi 	reqsize += len_args(out->numargs, out->args);
788334f485dSMiklos Szeredi 
789334f485dSMiklos Szeredi 	if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))
790334f485dSMiklos Szeredi 		return -EINVAL;
791334f485dSMiklos Szeredi 	else if (reqsize > nbytes) {
792334f485dSMiklos Szeredi 		struct fuse_arg *lastarg = &out->args[out->numargs-1];
793334f485dSMiklos Szeredi 		unsigned diffsize = reqsize - nbytes;
794334f485dSMiklos Szeredi 		if (diffsize > lastarg->size)
795334f485dSMiklos Szeredi 			return -EINVAL;
796334f485dSMiklos Szeredi 		lastarg->size -= diffsize;
797334f485dSMiklos Szeredi 	}
798334f485dSMiklos Szeredi 	return fuse_copy_args(cs, out->numargs, out->argpages, out->args,
799334f485dSMiklos Szeredi 			      out->page_zeroing);
800334f485dSMiklos Szeredi }
801334f485dSMiklos Szeredi 
802334f485dSMiklos Szeredi /*
803334f485dSMiklos Szeredi  * Write a single reply to a request.  First the header is copied from
804334f485dSMiklos Szeredi  * the write buffer.  The request is then searched on the processing
805334f485dSMiklos Szeredi  * list by the unique ID found in the header.  If found, then remove
806334f485dSMiklos Szeredi  * it from the list and copy the rest of the buffer to the request.
807334f485dSMiklos Szeredi  * The request is finished by calling request_end()
808334f485dSMiklos Szeredi  */
809ee0b3e67SBadari Pulavarty static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
810ee0b3e67SBadari Pulavarty 			       unsigned long nr_segs, loff_t pos)
811334f485dSMiklos Szeredi {
812334f485dSMiklos Szeredi 	int err;
813334f485dSMiklos Szeredi 	unsigned nbytes = iov_length(iov, nr_segs);
814334f485dSMiklos Szeredi 	struct fuse_req *req;
815334f485dSMiklos Szeredi 	struct fuse_out_header oh;
816334f485dSMiklos Szeredi 	struct fuse_copy_state cs;
817ee0b3e67SBadari Pulavarty 	struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp);
818334f485dSMiklos Szeredi 	if (!fc)
819a87046d8SMiklos Szeredi 		return -EPERM;
820334f485dSMiklos Szeredi 
821d7133114SMiklos Szeredi 	fuse_copy_init(&cs, fc, 0, NULL, iov, nr_segs);
822334f485dSMiklos Szeredi 	if (nbytes < sizeof(struct fuse_out_header))
823334f485dSMiklos Szeredi 		return -EINVAL;
824334f485dSMiklos Szeredi 
825334f485dSMiklos Szeredi 	err = fuse_copy_one(&cs, &oh, sizeof(oh));
826334f485dSMiklos Szeredi 	if (err)
827334f485dSMiklos Szeredi 		goto err_finish;
828334f485dSMiklos Szeredi 	err = -EINVAL;
829334f485dSMiklos Szeredi 	if (!oh.unique || oh.error <= -1000 || oh.error > 0 ||
830334f485dSMiklos Szeredi 	    oh.len != nbytes)
831334f485dSMiklos Szeredi 		goto err_finish;
832334f485dSMiklos Szeredi 
833d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
83469a53bf2SMiklos Szeredi 	err = -ENOENT;
83569a53bf2SMiklos Szeredi 	if (!fc->connected)
83669a53bf2SMiklos Szeredi 		goto err_unlock;
83769a53bf2SMiklos Szeredi 
838334f485dSMiklos Szeredi 	req = request_find(fc, oh.unique);
839334f485dSMiklos Szeredi 	if (!req)
840334f485dSMiklos Szeredi 		goto err_unlock;
841334f485dSMiklos Szeredi 
842f9a2842eSMiklos Szeredi 	if (req->aborted) {
843d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
844334f485dSMiklos Szeredi 		fuse_copy_finish(&cs);
845d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
846222f1d69SMiklos Szeredi 		request_end(fc, req);
847334f485dSMiklos Szeredi 		return -ENOENT;
848334f485dSMiklos Szeredi 	}
849a4d27e75SMiklos Szeredi 	/* Is it an interrupt reply? */
850a4d27e75SMiklos Szeredi 	if (req->intr_unique == oh.unique) {
851a4d27e75SMiklos Szeredi 		err = -EINVAL;
852a4d27e75SMiklos Szeredi 		if (nbytes != sizeof(struct fuse_out_header))
853a4d27e75SMiklos Szeredi 			goto err_unlock;
854a4d27e75SMiklos Szeredi 
855a4d27e75SMiklos Szeredi 		if (oh.error == -ENOSYS)
856a4d27e75SMiklos Szeredi 			fc->no_interrupt = 1;
857a4d27e75SMiklos Szeredi 		else if (oh.error == -EAGAIN)
858a4d27e75SMiklos Szeredi 			queue_interrupt(fc, req);
859a4d27e75SMiklos Szeredi 
860a4d27e75SMiklos Szeredi 		spin_unlock(&fc->lock);
861a4d27e75SMiklos Szeredi 		fuse_copy_finish(&cs);
862a4d27e75SMiklos Szeredi 		return nbytes;
863a4d27e75SMiklos Szeredi 	}
864a4d27e75SMiklos Szeredi 
865a4d27e75SMiklos Szeredi 	req->state = FUSE_REQ_WRITING;
866d77a1d5bSMiklos Szeredi 	list_move(&req->list, &fc->io);
867334f485dSMiklos Szeredi 	req->out.h = oh;
868334f485dSMiklos Szeredi 	req->locked = 1;
869334f485dSMiklos Szeredi 	cs.req = req;
870d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
871334f485dSMiklos Szeredi 
872334f485dSMiklos Szeredi 	err = copy_out_args(&cs, &req->out, nbytes);
873334f485dSMiklos Szeredi 	fuse_copy_finish(&cs);
874334f485dSMiklos Szeredi 
875d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
876334f485dSMiklos Szeredi 	req->locked = 0;
877334f485dSMiklos Szeredi 	if (!err) {
878f9a2842eSMiklos Szeredi 		if (req->aborted)
879334f485dSMiklos Szeredi 			err = -ENOENT;
880f9a2842eSMiklos Szeredi 	} else if (!req->aborted)
881334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
882334f485dSMiklos Szeredi 	request_end(fc, req);
883334f485dSMiklos Szeredi 
884334f485dSMiklos Szeredi 	return err ? err : nbytes;
885334f485dSMiklos Szeredi 
886334f485dSMiklos Szeredi  err_unlock:
887d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
888334f485dSMiklos Szeredi  err_finish:
889334f485dSMiklos Szeredi 	fuse_copy_finish(&cs);
890334f485dSMiklos Szeredi 	return err;
891334f485dSMiklos Szeredi }
892334f485dSMiklos Szeredi 
893334f485dSMiklos Szeredi static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
894334f485dSMiklos Szeredi {
895334f485dSMiklos Szeredi 	unsigned mask = POLLOUT | POLLWRNORM;
8967025d9adSMiklos Szeredi 	struct fuse_conn *fc = fuse_get_conn(file);
897334f485dSMiklos Szeredi 	if (!fc)
8987025d9adSMiklos Szeredi 		return POLLERR;
899334f485dSMiklos Szeredi 
900334f485dSMiklos Szeredi 	poll_wait(file, &fc->waitq, wait);
901334f485dSMiklos Szeredi 
902d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
9037025d9adSMiklos Szeredi 	if (!fc->connected)
9047025d9adSMiklos Szeredi 		mask = POLLERR;
905a4d27e75SMiklos Szeredi 	else if (request_pending(fc))
906334f485dSMiklos Szeredi 		mask |= POLLIN | POLLRDNORM;
907d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
908334f485dSMiklos Szeredi 
909334f485dSMiklos Szeredi 	return mask;
910334f485dSMiklos Szeredi }
911334f485dSMiklos Szeredi 
91269a53bf2SMiklos Szeredi /*
91369a53bf2SMiklos Szeredi  * Abort all requests on the given list (pending or processing)
91469a53bf2SMiklos Szeredi  *
915d7133114SMiklos Szeredi  * This function releases and reacquires fc->lock
91669a53bf2SMiklos Szeredi  */
917334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head)
918334f485dSMiklos Szeredi {
919334f485dSMiklos Szeredi 	while (!list_empty(head)) {
920334f485dSMiklos Szeredi 		struct fuse_req *req;
921334f485dSMiklos Szeredi 		req = list_entry(head->next, struct fuse_req, list);
922334f485dSMiklos Szeredi 		req->out.h.error = -ECONNABORTED;
923334f485dSMiklos Szeredi 		request_end(fc, req);
924d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
925334f485dSMiklos Szeredi 	}
926334f485dSMiklos Szeredi }
927334f485dSMiklos Szeredi 
92869a53bf2SMiklos Szeredi /*
92969a53bf2SMiklos Szeredi  * Abort requests under I/O
93069a53bf2SMiklos Szeredi  *
931f9a2842eSMiklos Szeredi  * The requests are set to aborted and finished, and the request
93269a53bf2SMiklos Szeredi  * waiter is woken up.  This will make request_wait_answer() wait
93369a53bf2SMiklos Szeredi  * until the request is unlocked and then return.
93464c6d8edSMiklos Szeredi  *
93564c6d8edSMiklos Szeredi  * If the request is asynchronous, then the end function needs to be
93664c6d8edSMiklos Szeredi  * called after waiting for the request to be unlocked (if it was
93764c6d8edSMiklos Szeredi  * locked).
93869a53bf2SMiklos Szeredi  */
93969a53bf2SMiklos Szeredi static void end_io_requests(struct fuse_conn *fc)
94069a53bf2SMiklos Szeredi {
94169a53bf2SMiklos Szeredi 	while (!list_empty(&fc->io)) {
94264c6d8edSMiklos Szeredi 		struct fuse_req *req =
94364c6d8edSMiklos Szeredi 			list_entry(fc->io.next, struct fuse_req, list);
94464c6d8edSMiklos Szeredi 		void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
94564c6d8edSMiklos Szeredi 
946f9a2842eSMiklos Szeredi 		req->aborted = 1;
94769a53bf2SMiklos Szeredi 		req->out.h.error = -ECONNABORTED;
94869a53bf2SMiklos Szeredi 		req->state = FUSE_REQ_FINISHED;
94969a53bf2SMiklos Szeredi 		list_del_init(&req->list);
95069a53bf2SMiklos Szeredi 		wake_up(&req->waitq);
95164c6d8edSMiklos Szeredi 		if (end) {
95264c6d8edSMiklos Szeredi 			req->end = NULL;
95364c6d8edSMiklos Szeredi 			/* The end function will consume this reference */
95464c6d8edSMiklos Szeredi 			__fuse_get_request(req);
955d7133114SMiklos Szeredi 			spin_unlock(&fc->lock);
95664c6d8edSMiklos Szeredi 			wait_event(req->waitq, !req->locked);
95764c6d8edSMiklos Szeredi 			end(fc, req);
958d7133114SMiklos Szeredi 			spin_lock(&fc->lock);
95964c6d8edSMiklos Szeredi 		}
96069a53bf2SMiklos Szeredi 	}
96169a53bf2SMiklos Szeredi }
96269a53bf2SMiklos Szeredi 
96369a53bf2SMiklos Szeredi /*
96469a53bf2SMiklos Szeredi  * Abort all requests.
96569a53bf2SMiklos Szeredi  *
96669a53bf2SMiklos Szeredi  * Emergency exit in case of a malicious or accidental deadlock, or
96769a53bf2SMiklos Szeredi  * just a hung filesystem.
96869a53bf2SMiklos Szeredi  *
96969a53bf2SMiklos Szeredi  * The same effect is usually achievable through killing the
97069a53bf2SMiklos Szeredi  * filesystem daemon and all users of the filesystem.  The exception
97169a53bf2SMiklos Szeredi  * is the combination of an asynchronous request and the tricky
97269a53bf2SMiklos Szeredi  * deadlock (see Documentation/filesystems/fuse.txt).
97369a53bf2SMiklos Szeredi  *
97469a53bf2SMiklos Szeredi  * During the aborting, progression of requests from the pending and
97569a53bf2SMiklos Szeredi  * processing lists onto the io list, and progression of new requests
97669a53bf2SMiklos Szeredi  * onto the pending list is prevented by req->connected being false.
97769a53bf2SMiklos Szeredi  *
97869a53bf2SMiklos Szeredi  * Progression of requests under I/O to the processing list is
979f9a2842eSMiklos Szeredi  * prevented by the req->aborted flag being true for these requests.
980f9a2842eSMiklos Szeredi  * For this reason requests on the io list must be aborted first.
98169a53bf2SMiklos Szeredi  */
98269a53bf2SMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc)
98369a53bf2SMiklos Szeredi {
984d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
98569a53bf2SMiklos Szeredi 	if (fc->connected) {
98669a53bf2SMiklos Szeredi 		fc->connected = 0;
98751eb01e7SMiklos Szeredi 		fc->blocked = 0;
98869a53bf2SMiklos Szeredi 		end_io_requests(fc);
98969a53bf2SMiklos Szeredi 		end_requests(fc, &fc->pending);
99069a53bf2SMiklos Szeredi 		end_requests(fc, &fc->processing);
99169a53bf2SMiklos Szeredi 		wake_up_all(&fc->waitq);
99251eb01e7SMiklos Szeredi 		wake_up_all(&fc->blocked_waitq);
993385a17bfSJeff Dike 		kill_fasync(&fc->fasync, SIGIO, POLL_IN);
99469a53bf2SMiklos Szeredi 	}
995d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
99669a53bf2SMiklos Szeredi }
99769a53bf2SMiklos Szeredi 
998334f485dSMiklos Szeredi static int fuse_dev_release(struct inode *inode, struct file *file)
999334f485dSMiklos Szeredi {
10000720b315SMiklos Szeredi 	struct fuse_conn *fc = fuse_get_conn(file);
1001334f485dSMiklos Szeredi 	if (fc) {
1002d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
10031e9a4ed9SMiklos Szeredi 		fc->connected = 0;
1004334f485dSMiklos Szeredi 		end_requests(fc, &fc->pending);
1005334f485dSMiklos Szeredi 		end_requests(fc, &fc->processing);
1006d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
1007385a17bfSJeff Dike 		fasync_helper(-1, file, 0, &fc->fasync);
1008bafa9654SMiklos Szeredi 		fuse_conn_put(fc);
1009385a17bfSJeff Dike 	}
1010f543f253SMiklos Szeredi 
1011334f485dSMiklos Szeredi 	return 0;
1012334f485dSMiklos Szeredi }
1013334f485dSMiklos Szeredi 
1014385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on)
1015385a17bfSJeff Dike {
1016385a17bfSJeff Dike 	struct fuse_conn *fc = fuse_get_conn(file);
1017385a17bfSJeff Dike 	if (!fc)
1018a87046d8SMiklos Szeredi 		return -EPERM;
1019385a17bfSJeff Dike 
1020385a17bfSJeff Dike 	/* No locking - fasync_helper does its own locking */
1021385a17bfSJeff Dike 	return fasync_helper(fd, file, on, &fc->fasync);
1022385a17bfSJeff Dike }
1023385a17bfSJeff Dike 
10244b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = {
1025334f485dSMiklos Szeredi 	.owner		= THIS_MODULE,
1026334f485dSMiklos Szeredi 	.llseek		= no_llseek,
1027ee0b3e67SBadari Pulavarty 	.read		= do_sync_read,
1028ee0b3e67SBadari Pulavarty 	.aio_read	= fuse_dev_read,
1029ee0b3e67SBadari Pulavarty 	.write		= do_sync_write,
1030ee0b3e67SBadari Pulavarty 	.aio_write	= fuse_dev_write,
1031334f485dSMiklos Szeredi 	.poll		= fuse_dev_poll,
1032334f485dSMiklos Szeredi 	.release	= fuse_dev_release,
1033385a17bfSJeff Dike 	.fasync		= fuse_dev_fasync,
1034334f485dSMiklos Szeredi };
1035334f485dSMiklos Szeredi 
1036334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = {
1037334f485dSMiklos Szeredi 	.minor = FUSE_MINOR,
1038334f485dSMiklos Szeredi 	.name  = "fuse",
1039334f485dSMiklos Szeredi 	.fops = &fuse_dev_operations,
1040334f485dSMiklos Szeredi };
1041334f485dSMiklos Szeredi 
1042334f485dSMiklos Szeredi int __init fuse_dev_init(void)
1043334f485dSMiklos Szeredi {
1044334f485dSMiklos Szeredi 	int err = -ENOMEM;
1045334f485dSMiklos Szeredi 	fuse_req_cachep = kmem_cache_create("fuse_request",
1046334f485dSMiklos Szeredi 					    sizeof(struct fuse_req),
1047334f485dSMiklos Szeredi 					    0, 0, NULL, NULL);
1048334f485dSMiklos Szeredi 	if (!fuse_req_cachep)
1049334f485dSMiklos Szeredi 		goto out;
1050334f485dSMiklos Szeredi 
1051334f485dSMiklos Szeredi 	err = misc_register(&fuse_miscdevice);
1052334f485dSMiklos Szeredi 	if (err)
1053334f485dSMiklos Szeredi 		goto out_cache_clean;
1054334f485dSMiklos Szeredi 
1055334f485dSMiklos Szeredi 	return 0;
1056334f485dSMiklos Szeredi 
1057334f485dSMiklos Szeredi  out_cache_clean:
1058334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
1059334f485dSMiklos Szeredi  out:
1060334f485dSMiklos Szeredi 	return err;
1061334f485dSMiklos Szeredi }
1062334f485dSMiklos Szeredi 
1063334f485dSMiklos Szeredi void fuse_dev_cleanup(void)
1064334f485dSMiklos Szeredi {
1065334f485dSMiklos Szeredi 	misc_deregister(&fuse_miscdevice);
1066334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
1067334f485dSMiklos Szeredi }
1068