xref: /openbmc/linux/fs/fuse/dev.c (revision d7133114)
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);
37334f485dSMiklos Szeredi 	init_waitqueue_head(&req->waitq);
38334f485dSMiklos Szeredi 	atomic_set(&req->count, 1);
39334f485dSMiklos Szeredi }
40334f485dSMiklos Szeredi 
41334f485dSMiklos Szeredi struct fuse_req *fuse_request_alloc(void)
42334f485dSMiklos Szeredi {
43334f485dSMiklos Szeredi 	struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, SLAB_KERNEL);
44334f485dSMiklos Szeredi 	if (req)
45334f485dSMiklos Szeredi 		fuse_request_init(req);
46334f485dSMiklos Szeredi 	return req;
47334f485dSMiklos Szeredi }
48334f485dSMiklos Szeredi 
49334f485dSMiklos Szeredi void fuse_request_free(struct fuse_req *req)
50334f485dSMiklos Szeredi {
51334f485dSMiklos Szeredi 	kmem_cache_free(fuse_req_cachep, req);
52334f485dSMiklos Szeredi }
53334f485dSMiklos Szeredi 
548bfc016dSMiklos Szeredi static void block_sigs(sigset_t *oldset)
55334f485dSMiklos Szeredi {
56334f485dSMiklos Szeredi 	sigset_t mask;
57334f485dSMiklos Szeredi 
58334f485dSMiklos Szeredi 	siginitsetinv(&mask, sigmask(SIGKILL));
59334f485dSMiklos Szeredi 	sigprocmask(SIG_BLOCK, &mask, oldset);
60334f485dSMiklos Szeredi }
61334f485dSMiklos Szeredi 
628bfc016dSMiklos Szeredi static void restore_sigs(sigset_t *oldset)
63334f485dSMiklos Szeredi {
64334f485dSMiklos Szeredi 	sigprocmask(SIG_SETMASK, oldset, NULL);
65334f485dSMiklos Szeredi }
66334f485dSMiklos Szeredi 
6777e7f250SMiklos Szeredi /*
6877e7f250SMiklos Szeredi  * Reset request, so that it can be reused
6977e7f250SMiklos Szeredi  *
7077e7f250SMiklos Szeredi  * The caller must be _very_ careful to make sure, that it is holding
7177e7f250SMiklos Szeredi  * the only reference to req
7277e7f250SMiklos Szeredi  */
73334f485dSMiklos Szeredi void fuse_reset_request(struct fuse_req *req)
74334f485dSMiklos Szeredi {
75334f485dSMiklos Szeredi 	int preallocated = req->preallocated;
76334f485dSMiklos Szeredi 	BUG_ON(atomic_read(&req->count) != 1);
77334f485dSMiklos Szeredi 	fuse_request_init(req);
78334f485dSMiklos Szeredi 	req->preallocated = preallocated;
79334f485dSMiklos Szeredi }
80334f485dSMiklos Szeredi 
81334f485dSMiklos Szeredi static void __fuse_get_request(struct fuse_req *req)
82334f485dSMiklos Szeredi {
83334f485dSMiklos Szeredi 	atomic_inc(&req->count);
84334f485dSMiklos Szeredi }
85334f485dSMiklos Szeredi 
86334f485dSMiklos Szeredi /* Must be called with > 1 refcount */
87334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req)
88334f485dSMiklos Szeredi {
89334f485dSMiklos Szeredi 	BUG_ON(atomic_read(&req->count) < 2);
90334f485dSMiklos Szeredi 	atomic_dec(&req->count);
91334f485dSMiklos Szeredi }
92334f485dSMiklos Szeredi 
93334f485dSMiklos Szeredi static struct fuse_req *do_get_request(struct fuse_conn *fc)
94334f485dSMiklos Szeredi {
95334f485dSMiklos Szeredi 	struct fuse_req *req;
96334f485dSMiklos Szeredi 
97d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
98334f485dSMiklos Szeredi 	BUG_ON(list_empty(&fc->unused_list));
99334f485dSMiklos Szeredi 	req = list_entry(fc->unused_list.next, struct fuse_req, list);
100334f485dSMiklos Szeredi 	list_del_init(&req->list);
101d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
102334f485dSMiklos Szeredi 	fuse_request_init(req);
103334f485dSMiklos Szeredi 	req->preallocated = 1;
104334f485dSMiklos Szeredi 	req->in.h.uid = current->fsuid;
105334f485dSMiklos Szeredi 	req->in.h.gid = current->fsgid;
106334f485dSMiklos Szeredi 	req->in.h.pid = current->pid;
107334f485dSMiklos Szeredi 	return req;
108334f485dSMiklos Szeredi }
109334f485dSMiklos Szeredi 
1107c352bdfSMiklos Szeredi /* This can return NULL, but only in case it's interrupted by a SIGKILL */
111334f485dSMiklos Szeredi struct fuse_req *fuse_get_request(struct fuse_conn *fc)
112334f485dSMiklos Szeredi {
113334f485dSMiklos Szeredi 	int intr;
114334f485dSMiklos Szeredi 	sigset_t oldset;
115334f485dSMiklos Szeredi 
1160cd5b885SMiklos Szeredi 	atomic_inc(&fc->num_waiting);
117334f485dSMiklos Szeredi 	block_sigs(&oldset);
118334f485dSMiklos Szeredi 	intr = down_interruptible(&fc->outstanding_sem);
119334f485dSMiklos Szeredi 	restore_sigs(&oldset);
1200cd5b885SMiklos Szeredi 	if (intr) {
1210cd5b885SMiklos Szeredi 		atomic_dec(&fc->num_waiting);
1220cd5b885SMiklos Szeredi 		return NULL;
1230cd5b885SMiklos Szeredi 	}
1240cd5b885SMiklos Szeredi 	return do_get_request(fc);
125334f485dSMiklos Szeredi }
126334f485dSMiklos Szeredi 
127d7133114SMiklos Szeredi /* Must be called with fc->lock held */
128334f485dSMiklos Szeredi static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req)
129334f485dSMiklos Szeredi {
1300cd5b885SMiklos Szeredi 	if (req->preallocated) {
1310cd5b885SMiklos Szeredi 		atomic_dec(&fc->num_waiting);
132334f485dSMiklos Szeredi 		list_add(&req->list, &fc->unused_list);
1330cd5b885SMiklos Szeredi 	} else
134334f485dSMiklos Szeredi 		fuse_request_free(req);
135334f485dSMiklos Szeredi 
136334f485dSMiklos Szeredi 	/* If we are in debt decrease that first */
137334f485dSMiklos Szeredi 	if (fc->outstanding_debt)
138334f485dSMiklos Szeredi 		fc->outstanding_debt--;
139334f485dSMiklos Szeredi 	else
140334f485dSMiklos Szeredi 		up(&fc->outstanding_sem);
141334f485dSMiklos Szeredi }
142334f485dSMiklos Szeredi 
143334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
144334f485dSMiklos Szeredi {
1457128ec2aSMiklos Szeredi 	if (atomic_dec_and_test(&req->count)) {
146d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
1477128ec2aSMiklos Szeredi 		fuse_putback_request(fc, req);
148d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
1497128ec2aSMiklos Szeredi 	}
1507128ec2aSMiklos Szeredi }
1517128ec2aSMiklos Szeredi 
1527128ec2aSMiklos Szeredi static void fuse_put_request_locked(struct fuse_conn *fc, struct fuse_req *req)
1537128ec2aSMiklos Szeredi {
154334f485dSMiklos Szeredi 	if (atomic_dec_and_test(&req->count))
155334f485dSMiklos Szeredi 		fuse_putback_request(fc, req);
156334f485dSMiklos Szeredi }
157334f485dSMiklos Szeredi 
158d7133114SMiklos Szeredi void fuse_release_background(struct fuse_conn *fc, struct fuse_req *req)
1591e9a4ed9SMiklos Szeredi {
1601e9a4ed9SMiklos Szeredi 	iput(req->inode);
1611e9a4ed9SMiklos Szeredi 	iput(req->inode2);
1621e9a4ed9SMiklos Szeredi 	if (req->file)
1631e9a4ed9SMiklos Szeredi 		fput(req->file);
164d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
1651e9a4ed9SMiklos Szeredi 	list_del(&req->bg_entry);
166d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
1671e9a4ed9SMiklos Szeredi }
1681e9a4ed9SMiklos Szeredi 
169334f485dSMiklos Szeredi /*
170334f485dSMiklos Szeredi  * This function is called when a request is finished.  Either a reply
171334f485dSMiklos Szeredi  * has arrived or it was interrupted (and not yet sent) or some error
172f43b155aSMiklos Szeredi  * occurred during communication with userspace, or the device file
173f43b155aSMiklos Szeredi  * was closed.  In case of a background request the reference to the
174f43b155aSMiklos Szeredi  * stored objects are released.  The requester thread is woken up (if
17564c6d8edSMiklos Szeredi  * still waiting), the 'end' callback is called if given, else the
17664c6d8edSMiklos Szeredi  * reference to the request is released
177334f485dSMiklos Szeredi  *
1787128ec2aSMiklos Szeredi  * Releasing extra reference for foreground requests must be done
1797128ec2aSMiklos Szeredi  * within the same locked region as setting state to finished.  This
1807128ec2aSMiklos Szeredi  * is because fuse_reset_request() may be called after request is
1817128ec2aSMiklos Szeredi  * finished and it must be the sole possessor.  If request is
1827128ec2aSMiklos Szeredi  * interrupted and put in the background, it will return with an error
1837128ec2aSMiklos Szeredi  * and hence never be reset and reused.
1847128ec2aSMiklos Szeredi  *
185d7133114SMiklos Szeredi  * Called with fc->lock, unlocks it
186334f485dSMiklos Szeredi  */
187334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req)
188334f485dSMiklos Szeredi {
189d77a1d5bSMiklos Szeredi 	list_del(&req->list);
19083cfd493SMiklos Szeredi 	req->state = FUSE_REQ_FINISHED;
1917128ec2aSMiklos Szeredi 	if (!req->background) {
1927128ec2aSMiklos Szeredi 		wake_up(&req->waitq);
1937128ec2aSMiklos Szeredi 		fuse_put_request_locked(fc, req);
194d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
1957128ec2aSMiklos Szeredi 	} else {
1967128ec2aSMiklos Szeredi 		void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
1977128ec2aSMiklos Szeredi 		req->end = NULL;
198d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
1991e9a4ed9SMiklos Szeredi 		down_read(&fc->sbput_sem);
2001e9a4ed9SMiklos Szeredi 		if (fc->mounted)
201d7133114SMiklos Szeredi 			fuse_release_background(fc, req);
2021e9a4ed9SMiklos Szeredi 		up_read(&fc->sbput_sem);
20364c6d8edSMiklos Szeredi 		if (end)
20464c6d8edSMiklos Szeredi 			end(fc, req);
20564c6d8edSMiklos Szeredi 		else
206f43b155aSMiklos Szeredi 			fuse_put_request(fc, req);
207334f485dSMiklos Szeredi 	}
2087128ec2aSMiklos Szeredi }
209334f485dSMiklos Szeredi 
2101e9a4ed9SMiklos Szeredi /*
2111e9a4ed9SMiklos Szeredi  * Unfortunately request interruption not just solves the deadlock
2121e9a4ed9SMiklos Szeredi  * problem, it causes problems too.  These stem from the fact, that an
2131e9a4ed9SMiklos Szeredi  * interrupted request is continued to be processed in userspace,
2141e9a4ed9SMiklos Szeredi  * while all the locks and object references (inode and file) held
2151e9a4ed9SMiklos Szeredi  * during the operation are released.
2161e9a4ed9SMiklos Szeredi  *
2171e9a4ed9SMiklos Szeredi  * To release the locks is exactly why there's a need to interrupt the
2181e9a4ed9SMiklos Szeredi  * request, so there's not a lot that can be done about this, except
2191e9a4ed9SMiklos Szeredi  * introduce additional locking in userspace.
2201e9a4ed9SMiklos Szeredi  *
2211e9a4ed9SMiklos Szeredi  * More important is to keep inode and file references until userspace
2221e9a4ed9SMiklos Szeredi  * has replied, otherwise FORGET and RELEASE could be sent while the
2231e9a4ed9SMiklos Szeredi  * inode/file is still used by the filesystem.
2241e9a4ed9SMiklos Szeredi  *
2251e9a4ed9SMiklos Szeredi  * For this reason the concept of "background" request is introduced.
2261e9a4ed9SMiklos Szeredi  * An interrupted request is backgrounded if it has been already sent
2271e9a4ed9SMiklos Szeredi  * to userspace.  Backgrounding involves getting an extra reference to
2281e9a4ed9SMiklos Szeredi  * inode(s) or file used in the request, and adding the request to
2291e9a4ed9SMiklos Szeredi  * fc->background list.  When a reply is received for a background
2301e9a4ed9SMiklos Szeredi  * request, the object references are released, and the request is
2311e9a4ed9SMiklos Szeredi  * removed from the list.  If the filesystem is unmounted while there
2321e9a4ed9SMiklos Szeredi  * are still background requests, the list is walked and references
2331e9a4ed9SMiklos Szeredi  * are released as if a reply was received.
2341e9a4ed9SMiklos Szeredi  *
2351e9a4ed9SMiklos Szeredi  * There's one more use for a background request.  The RELEASE message is
2361e9a4ed9SMiklos Szeredi  * always sent as background, since it doesn't return an error or
2371e9a4ed9SMiklos Szeredi  * data.
2381e9a4ed9SMiklos Szeredi  */
2391e9a4ed9SMiklos Szeredi static void background_request(struct fuse_conn *fc, struct fuse_req *req)
240334f485dSMiklos Szeredi {
241334f485dSMiklos Szeredi 	req->background = 1;
2421e9a4ed9SMiklos Szeredi 	list_add(&req->bg_entry, &fc->background);
243334f485dSMiklos Szeredi 	if (req->inode)
244334f485dSMiklos Szeredi 		req->inode = igrab(req->inode);
245334f485dSMiklos Szeredi 	if (req->inode2)
246334f485dSMiklos Szeredi 		req->inode2 = igrab(req->inode2);
247334f485dSMiklos Szeredi 	if (req->file)
248334f485dSMiklos Szeredi 		get_file(req->file);
249334f485dSMiklos Szeredi }
250334f485dSMiklos Szeredi 
251d7133114SMiklos Szeredi /* Called with fc->lock held.  Releases, and then reacquires it. */
2527c352bdfSMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
253334f485dSMiklos Szeredi {
2547c352bdfSMiklos Szeredi 	sigset_t oldset;
255334f485dSMiklos Szeredi 
256d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
2577c352bdfSMiklos Szeredi 	block_sigs(&oldset);
25883cfd493SMiklos Szeredi 	wait_event_interruptible(req->waitq, req->state == FUSE_REQ_FINISHED);
2597c352bdfSMiklos Szeredi 	restore_sigs(&oldset);
260d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
26169a53bf2SMiklos Szeredi 	if (req->state == FUSE_REQ_FINISHED && !req->interrupted)
262334f485dSMiklos Szeredi 		return;
263334f485dSMiklos Szeredi 
26469a53bf2SMiklos Szeredi 	if (!req->interrupted) {
265334f485dSMiklos Szeredi 		req->out.h.error = -EINTR;
266334f485dSMiklos Szeredi 		req->interrupted = 1;
26769a53bf2SMiklos Szeredi 	}
268334f485dSMiklos Szeredi 	if (req->locked) {
269334f485dSMiklos Szeredi 		/* This is uninterruptible sleep, because data is
270334f485dSMiklos Szeredi 		   being copied to/from the buffers of req.  During
271334f485dSMiklos Szeredi 		   locked state, there mustn't be any filesystem
272334f485dSMiklos Szeredi 		   operation (e.g. page fault), since that could lead
273334f485dSMiklos Szeredi 		   to deadlock */
274d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
275334f485dSMiklos Szeredi 		wait_event(req->waitq, !req->locked);
276d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
277334f485dSMiklos Szeredi 	}
27883cfd493SMiklos Szeredi 	if (req->state == FUSE_REQ_PENDING) {
279334f485dSMiklos Szeredi 		list_del(&req->list);
280334f485dSMiklos Szeredi 		__fuse_put_request(req);
28183cfd493SMiklos Szeredi 	} else if (req->state == FUSE_REQ_SENT)
2821e9a4ed9SMiklos Szeredi 		background_request(fc, req);
283334f485dSMiklos Szeredi }
284334f485dSMiklos Szeredi 
285334f485dSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args)
286334f485dSMiklos Szeredi {
287334f485dSMiklos Szeredi 	unsigned nbytes = 0;
288334f485dSMiklos Szeredi 	unsigned i;
289334f485dSMiklos Szeredi 
290334f485dSMiklos Szeredi 	for (i = 0; i < numargs; i++)
291334f485dSMiklos Szeredi 		nbytes += args[i].size;
292334f485dSMiklos Szeredi 
293334f485dSMiklos Szeredi 	return nbytes;
294334f485dSMiklos Szeredi }
295334f485dSMiklos Szeredi 
296334f485dSMiklos Szeredi static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
297334f485dSMiklos Szeredi {
298334f485dSMiklos Szeredi 	fc->reqctr++;
299334f485dSMiklos Szeredi 	/* zero is special */
300334f485dSMiklos Szeredi 	if (fc->reqctr == 0)
301334f485dSMiklos Szeredi 		fc->reqctr = 1;
302334f485dSMiklos Szeredi 	req->in.h.unique = fc->reqctr;
303334f485dSMiklos Szeredi 	req->in.h.len = sizeof(struct fuse_in_header) +
304334f485dSMiklos Szeredi 		len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
305334f485dSMiklos Szeredi 	if (!req->preallocated) {
306334f485dSMiklos Szeredi 		/* If request is not preallocated (either FORGET or
307334f485dSMiklos Szeredi 		   RELEASE), then still decrease outstanding_sem, so
308334f485dSMiklos Szeredi 		   user can't open infinite number of files while not
309334f485dSMiklos Szeredi 		   processing the RELEASE requests.  However for
310334f485dSMiklos Szeredi 		   efficiency do it without blocking, so if down()
311334f485dSMiklos Szeredi 		   would block, just increase the debt instead */
312334f485dSMiklos Szeredi 		if (down_trylock(&fc->outstanding_sem))
313334f485dSMiklos Szeredi 			fc->outstanding_debt++;
314334f485dSMiklos Szeredi 	}
315334f485dSMiklos Szeredi 	list_add_tail(&req->list, &fc->pending);
31683cfd493SMiklos Szeredi 	req->state = FUSE_REQ_PENDING;
317334f485dSMiklos Szeredi 	wake_up(&fc->waitq);
318385a17bfSJeff Dike 	kill_fasync(&fc->fasync, SIGIO, POLL_IN);
319334f485dSMiklos Szeredi }
320334f485dSMiklos Szeredi 
3217c352bdfSMiklos Szeredi /*
3227c352bdfSMiklos Szeredi  * This can only be interrupted by a SIGKILL
3237c352bdfSMiklos Szeredi  */
3247c352bdfSMiklos Szeredi void request_send(struct fuse_conn *fc, struct fuse_req *req)
325334f485dSMiklos Szeredi {
326334f485dSMiklos Szeredi 	req->isreply = 1;
327d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
3281e9a4ed9SMiklos Szeredi 	if (!fc->connected)
329334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
330334f485dSMiklos Szeredi 	else if (fc->conn_error)
331334f485dSMiklos Szeredi 		req->out.h.error = -ECONNREFUSED;
332334f485dSMiklos Szeredi 	else {
333334f485dSMiklos Szeredi 		queue_request(fc, req);
334334f485dSMiklos Szeredi 		/* acquire extra reference, since request is still needed
335334f485dSMiklos Szeredi 		   after request_end() */
336334f485dSMiklos Szeredi 		__fuse_get_request(req);
337334f485dSMiklos Szeredi 
3387c352bdfSMiklos Szeredi 		request_wait_answer(fc, req);
339334f485dSMiklos Szeredi 	}
340d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
341334f485dSMiklos Szeredi }
342334f485dSMiklos Szeredi 
343334f485dSMiklos Szeredi static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
344334f485dSMiklos Szeredi {
345d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
3461e9a4ed9SMiklos Szeredi 	if (fc->connected) {
347334f485dSMiklos Szeredi 		queue_request(fc, req);
348d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
349334f485dSMiklos Szeredi 	} else {
350334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
351334f485dSMiklos Szeredi 		request_end(fc, req);
352334f485dSMiklos Szeredi 	}
353334f485dSMiklos Szeredi }
354334f485dSMiklos Szeredi 
355334f485dSMiklos Szeredi void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req)
356334f485dSMiklos Szeredi {
357334f485dSMiklos Szeredi 	req->isreply = 0;
358334f485dSMiklos Szeredi 	request_send_nowait(fc, req);
359334f485dSMiklos Szeredi }
360334f485dSMiklos Szeredi 
361334f485dSMiklos Szeredi void request_send_background(struct fuse_conn *fc, struct fuse_req *req)
362334f485dSMiklos Szeredi {
363334f485dSMiklos Szeredi 	req->isreply = 1;
364d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
3651e9a4ed9SMiklos Szeredi 	background_request(fc, req);
366d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
367334f485dSMiklos Szeredi 	request_send_nowait(fc, req);
368334f485dSMiklos Szeredi }
369334f485dSMiklos Szeredi 
370334f485dSMiklos Szeredi /*
371334f485dSMiklos Szeredi  * Lock the request.  Up to the next unlock_request() there mustn't be
372334f485dSMiklos Szeredi  * anything that could cause a page-fault.  If the request was already
373334f485dSMiklos Szeredi  * interrupted bail out.
374334f485dSMiklos Szeredi  */
375d7133114SMiklos Szeredi static int lock_request(struct fuse_conn *fc, struct fuse_req *req)
376334f485dSMiklos Szeredi {
377334f485dSMiklos Szeredi 	int err = 0;
378334f485dSMiklos Szeredi 	if (req) {
379d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
380334f485dSMiklos Szeredi 		if (req->interrupted)
381334f485dSMiklos Szeredi 			err = -ENOENT;
382334f485dSMiklos Szeredi 		else
383334f485dSMiklos Szeredi 			req->locked = 1;
384d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
385334f485dSMiklos Szeredi 	}
386334f485dSMiklos Szeredi 	return err;
387334f485dSMiklos Szeredi }
388334f485dSMiklos Szeredi 
389334f485dSMiklos Szeredi /*
390334f485dSMiklos Szeredi  * Unlock request.  If it was interrupted during being locked, the
391334f485dSMiklos Szeredi  * requester thread is currently waiting for it to be unlocked, so
392334f485dSMiklos Szeredi  * wake it up.
393334f485dSMiklos Szeredi  */
394d7133114SMiklos Szeredi static void unlock_request(struct fuse_conn *fc, struct fuse_req *req)
395334f485dSMiklos Szeredi {
396334f485dSMiklos Szeredi 	if (req) {
397d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
398334f485dSMiklos Szeredi 		req->locked = 0;
399334f485dSMiklos Szeredi 		if (req->interrupted)
400334f485dSMiklos Szeredi 			wake_up(&req->waitq);
401d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
402334f485dSMiklos Szeredi 	}
403334f485dSMiklos Szeredi }
404334f485dSMiklos Szeredi 
405334f485dSMiklos Szeredi struct fuse_copy_state {
406d7133114SMiklos Szeredi 	struct fuse_conn *fc;
407334f485dSMiklos Szeredi 	int write;
408334f485dSMiklos Szeredi 	struct fuse_req *req;
409334f485dSMiklos Szeredi 	const struct iovec *iov;
410334f485dSMiklos Szeredi 	unsigned long nr_segs;
411334f485dSMiklos Szeredi 	unsigned long seglen;
412334f485dSMiklos Szeredi 	unsigned long addr;
413334f485dSMiklos Szeredi 	struct page *pg;
414334f485dSMiklos Szeredi 	void *mapaddr;
415334f485dSMiklos Szeredi 	void *buf;
416334f485dSMiklos Szeredi 	unsigned len;
417334f485dSMiklos Szeredi };
418334f485dSMiklos Szeredi 
419d7133114SMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, struct fuse_conn *fc,
420d7133114SMiklos Szeredi 			   int write, struct fuse_req *req,
421d7133114SMiklos Szeredi 			   const struct iovec *iov, unsigned long nr_segs)
422334f485dSMiklos Szeredi {
423334f485dSMiklos Szeredi 	memset(cs, 0, sizeof(*cs));
424d7133114SMiklos Szeredi 	cs->fc = fc;
425334f485dSMiklos Szeredi 	cs->write = write;
426334f485dSMiklos Szeredi 	cs->req = req;
427334f485dSMiklos Szeredi 	cs->iov = iov;
428334f485dSMiklos Szeredi 	cs->nr_segs = nr_segs;
429334f485dSMiklos Szeredi }
430334f485dSMiklos Szeredi 
431334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */
4328bfc016dSMiklos Szeredi static void fuse_copy_finish(struct fuse_copy_state *cs)
433334f485dSMiklos Szeredi {
434334f485dSMiklos Szeredi 	if (cs->mapaddr) {
435334f485dSMiklos Szeredi 		kunmap_atomic(cs->mapaddr, KM_USER0);
436334f485dSMiklos Szeredi 		if (cs->write) {
437334f485dSMiklos Szeredi 			flush_dcache_page(cs->pg);
438334f485dSMiklos Szeredi 			set_page_dirty_lock(cs->pg);
439334f485dSMiklos Szeredi 		}
440334f485dSMiklos Szeredi 		put_page(cs->pg);
441334f485dSMiklos Szeredi 		cs->mapaddr = NULL;
442334f485dSMiklos Szeredi 	}
443334f485dSMiklos Szeredi }
444334f485dSMiklos Szeredi 
445334f485dSMiklos Szeredi /*
446334f485dSMiklos Szeredi  * Get another pagefull of userspace buffer, and map it to kernel
447334f485dSMiklos Szeredi  * address space, and lock request
448334f485dSMiklos Szeredi  */
449334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs)
450334f485dSMiklos Szeredi {
451334f485dSMiklos Szeredi 	unsigned long offset;
452334f485dSMiklos Szeredi 	int err;
453334f485dSMiklos Szeredi 
454d7133114SMiklos Szeredi 	unlock_request(cs->fc, cs->req);
455334f485dSMiklos Szeredi 	fuse_copy_finish(cs);
456334f485dSMiklos Szeredi 	if (!cs->seglen) {
457334f485dSMiklos Szeredi 		BUG_ON(!cs->nr_segs);
458334f485dSMiklos Szeredi 		cs->seglen = cs->iov[0].iov_len;
459334f485dSMiklos Szeredi 		cs->addr = (unsigned long) cs->iov[0].iov_base;
460334f485dSMiklos Szeredi 		cs->iov ++;
461334f485dSMiklos Szeredi 		cs->nr_segs --;
462334f485dSMiklos Szeredi 	}
463334f485dSMiklos Szeredi 	down_read(&current->mm->mmap_sem);
464334f485dSMiklos Szeredi 	err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
465334f485dSMiklos Szeredi 			     &cs->pg, NULL);
466334f485dSMiklos Szeredi 	up_read(&current->mm->mmap_sem);
467334f485dSMiklos Szeredi 	if (err < 0)
468334f485dSMiklos Szeredi 		return err;
469334f485dSMiklos Szeredi 	BUG_ON(err != 1);
470334f485dSMiklos Szeredi 	offset = cs->addr % PAGE_SIZE;
471334f485dSMiklos Szeredi 	cs->mapaddr = kmap_atomic(cs->pg, KM_USER0);
472334f485dSMiklos Szeredi 	cs->buf = cs->mapaddr + offset;
473334f485dSMiklos Szeredi 	cs->len = min(PAGE_SIZE - offset, cs->seglen);
474334f485dSMiklos Szeredi 	cs->seglen -= cs->len;
475334f485dSMiklos Szeredi 	cs->addr += cs->len;
476334f485dSMiklos Szeredi 
477d7133114SMiklos Szeredi 	return lock_request(cs->fc, cs->req);
478334f485dSMiklos Szeredi }
479334f485dSMiklos Szeredi 
480334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */
4818bfc016dSMiklos Szeredi static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
482334f485dSMiklos Szeredi {
483334f485dSMiklos Szeredi 	unsigned ncpy = min(*size, cs->len);
484334f485dSMiklos Szeredi 	if (val) {
485334f485dSMiklos Szeredi 		if (cs->write)
486334f485dSMiklos Szeredi 			memcpy(cs->buf, *val, ncpy);
487334f485dSMiklos Szeredi 		else
488334f485dSMiklos Szeredi 			memcpy(*val, cs->buf, ncpy);
489334f485dSMiklos Szeredi 		*val += ncpy;
490334f485dSMiklos Szeredi 	}
491334f485dSMiklos Szeredi 	*size -= ncpy;
492334f485dSMiklos Szeredi 	cs->len -= ncpy;
493334f485dSMiklos Szeredi 	cs->buf += ncpy;
494334f485dSMiklos Szeredi 	return ncpy;
495334f485dSMiklos Szeredi }
496334f485dSMiklos Szeredi 
497334f485dSMiklos Szeredi /*
498334f485dSMiklos Szeredi  * Copy a page in the request to/from the userspace buffer.  Must be
499334f485dSMiklos Szeredi  * done atomically
500334f485dSMiklos Szeredi  */
5018bfc016dSMiklos Szeredi static int fuse_copy_page(struct fuse_copy_state *cs, struct page *page,
502334f485dSMiklos Szeredi 			  unsigned offset, unsigned count, int zeroing)
503334f485dSMiklos Szeredi {
504334f485dSMiklos Szeredi 	if (page && zeroing && count < PAGE_SIZE) {
505334f485dSMiklos Szeredi 		void *mapaddr = kmap_atomic(page, KM_USER1);
506334f485dSMiklos Szeredi 		memset(mapaddr, 0, PAGE_SIZE);
507334f485dSMiklos Szeredi 		kunmap_atomic(mapaddr, KM_USER1);
508334f485dSMiklos Szeredi 	}
509334f485dSMiklos Szeredi 	while (count) {
510334f485dSMiklos Szeredi 		int err;
511334f485dSMiklos Szeredi 		if (!cs->len && (err = fuse_copy_fill(cs)))
512334f485dSMiklos Szeredi 			return err;
513334f485dSMiklos Szeredi 		if (page) {
514334f485dSMiklos Szeredi 			void *mapaddr = kmap_atomic(page, KM_USER1);
515334f485dSMiklos Szeredi 			void *buf = mapaddr + offset;
516334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, &buf, &count);
517334f485dSMiklos Szeredi 			kunmap_atomic(mapaddr, KM_USER1);
518334f485dSMiklos Szeredi 		} else
519334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, NULL, &count);
520334f485dSMiklos Szeredi 	}
521334f485dSMiklos Szeredi 	if (page && !cs->write)
522334f485dSMiklos Szeredi 		flush_dcache_page(page);
523334f485dSMiklos Szeredi 	return 0;
524334f485dSMiklos Szeredi }
525334f485dSMiklos Szeredi 
526334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */
527334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
528334f485dSMiklos Szeredi 			   int zeroing)
529334f485dSMiklos Szeredi {
530334f485dSMiklos Szeredi 	unsigned i;
531334f485dSMiklos Szeredi 	struct fuse_req *req = cs->req;
532334f485dSMiklos Szeredi 	unsigned offset = req->page_offset;
533334f485dSMiklos Szeredi 	unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);
534334f485dSMiklos Szeredi 
535334f485dSMiklos Szeredi 	for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
536334f485dSMiklos Szeredi 		struct page *page = req->pages[i];
537334f485dSMiklos Szeredi 		int err = fuse_copy_page(cs, page, offset, count, zeroing);
538334f485dSMiklos Szeredi 		if (err)
539334f485dSMiklos Szeredi 			return err;
540334f485dSMiklos Szeredi 
541334f485dSMiklos Szeredi 		nbytes -= count;
542334f485dSMiklos Szeredi 		count = min(nbytes, (unsigned) PAGE_SIZE);
543334f485dSMiklos Szeredi 		offset = 0;
544334f485dSMiklos Szeredi 	}
545334f485dSMiklos Szeredi 	return 0;
546334f485dSMiklos Szeredi }
547334f485dSMiklos Szeredi 
548334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */
549334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
550334f485dSMiklos Szeredi {
551334f485dSMiklos Szeredi 	while (size) {
552334f485dSMiklos Szeredi 		int err;
553334f485dSMiklos Szeredi 		if (!cs->len && (err = fuse_copy_fill(cs)))
554334f485dSMiklos Szeredi 			return err;
555334f485dSMiklos Szeredi 		fuse_copy_do(cs, &val, &size);
556334f485dSMiklos Szeredi 	}
557334f485dSMiklos Szeredi 	return 0;
558334f485dSMiklos Szeredi }
559334f485dSMiklos Szeredi 
560334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */
561334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
562334f485dSMiklos Szeredi 			  unsigned argpages, struct fuse_arg *args,
563334f485dSMiklos Szeredi 			  int zeroing)
564334f485dSMiklos Szeredi {
565334f485dSMiklos Szeredi 	int err = 0;
566334f485dSMiklos Szeredi 	unsigned i;
567334f485dSMiklos Szeredi 
568334f485dSMiklos Szeredi 	for (i = 0; !err && i < numargs; i++)  {
569334f485dSMiklos Szeredi 		struct fuse_arg *arg = &args[i];
570334f485dSMiklos Szeredi 		if (i == numargs - 1 && argpages)
571334f485dSMiklos Szeredi 			err = fuse_copy_pages(cs, arg->size, zeroing);
572334f485dSMiklos Szeredi 		else
573334f485dSMiklos Szeredi 			err = fuse_copy_one(cs, arg->value, arg->size);
574334f485dSMiklos Szeredi 	}
575334f485dSMiklos Szeredi 	return err;
576334f485dSMiklos Szeredi }
577334f485dSMiklos Szeredi 
578334f485dSMiklos Szeredi /* Wait until a request is available on the pending list */
579334f485dSMiklos Szeredi static void request_wait(struct fuse_conn *fc)
580334f485dSMiklos Szeredi {
581334f485dSMiklos Szeredi 	DECLARE_WAITQUEUE(wait, current);
582334f485dSMiklos Szeredi 
583334f485dSMiklos Szeredi 	add_wait_queue_exclusive(&fc->waitq, &wait);
5849ba7cbbaSMiklos Szeredi 	while (fc->connected && list_empty(&fc->pending)) {
585334f485dSMiklos Szeredi 		set_current_state(TASK_INTERRUPTIBLE);
586334f485dSMiklos Szeredi 		if (signal_pending(current))
587334f485dSMiklos Szeredi 			break;
588334f485dSMiklos Szeredi 
589d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
590334f485dSMiklos Szeredi 		schedule();
591d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
592334f485dSMiklos Szeredi 	}
593334f485dSMiklos Szeredi 	set_current_state(TASK_RUNNING);
594334f485dSMiklos Szeredi 	remove_wait_queue(&fc->waitq, &wait);
595334f485dSMiklos Szeredi }
596334f485dSMiklos Szeredi 
597334f485dSMiklos Szeredi /*
598334f485dSMiklos Szeredi  * Read a single request into the userspace filesystem's buffer.  This
599334f485dSMiklos Szeredi  * function waits until a request is available, then removes it from
600334f485dSMiklos Szeredi  * the pending list and copies request data to userspace buffer.  If
601334f485dSMiklos Szeredi  * no reply is needed (FORGET) or request has been interrupted or
602334f485dSMiklos Szeredi  * there was an error during the copying then it's finished by calling
603334f485dSMiklos Szeredi  * request_end().  Otherwise add it to the processing list, and set
604334f485dSMiklos Szeredi  * the 'sent' flag.
605334f485dSMiklos Szeredi  */
606334f485dSMiklos Szeredi static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
607334f485dSMiklos Szeredi 			      unsigned long nr_segs, loff_t *off)
608334f485dSMiklos Szeredi {
609334f485dSMiklos Szeredi 	int err;
610334f485dSMiklos Szeredi 	struct fuse_req *req;
611334f485dSMiklos Szeredi 	struct fuse_in *in;
612334f485dSMiklos Szeredi 	struct fuse_copy_state cs;
613334f485dSMiklos Szeredi 	unsigned reqsize;
6140720b315SMiklos Szeredi 	struct fuse_conn *fc = fuse_get_conn(file);
6150720b315SMiklos Szeredi 	if (!fc)
6160720b315SMiklos Szeredi 		return -EPERM;
617334f485dSMiklos Szeredi 
6181d3d752bSMiklos Szeredi  restart:
619d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
620e5ac1d1eSJeff Dike 	err = -EAGAIN;
621e5ac1d1eSJeff Dike 	if ((file->f_flags & O_NONBLOCK) && fc->connected &&
622e5ac1d1eSJeff Dike 	    list_empty(&fc->pending))
623e5ac1d1eSJeff Dike 		goto err_unlock;
624e5ac1d1eSJeff Dike 
625334f485dSMiklos Szeredi 	request_wait(fc);
626334f485dSMiklos Szeredi 	err = -ENODEV;
6279ba7cbbaSMiklos Szeredi 	if (!fc->connected)
628334f485dSMiklos Szeredi 		goto err_unlock;
629334f485dSMiklos Szeredi 	err = -ERESTARTSYS;
630334f485dSMiklos Szeredi 	if (list_empty(&fc->pending))
631334f485dSMiklos Szeredi 		goto err_unlock;
632334f485dSMiklos Szeredi 
633334f485dSMiklos Szeredi 	req = list_entry(fc->pending.next, struct fuse_req, list);
63483cfd493SMiklos Szeredi 	req->state = FUSE_REQ_READING;
635d77a1d5bSMiklos Szeredi 	list_move(&req->list, &fc->io);
636334f485dSMiklos Szeredi 
637334f485dSMiklos Szeredi 	in = &req->in;
6381d3d752bSMiklos Szeredi 	reqsize = in->h.len;
6391d3d752bSMiklos Szeredi 	/* If request is too large, reply with an error and restart the read */
6401d3d752bSMiklos Szeredi 	if (iov_length(iov, nr_segs) < reqsize) {
6411d3d752bSMiklos Szeredi 		req->out.h.error = -EIO;
6421d3d752bSMiklos Szeredi 		/* SETXATTR is special, since it may contain too large data */
6431d3d752bSMiklos Szeredi 		if (in->h.opcode == FUSE_SETXATTR)
6441d3d752bSMiklos Szeredi 			req->out.h.error = -E2BIG;
6451d3d752bSMiklos Szeredi 		request_end(fc, req);
6461d3d752bSMiklos Szeredi 		goto restart;
6471d3d752bSMiklos Szeredi 	}
648d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
649d7133114SMiklos Szeredi 	fuse_copy_init(&cs, fc, 1, req, iov, nr_segs);
650334f485dSMiklos Szeredi 	err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
651334f485dSMiklos Szeredi 	if (!err)
652334f485dSMiklos Szeredi 		err = fuse_copy_args(&cs, in->numargs, in->argpages,
653334f485dSMiklos Szeredi 				     (struct fuse_arg *) in->args, 0);
654334f485dSMiklos Szeredi 	fuse_copy_finish(&cs);
655d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
656334f485dSMiklos Szeredi 	req->locked = 0;
657334f485dSMiklos Szeredi 	if (!err && req->interrupted)
658334f485dSMiklos Szeredi 		err = -ENOENT;
659334f485dSMiklos Szeredi 	if (err) {
660334f485dSMiklos Szeredi 		if (!req->interrupted)
661334f485dSMiklos Szeredi 			req->out.h.error = -EIO;
662334f485dSMiklos Szeredi 		request_end(fc, req);
663334f485dSMiklos Szeredi 		return err;
664334f485dSMiklos Szeredi 	}
665334f485dSMiklos Szeredi 	if (!req->isreply)
666334f485dSMiklos Szeredi 		request_end(fc, req);
667334f485dSMiklos Szeredi 	else {
66883cfd493SMiklos Szeredi 		req->state = FUSE_REQ_SENT;
669d77a1d5bSMiklos Szeredi 		list_move_tail(&req->list, &fc->processing);
670d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
671334f485dSMiklos Szeredi 	}
672334f485dSMiklos Szeredi 	return reqsize;
673334f485dSMiklos Szeredi 
674334f485dSMiklos Szeredi  err_unlock:
675d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
676334f485dSMiklos Szeredi 	return err;
677334f485dSMiklos Szeredi }
678334f485dSMiklos Szeredi 
679334f485dSMiklos Szeredi static ssize_t fuse_dev_read(struct file *file, char __user *buf,
680334f485dSMiklos Szeredi 			     size_t nbytes, loff_t *off)
681334f485dSMiklos Szeredi {
682334f485dSMiklos Szeredi 	struct iovec iov;
683334f485dSMiklos Szeredi 	iov.iov_len = nbytes;
684334f485dSMiklos Szeredi 	iov.iov_base = buf;
685334f485dSMiklos Szeredi 	return fuse_dev_readv(file, &iov, 1, off);
686334f485dSMiklos Szeredi }
687334f485dSMiklos Szeredi 
688334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */
689334f485dSMiklos Szeredi static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
690334f485dSMiklos Szeredi {
691334f485dSMiklos Szeredi 	struct list_head *entry;
692334f485dSMiklos Szeredi 
693334f485dSMiklos Szeredi 	list_for_each(entry, &fc->processing) {
694334f485dSMiklos Szeredi 		struct fuse_req *req;
695334f485dSMiklos Szeredi 		req = list_entry(entry, struct fuse_req, list);
696334f485dSMiklos Szeredi 		if (req->in.h.unique == unique)
697334f485dSMiklos Szeredi 			return req;
698334f485dSMiklos Szeredi 	}
699334f485dSMiklos Szeredi 	return NULL;
700334f485dSMiklos Szeredi }
701334f485dSMiklos Szeredi 
702334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
703334f485dSMiklos Szeredi 			 unsigned nbytes)
704334f485dSMiklos Szeredi {
705334f485dSMiklos Szeredi 	unsigned reqsize = sizeof(struct fuse_out_header);
706334f485dSMiklos Szeredi 
707334f485dSMiklos Szeredi 	if (out->h.error)
708334f485dSMiklos Szeredi 		return nbytes != reqsize ? -EINVAL : 0;
709334f485dSMiklos Szeredi 
710334f485dSMiklos Szeredi 	reqsize += len_args(out->numargs, out->args);
711334f485dSMiklos Szeredi 
712334f485dSMiklos Szeredi 	if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))
713334f485dSMiklos Szeredi 		return -EINVAL;
714334f485dSMiklos Szeredi 	else if (reqsize > nbytes) {
715334f485dSMiklos Szeredi 		struct fuse_arg *lastarg = &out->args[out->numargs-1];
716334f485dSMiklos Szeredi 		unsigned diffsize = reqsize - nbytes;
717334f485dSMiklos Szeredi 		if (diffsize > lastarg->size)
718334f485dSMiklos Szeredi 			return -EINVAL;
719334f485dSMiklos Szeredi 		lastarg->size -= diffsize;
720334f485dSMiklos Szeredi 	}
721334f485dSMiklos Szeredi 	return fuse_copy_args(cs, out->numargs, out->argpages, out->args,
722334f485dSMiklos Szeredi 			      out->page_zeroing);
723334f485dSMiklos Szeredi }
724334f485dSMiklos Szeredi 
725334f485dSMiklos Szeredi /*
726334f485dSMiklos Szeredi  * Write a single reply to a request.  First the header is copied from
727334f485dSMiklos Szeredi  * the write buffer.  The request is then searched on the processing
728334f485dSMiklos Szeredi  * list by the unique ID found in the header.  If found, then remove
729334f485dSMiklos Szeredi  * it from the list and copy the rest of the buffer to the request.
730334f485dSMiklos Szeredi  * The request is finished by calling request_end()
731334f485dSMiklos Szeredi  */
732334f485dSMiklos Szeredi static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
733334f485dSMiklos Szeredi 			       unsigned long nr_segs, loff_t *off)
734334f485dSMiklos Szeredi {
735334f485dSMiklos Szeredi 	int err;
736334f485dSMiklos Szeredi 	unsigned nbytes = iov_length(iov, nr_segs);
737334f485dSMiklos Szeredi 	struct fuse_req *req;
738334f485dSMiklos Szeredi 	struct fuse_out_header oh;
739334f485dSMiklos Szeredi 	struct fuse_copy_state cs;
740334f485dSMiklos Szeredi 	struct fuse_conn *fc = fuse_get_conn(file);
741334f485dSMiklos Szeredi 	if (!fc)
742334f485dSMiklos Szeredi 		return -ENODEV;
743334f485dSMiklos Szeredi 
744d7133114SMiklos Szeredi 	fuse_copy_init(&cs, fc, 0, NULL, iov, nr_segs);
745334f485dSMiklos Szeredi 	if (nbytes < sizeof(struct fuse_out_header))
746334f485dSMiklos Szeredi 		return -EINVAL;
747334f485dSMiklos Szeredi 
748334f485dSMiklos Szeredi 	err = fuse_copy_one(&cs, &oh, sizeof(oh));
749334f485dSMiklos Szeredi 	if (err)
750334f485dSMiklos Szeredi 		goto err_finish;
751334f485dSMiklos Szeredi 	err = -EINVAL;
752334f485dSMiklos Szeredi 	if (!oh.unique || oh.error <= -1000 || oh.error > 0 ||
753334f485dSMiklos Szeredi 	    oh.len != nbytes)
754334f485dSMiklos Szeredi 		goto err_finish;
755334f485dSMiklos Szeredi 
756d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
75769a53bf2SMiklos Szeredi 	err = -ENOENT;
75869a53bf2SMiklos Szeredi 	if (!fc->connected)
75969a53bf2SMiklos Szeredi 		goto err_unlock;
76069a53bf2SMiklos Szeredi 
761334f485dSMiklos Szeredi 	req = request_find(fc, oh.unique);
762334f485dSMiklos Szeredi 	err = -EINVAL;
763334f485dSMiklos Szeredi 	if (!req)
764334f485dSMiklos Szeredi 		goto err_unlock;
765334f485dSMiklos Szeredi 
766334f485dSMiklos Szeredi 	if (req->interrupted) {
767d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
768334f485dSMiklos Szeredi 		fuse_copy_finish(&cs);
769d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
770222f1d69SMiklos Szeredi 		request_end(fc, req);
771334f485dSMiklos Szeredi 		return -ENOENT;
772334f485dSMiklos Szeredi 	}
773d77a1d5bSMiklos Szeredi 	list_move(&req->list, &fc->io);
774334f485dSMiklos Szeredi 	req->out.h = oh;
775334f485dSMiklos Szeredi 	req->locked = 1;
776334f485dSMiklos Szeredi 	cs.req = req;
777d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
778334f485dSMiklos Szeredi 
779334f485dSMiklos Szeredi 	err = copy_out_args(&cs, &req->out, nbytes);
780334f485dSMiklos Szeredi 	fuse_copy_finish(&cs);
781334f485dSMiklos Szeredi 
782d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
783334f485dSMiklos Szeredi 	req->locked = 0;
784334f485dSMiklos Szeredi 	if (!err) {
785334f485dSMiklos Szeredi 		if (req->interrupted)
786334f485dSMiklos Szeredi 			err = -ENOENT;
787334f485dSMiklos Szeredi 	} else if (!req->interrupted)
788334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
789334f485dSMiklos Szeredi 	request_end(fc, req);
790334f485dSMiklos Szeredi 
791334f485dSMiklos Szeredi 	return err ? err : nbytes;
792334f485dSMiklos Szeredi 
793334f485dSMiklos Szeredi  err_unlock:
794d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
795334f485dSMiklos Szeredi  err_finish:
796334f485dSMiklos Szeredi 	fuse_copy_finish(&cs);
797334f485dSMiklos Szeredi 	return err;
798334f485dSMiklos Szeredi }
799334f485dSMiklos Szeredi 
800334f485dSMiklos Szeredi static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
801334f485dSMiklos Szeredi 			      size_t nbytes, loff_t *off)
802334f485dSMiklos Szeredi {
803334f485dSMiklos Szeredi 	struct iovec iov;
804334f485dSMiklos Szeredi 	iov.iov_len = nbytes;
805334f485dSMiklos Szeredi 	iov.iov_base = (char __user *) buf;
806334f485dSMiklos Szeredi 	return fuse_dev_writev(file, &iov, 1, off);
807334f485dSMiklos Szeredi }
808334f485dSMiklos Szeredi 
809334f485dSMiklos Szeredi static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
810334f485dSMiklos Szeredi {
811334f485dSMiklos Szeredi 	unsigned mask = POLLOUT | POLLWRNORM;
8127025d9adSMiklos Szeredi 	struct fuse_conn *fc = fuse_get_conn(file);
813334f485dSMiklos Szeredi 	if (!fc)
8147025d9adSMiklos Szeredi 		return POLLERR;
815334f485dSMiklos Szeredi 
816334f485dSMiklos Szeredi 	poll_wait(file, &fc->waitq, wait);
817334f485dSMiklos Szeredi 
818d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
8197025d9adSMiklos Szeredi 	if (!fc->connected)
8207025d9adSMiklos Szeredi 		mask = POLLERR;
8217025d9adSMiklos Szeredi 	else if (!list_empty(&fc->pending))
822334f485dSMiklos Szeredi 		mask |= POLLIN | POLLRDNORM;
823d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
824334f485dSMiklos Szeredi 
825334f485dSMiklos Szeredi 	return mask;
826334f485dSMiklos Szeredi }
827334f485dSMiklos Szeredi 
82869a53bf2SMiklos Szeredi /*
82969a53bf2SMiklos Szeredi  * Abort all requests on the given list (pending or processing)
83069a53bf2SMiklos Szeredi  *
831d7133114SMiklos Szeredi  * This function releases and reacquires fc->lock
83269a53bf2SMiklos Szeredi  */
833334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head)
834334f485dSMiklos Szeredi {
835334f485dSMiklos Szeredi 	while (!list_empty(head)) {
836334f485dSMiklos Szeredi 		struct fuse_req *req;
837334f485dSMiklos Szeredi 		req = list_entry(head->next, struct fuse_req, list);
838334f485dSMiklos Szeredi 		req->out.h.error = -ECONNABORTED;
839334f485dSMiklos Szeredi 		request_end(fc, req);
840d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
841334f485dSMiklos Szeredi 	}
842334f485dSMiklos Szeredi }
843334f485dSMiklos Szeredi 
84469a53bf2SMiklos Szeredi /*
84569a53bf2SMiklos Szeredi  * Abort requests under I/O
84669a53bf2SMiklos Szeredi  *
84769a53bf2SMiklos Szeredi  * The requests are set to interrupted and finished, and the request
84869a53bf2SMiklos Szeredi  * waiter is woken up.  This will make request_wait_answer() wait
84969a53bf2SMiklos Szeredi  * until the request is unlocked and then return.
85064c6d8edSMiklos Szeredi  *
85164c6d8edSMiklos Szeredi  * If the request is asynchronous, then the end function needs to be
85264c6d8edSMiklos Szeredi  * called after waiting for the request to be unlocked (if it was
85364c6d8edSMiklos Szeredi  * locked).
85469a53bf2SMiklos Szeredi  */
85569a53bf2SMiklos Szeredi static void end_io_requests(struct fuse_conn *fc)
85669a53bf2SMiklos Szeredi {
85769a53bf2SMiklos Szeredi 	while (!list_empty(&fc->io)) {
85864c6d8edSMiklos Szeredi 		struct fuse_req *req =
85964c6d8edSMiklos Szeredi 			list_entry(fc->io.next, struct fuse_req, list);
86064c6d8edSMiklos Szeredi 		void (*end) (struct fuse_conn *, struct fuse_req *) = req->end;
86164c6d8edSMiklos Szeredi 
86269a53bf2SMiklos Szeredi 		req->interrupted = 1;
86369a53bf2SMiklos Szeredi 		req->out.h.error = -ECONNABORTED;
86469a53bf2SMiklos Szeredi 		req->state = FUSE_REQ_FINISHED;
86569a53bf2SMiklos Szeredi 		list_del_init(&req->list);
86669a53bf2SMiklos Szeredi 		wake_up(&req->waitq);
86764c6d8edSMiklos Szeredi 		if (end) {
86864c6d8edSMiklos Szeredi 			req->end = NULL;
86964c6d8edSMiklos Szeredi 			/* The end function will consume this reference */
87064c6d8edSMiklos Szeredi 			__fuse_get_request(req);
871d7133114SMiklos Szeredi 			spin_unlock(&fc->lock);
87264c6d8edSMiklos Szeredi 			wait_event(req->waitq, !req->locked);
87364c6d8edSMiklos Szeredi 			end(fc, req);
874d7133114SMiklos Szeredi 			spin_lock(&fc->lock);
87564c6d8edSMiklos Szeredi 		}
87669a53bf2SMiklos Szeredi 	}
87769a53bf2SMiklos Szeredi }
87869a53bf2SMiklos Szeredi 
87969a53bf2SMiklos Szeredi /*
88069a53bf2SMiklos Szeredi  * Abort all requests.
88169a53bf2SMiklos Szeredi  *
88269a53bf2SMiklos Szeredi  * Emergency exit in case of a malicious or accidental deadlock, or
88369a53bf2SMiklos Szeredi  * just a hung filesystem.
88469a53bf2SMiklos Szeredi  *
88569a53bf2SMiklos Szeredi  * The same effect is usually achievable through killing the
88669a53bf2SMiklos Szeredi  * filesystem daemon and all users of the filesystem.  The exception
88769a53bf2SMiklos Szeredi  * is the combination of an asynchronous request and the tricky
88869a53bf2SMiklos Szeredi  * deadlock (see Documentation/filesystems/fuse.txt).
88969a53bf2SMiklos Szeredi  *
89069a53bf2SMiklos Szeredi  * During the aborting, progression of requests from the pending and
89169a53bf2SMiklos Szeredi  * processing lists onto the io list, and progression of new requests
89269a53bf2SMiklos Szeredi  * onto the pending list is prevented by req->connected being false.
89369a53bf2SMiklos Szeredi  *
89469a53bf2SMiklos Szeredi  * Progression of requests under I/O to the processing list is
89569a53bf2SMiklos Szeredi  * prevented by the req->interrupted flag being true for these
89669a53bf2SMiklos Szeredi  * requests.  For this reason requests on the io list must be aborted
89769a53bf2SMiklos Szeredi  * first.
89869a53bf2SMiklos Szeredi  */
89969a53bf2SMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc)
90069a53bf2SMiklos Szeredi {
901d7133114SMiklos Szeredi 	spin_lock(&fc->lock);
90269a53bf2SMiklos Szeredi 	if (fc->connected) {
90369a53bf2SMiklos Szeredi 		fc->connected = 0;
90469a53bf2SMiklos Szeredi 		end_io_requests(fc);
90569a53bf2SMiklos Szeredi 		end_requests(fc, &fc->pending);
90669a53bf2SMiklos Szeredi 		end_requests(fc, &fc->processing);
90769a53bf2SMiklos Szeredi 		wake_up_all(&fc->waitq);
908385a17bfSJeff Dike 		kill_fasync(&fc->fasync, SIGIO, POLL_IN);
90969a53bf2SMiklos Szeredi 	}
910d7133114SMiklos Szeredi 	spin_unlock(&fc->lock);
91169a53bf2SMiklos Szeredi }
91269a53bf2SMiklos Szeredi 
913334f485dSMiklos Szeredi static int fuse_dev_release(struct inode *inode, struct file *file)
914334f485dSMiklos Szeredi {
9150720b315SMiklos Szeredi 	struct fuse_conn *fc = fuse_get_conn(file);
916334f485dSMiklos Szeredi 	if (fc) {
917d7133114SMiklos Szeredi 		spin_lock(&fc->lock);
9181e9a4ed9SMiklos Szeredi 		fc->connected = 0;
919334f485dSMiklos Szeredi 		end_requests(fc, &fc->pending);
920334f485dSMiklos Szeredi 		end_requests(fc, &fc->processing);
921d7133114SMiklos Szeredi 		spin_unlock(&fc->lock);
922385a17bfSJeff Dike 		fasync_helper(-1, file, 0, &fc->fasync);
923f543f253SMiklos Szeredi 		kobject_put(&fc->kobj);
924385a17bfSJeff Dike 	}
925f543f253SMiklos Szeredi 
926334f485dSMiklos Szeredi 	return 0;
927334f485dSMiklos Szeredi }
928334f485dSMiklos Szeredi 
929385a17bfSJeff Dike static int fuse_dev_fasync(int fd, struct file *file, int on)
930385a17bfSJeff Dike {
931385a17bfSJeff Dike 	struct fuse_conn *fc = fuse_get_conn(file);
932385a17bfSJeff Dike 	if (!fc)
933385a17bfSJeff Dike 		return -ENODEV;
934385a17bfSJeff Dike 
935385a17bfSJeff Dike 	/* No locking - fasync_helper does its own locking */
936385a17bfSJeff Dike 	return fasync_helper(fd, file, on, &fc->fasync);
937385a17bfSJeff Dike }
938385a17bfSJeff Dike 
9394b6f5d20SArjan van de Ven const struct file_operations fuse_dev_operations = {
940334f485dSMiklos Szeredi 	.owner		= THIS_MODULE,
941334f485dSMiklos Szeredi 	.llseek		= no_llseek,
942334f485dSMiklos Szeredi 	.read		= fuse_dev_read,
943334f485dSMiklos Szeredi 	.readv		= fuse_dev_readv,
944334f485dSMiklos Szeredi 	.write		= fuse_dev_write,
945334f485dSMiklos Szeredi 	.writev		= fuse_dev_writev,
946334f485dSMiklos Szeredi 	.poll		= fuse_dev_poll,
947334f485dSMiklos Szeredi 	.release	= fuse_dev_release,
948385a17bfSJeff Dike 	.fasync		= fuse_dev_fasync,
949334f485dSMiklos Szeredi };
950334f485dSMiklos Szeredi 
951334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = {
952334f485dSMiklos Szeredi 	.minor = FUSE_MINOR,
953334f485dSMiklos Szeredi 	.name  = "fuse",
954334f485dSMiklos Szeredi 	.fops = &fuse_dev_operations,
955334f485dSMiklos Szeredi };
956334f485dSMiklos Szeredi 
957334f485dSMiklos Szeredi int __init fuse_dev_init(void)
958334f485dSMiklos Szeredi {
959334f485dSMiklos Szeredi 	int err = -ENOMEM;
960334f485dSMiklos Szeredi 	fuse_req_cachep = kmem_cache_create("fuse_request",
961334f485dSMiklos Szeredi 					    sizeof(struct fuse_req),
962334f485dSMiklos Szeredi 					    0, 0, NULL, NULL);
963334f485dSMiklos Szeredi 	if (!fuse_req_cachep)
964334f485dSMiklos Szeredi 		goto out;
965334f485dSMiklos Szeredi 
966334f485dSMiklos Szeredi 	err = misc_register(&fuse_miscdevice);
967334f485dSMiklos Szeredi 	if (err)
968334f485dSMiklos Szeredi 		goto out_cache_clean;
969334f485dSMiklos Szeredi 
970334f485dSMiklos Szeredi 	return 0;
971334f485dSMiklos Szeredi 
972334f485dSMiklos Szeredi  out_cache_clean:
973334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
974334f485dSMiklos Szeredi  out:
975334f485dSMiklos Szeredi 	return err;
976334f485dSMiklos Szeredi }
977334f485dSMiklos Szeredi 
978334f485dSMiklos Szeredi void fuse_dev_cleanup(void)
979334f485dSMiklos Szeredi {
980334f485dSMiklos Szeredi 	misc_deregister(&fuse_miscdevice);
981334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
982334f485dSMiklos Szeredi }
983