xref: /openbmc/linux/fs/fuse/dev.c (revision 1e9a4ed9)
1334f485dSMiklos Szeredi /*
2334f485dSMiklos Szeredi   FUSE: Filesystem in Userspace
3334f485dSMiklos Szeredi   Copyright (C) 2001-2005  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 
24334f485dSMiklos Szeredi static inline struct fuse_conn *fuse_get_conn(struct file *file)
25334f485dSMiklos Szeredi {
26334f485dSMiklos Szeredi 	struct fuse_conn *fc;
27334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
28334f485dSMiklos Szeredi 	fc = file->private_data;
29*1e9a4ed9SMiklos Szeredi 	if (fc && !fc->mounted)
30334f485dSMiklos Szeredi 		fc = NULL;
31334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
32334f485dSMiklos Szeredi 	return fc;
33334f485dSMiklos Szeredi }
34334f485dSMiklos Szeredi 
35334f485dSMiklos Szeredi static inline void fuse_request_init(struct fuse_req *req)
36334f485dSMiklos Szeredi {
37334f485dSMiklos Szeredi 	memset(req, 0, sizeof(*req));
38334f485dSMiklos Szeredi 	INIT_LIST_HEAD(&req->list);
39334f485dSMiklos Szeredi 	init_waitqueue_head(&req->waitq);
40334f485dSMiklos Szeredi 	atomic_set(&req->count, 1);
41334f485dSMiklos Szeredi }
42334f485dSMiklos Szeredi 
43334f485dSMiklos Szeredi struct fuse_req *fuse_request_alloc(void)
44334f485dSMiklos Szeredi {
45334f485dSMiklos Szeredi 	struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, SLAB_KERNEL);
46334f485dSMiklos Szeredi 	if (req)
47334f485dSMiklos Szeredi 		fuse_request_init(req);
48334f485dSMiklos Szeredi 	return req;
49334f485dSMiklos Szeredi }
50334f485dSMiklos Szeredi 
51334f485dSMiklos Szeredi void fuse_request_free(struct fuse_req *req)
52334f485dSMiklos Szeredi {
53334f485dSMiklos Szeredi 	kmem_cache_free(fuse_req_cachep, req);
54334f485dSMiklos Szeredi }
55334f485dSMiklos Szeredi 
56334f485dSMiklos Szeredi static inline void block_sigs(sigset_t *oldset)
57334f485dSMiklos Szeredi {
58334f485dSMiklos Szeredi 	sigset_t mask;
59334f485dSMiklos Szeredi 
60334f485dSMiklos Szeredi 	siginitsetinv(&mask, sigmask(SIGKILL));
61334f485dSMiklos Szeredi 	sigprocmask(SIG_BLOCK, &mask, oldset);
62334f485dSMiklos Szeredi }
63334f485dSMiklos Szeredi 
64334f485dSMiklos Szeredi static inline void restore_sigs(sigset_t *oldset)
65334f485dSMiklos Szeredi {
66334f485dSMiklos Szeredi 	sigprocmask(SIG_SETMASK, oldset, NULL);
67334f485dSMiklos Szeredi }
68334f485dSMiklos Szeredi 
69334f485dSMiklos Szeredi void fuse_reset_request(struct fuse_req *req)
70334f485dSMiklos Szeredi {
71334f485dSMiklos Szeredi 	int preallocated = req->preallocated;
72334f485dSMiklos Szeredi 	BUG_ON(atomic_read(&req->count) != 1);
73334f485dSMiklos Szeredi 	fuse_request_init(req);
74334f485dSMiklos Szeredi 	req->preallocated = preallocated;
75334f485dSMiklos Szeredi }
76334f485dSMiklos Szeredi 
77334f485dSMiklos Szeredi static void __fuse_get_request(struct fuse_req *req)
78334f485dSMiklos Szeredi {
79334f485dSMiklos Szeredi 	atomic_inc(&req->count);
80334f485dSMiklos Szeredi }
81334f485dSMiklos Szeredi 
82334f485dSMiklos Szeredi /* Must be called with > 1 refcount */
83334f485dSMiklos Szeredi static void __fuse_put_request(struct fuse_req *req)
84334f485dSMiklos Szeredi {
85334f485dSMiklos Szeredi 	BUG_ON(atomic_read(&req->count) < 2);
86334f485dSMiklos Szeredi 	atomic_dec(&req->count);
87334f485dSMiklos Szeredi }
88334f485dSMiklos Szeredi 
89334f485dSMiklos Szeredi static struct fuse_req *do_get_request(struct fuse_conn *fc)
90334f485dSMiklos Szeredi {
91334f485dSMiklos Szeredi 	struct fuse_req *req;
92334f485dSMiklos Szeredi 
93334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
94334f485dSMiklos Szeredi 	BUG_ON(list_empty(&fc->unused_list));
95334f485dSMiklos Szeredi 	req = list_entry(fc->unused_list.next, struct fuse_req, list);
96334f485dSMiklos Szeredi 	list_del_init(&req->list);
97334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
98334f485dSMiklos Szeredi 	fuse_request_init(req);
99334f485dSMiklos Szeredi 	req->preallocated = 1;
100334f485dSMiklos Szeredi 	req->in.h.uid = current->fsuid;
101334f485dSMiklos Szeredi 	req->in.h.gid = current->fsgid;
102334f485dSMiklos Szeredi 	req->in.h.pid = current->pid;
103334f485dSMiklos Szeredi 	return req;
104334f485dSMiklos Szeredi }
105334f485dSMiklos Szeredi 
106334f485dSMiklos Szeredi struct fuse_req *fuse_get_request(struct fuse_conn *fc)
107334f485dSMiklos Szeredi {
108334f485dSMiklos Szeredi 	if (down_interruptible(&fc->outstanding_sem))
109334f485dSMiklos Szeredi 		return NULL;
110334f485dSMiklos Szeredi 	return do_get_request(fc);
111334f485dSMiklos Szeredi }
112334f485dSMiklos Szeredi 
113334f485dSMiklos Szeredi /*
114334f485dSMiklos Szeredi  * Non-interruptible version of the above function is for operations
115334f485dSMiklos Szeredi  * which can't legally return -ERESTART{SYS,NOINTR}.  This can still
116334f485dSMiklos Szeredi  * return NULL, but only in case the signal is SIGKILL.
117334f485dSMiklos Szeredi  */
118334f485dSMiklos Szeredi struct fuse_req *fuse_get_request_nonint(struct fuse_conn *fc)
119334f485dSMiklos Szeredi {
120334f485dSMiklos Szeredi 	int intr;
121334f485dSMiklos Szeredi 	sigset_t oldset;
122334f485dSMiklos Szeredi 
123334f485dSMiklos Szeredi 	block_sigs(&oldset);
124334f485dSMiklos Szeredi 	intr = down_interruptible(&fc->outstanding_sem);
125334f485dSMiklos Szeredi 	restore_sigs(&oldset);
126334f485dSMiklos Szeredi 	return intr ? NULL : do_get_request(fc);
127334f485dSMiklos Szeredi }
128334f485dSMiklos Szeredi 
129334f485dSMiklos Szeredi static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req)
130334f485dSMiklos Szeredi {
131334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
132334f485dSMiklos Szeredi 	if (req->preallocated)
133334f485dSMiklos Szeredi 		list_add(&req->list, &fc->unused_list);
134334f485dSMiklos Szeredi 	else
135334f485dSMiklos Szeredi 		fuse_request_free(req);
136334f485dSMiklos Szeredi 
137334f485dSMiklos Szeredi 	/* If we are in debt decrease that first */
138334f485dSMiklos Szeredi 	if (fc->outstanding_debt)
139334f485dSMiklos Szeredi 		fc->outstanding_debt--;
140334f485dSMiklos Szeredi 	else
141334f485dSMiklos Szeredi 		up(&fc->outstanding_sem);
142334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
143334f485dSMiklos Szeredi }
144334f485dSMiklos Szeredi 
145334f485dSMiklos Szeredi void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
146334f485dSMiklos Szeredi {
147334f485dSMiklos Szeredi 	if (atomic_dec_and_test(&req->count))
148334f485dSMiklos Szeredi 		fuse_putback_request(fc, req);
149334f485dSMiklos Szeredi }
150334f485dSMiklos Szeredi 
151*1e9a4ed9SMiklos Szeredi void fuse_release_background(struct fuse_req *req)
152*1e9a4ed9SMiklos Szeredi {
153*1e9a4ed9SMiklos Szeredi 	iput(req->inode);
154*1e9a4ed9SMiklos Szeredi 	iput(req->inode2);
155*1e9a4ed9SMiklos Szeredi 	if (req->file)
156*1e9a4ed9SMiklos Szeredi 		fput(req->file);
157*1e9a4ed9SMiklos Szeredi 	spin_lock(&fuse_lock);
158*1e9a4ed9SMiklos Szeredi 	list_del(&req->bg_entry);
159*1e9a4ed9SMiklos Szeredi 	spin_unlock(&fuse_lock);
160*1e9a4ed9SMiklos Szeredi }
161*1e9a4ed9SMiklos Szeredi 
162334f485dSMiklos Szeredi /*
163334f485dSMiklos Szeredi  * This function is called when a request is finished.  Either a reply
164334f485dSMiklos Szeredi  * has arrived or it was interrupted (and not yet sent) or some error
165334f485dSMiklos Szeredi  * occured during communication with userspace, or the device file was
166334f485dSMiklos Szeredi  * closed.  It decreases the referece count for the request.  In case
167334f485dSMiklos Szeredi  * of a background request the referece to the stored objects are
168334f485dSMiklos Szeredi  * released.  The requester thread is woken up (if still waiting), and
169334f485dSMiklos Szeredi  * finally the request is either freed or put on the unused_list
170334f485dSMiklos Szeredi  *
171334f485dSMiklos Szeredi  * Called with fuse_lock, unlocks it
172334f485dSMiklos Szeredi  */
173334f485dSMiklos Szeredi static void request_end(struct fuse_conn *fc, struct fuse_req *req)
174334f485dSMiklos Szeredi {
175334f485dSMiklos Szeredi 	int putback;
176334f485dSMiklos Szeredi 	req->finished = 1;
177334f485dSMiklos Szeredi 	putback = atomic_dec_and_test(&req->count);
178334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
179334f485dSMiklos Szeredi 	if (req->background) {
180*1e9a4ed9SMiklos Szeredi 		down_read(&fc->sbput_sem);
181*1e9a4ed9SMiklos Szeredi 		if (fc->mounted)
182*1e9a4ed9SMiklos Szeredi 			fuse_release_background(req);
183*1e9a4ed9SMiklos Szeredi 		up_read(&fc->sbput_sem);
184334f485dSMiklos Szeredi 	}
185334f485dSMiklos Szeredi 	wake_up(&req->waitq);
186334f485dSMiklos Szeredi 	if (req->in.h.opcode == FUSE_INIT) {
187334f485dSMiklos Szeredi 		int i;
188334f485dSMiklos Szeredi 
189334f485dSMiklos Szeredi 		if (req->misc.init_in_out.major != FUSE_KERNEL_VERSION)
190334f485dSMiklos Szeredi 			fc->conn_error = 1;
191334f485dSMiklos Szeredi 
192334f485dSMiklos Szeredi 		/* After INIT reply is received other requests can go
193334f485dSMiklos Szeredi 		   out.  So do (FUSE_MAX_OUTSTANDING - 1) number of
194334f485dSMiklos Szeredi 		   up()s on outstanding_sem.  The last up() is done in
195334f485dSMiklos Szeredi 		   fuse_putback_request() */
196334f485dSMiklos Szeredi 		for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
197334f485dSMiklos Szeredi 			up(&fc->outstanding_sem);
198334f485dSMiklos Szeredi 	}
199334f485dSMiklos Szeredi 	if (putback)
200334f485dSMiklos Szeredi 		fuse_putback_request(fc, req);
201334f485dSMiklos Szeredi }
202334f485dSMiklos Szeredi 
203*1e9a4ed9SMiklos Szeredi /*
204*1e9a4ed9SMiklos Szeredi  * Unfortunately request interruption not just solves the deadlock
205*1e9a4ed9SMiklos Szeredi  * problem, it causes problems too.  These stem from the fact, that an
206*1e9a4ed9SMiklos Szeredi  * interrupted request is continued to be processed in userspace,
207*1e9a4ed9SMiklos Szeredi  * while all the locks and object references (inode and file) held
208*1e9a4ed9SMiklos Szeredi  * during the operation are released.
209*1e9a4ed9SMiklos Szeredi  *
210*1e9a4ed9SMiklos Szeredi  * To release the locks is exactly why there's a need to interrupt the
211*1e9a4ed9SMiklos Szeredi  * request, so there's not a lot that can be done about this, except
212*1e9a4ed9SMiklos Szeredi  * introduce additional locking in userspace.
213*1e9a4ed9SMiklos Szeredi  *
214*1e9a4ed9SMiklos Szeredi  * More important is to keep inode and file references until userspace
215*1e9a4ed9SMiklos Szeredi  * has replied, otherwise FORGET and RELEASE could be sent while the
216*1e9a4ed9SMiklos Szeredi  * inode/file is still used by the filesystem.
217*1e9a4ed9SMiklos Szeredi  *
218*1e9a4ed9SMiklos Szeredi  * For this reason the concept of "background" request is introduced.
219*1e9a4ed9SMiklos Szeredi  * An interrupted request is backgrounded if it has been already sent
220*1e9a4ed9SMiklos Szeredi  * to userspace.  Backgrounding involves getting an extra reference to
221*1e9a4ed9SMiklos Szeredi  * inode(s) or file used in the request, and adding the request to
222*1e9a4ed9SMiklos Szeredi  * fc->background list.  When a reply is received for a background
223*1e9a4ed9SMiklos Szeredi  * request, the object references are released, and the request is
224*1e9a4ed9SMiklos Szeredi  * removed from the list.  If the filesystem is unmounted while there
225*1e9a4ed9SMiklos Szeredi  * are still background requests, the list is walked and references
226*1e9a4ed9SMiklos Szeredi  * are released as if a reply was received.
227*1e9a4ed9SMiklos Szeredi  *
228*1e9a4ed9SMiklos Szeredi  * There's one more use for a background request.  The RELEASE message is
229*1e9a4ed9SMiklos Szeredi  * always sent as background, since it doesn't return an error or
230*1e9a4ed9SMiklos Szeredi  * data.
231*1e9a4ed9SMiklos Szeredi  */
232*1e9a4ed9SMiklos Szeredi static void background_request(struct fuse_conn *fc, struct fuse_req *req)
233334f485dSMiklos Szeredi {
234334f485dSMiklos Szeredi 	req->background = 1;
235*1e9a4ed9SMiklos Szeredi 	list_add(&req->bg_entry, &fc->background);
236334f485dSMiklos Szeredi 	if (req->inode)
237334f485dSMiklos Szeredi 		req->inode = igrab(req->inode);
238334f485dSMiklos Szeredi 	if (req->inode2)
239334f485dSMiklos Szeredi 		req->inode2 = igrab(req->inode2);
240334f485dSMiklos Szeredi 	if (req->file)
241334f485dSMiklos Szeredi 		get_file(req->file);
242334f485dSMiklos Szeredi }
243334f485dSMiklos Szeredi 
244334f485dSMiklos Szeredi static int request_wait_answer_nonint(struct fuse_req *req)
245334f485dSMiklos Szeredi {
246334f485dSMiklos Szeredi 	int err;
247334f485dSMiklos Szeredi 	sigset_t oldset;
248334f485dSMiklos Szeredi 	block_sigs(&oldset);
249334f485dSMiklos Szeredi 	err = wait_event_interruptible(req->waitq, req->finished);
250334f485dSMiklos Szeredi 	restore_sigs(&oldset);
251334f485dSMiklos Szeredi 	return err;
252334f485dSMiklos Szeredi }
253334f485dSMiklos Szeredi 
254334f485dSMiklos Szeredi /* Called with fuse_lock held.  Releases, and then reacquires it. */
255*1e9a4ed9SMiklos Szeredi static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req,
256*1e9a4ed9SMiklos Szeredi 				int interruptible)
257334f485dSMiklos Szeredi {
258334f485dSMiklos Szeredi 	int intr;
259334f485dSMiklos Szeredi 
260334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
261334f485dSMiklos Szeredi 	if (interruptible)
262334f485dSMiklos Szeredi 		intr = wait_event_interruptible(req->waitq, req->finished);
263334f485dSMiklos Szeredi 	else
264334f485dSMiklos Szeredi 		intr = request_wait_answer_nonint(req);
265334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
266334f485dSMiklos Szeredi 	if (intr && interruptible && req->sent) {
267334f485dSMiklos Szeredi 		/* If request is already in userspace, only allow KILL
268334f485dSMiklos Szeredi 		   signal to interrupt */
269334f485dSMiklos Szeredi 		spin_unlock(&fuse_lock);
270334f485dSMiklos Szeredi 		intr = request_wait_answer_nonint(req);
271334f485dSMiklos Szeredi 		spin_lock(&fuse_lock);
272334f485dSMiklos Szeredi 	}
273334f485dSMiklos Szeredi 	if (!intr)
274334f485dSMiklos Szeredi 		return;
275334f485dSMiklos Szeredi 
276334f485dSMiklos Szeredi 	if (!interruptible || req->sent)
277334f485dSMiklos Szeredi 		req->out.h.error = -EINTR;
278334f485dSMiklos Szeredi 	else
279334f485dSMiklos Szeredi 		req->out.h.error = -ERESTARTNOINTR;
280334f485dSMiklos Szeredi 
281334f485dSMiklos Szeredi 	req->interrupted = 1;
282334f485dSMiklos Szeredi 	if (req->locked) {
283334f485dSMiklos Szeredi 		/* This is uninterruptible sleep, because data is
284334f485dSMiklos Szeredi 		   being copied to/from the buffers of req.  During
285334f485dSMiklos Szeredi 		   locked state, there mustn't be any filesystem
286334f485dSMiklos Szeredi 		   operation (e.g. page fault), since that could lead
287334f485dSMiklos Szeredi 		   to deadlock */
288334f485dSMiklos Szeredi 		spin_unlock(&fuse_lock);
289334f485dSMiklos Szeredi 		wait_event(req->waitq, !req->locked);
290334f485dSMiklos Szeredi 		spin_lock(&fuse_lock);
291334f485dSMiklos Szeredi 	}
292334f485dSMiklos Szeredi 	if (!req->sent && !list_empty(&req->list)) {
293334f485dSMiklos Szeredi 		list_del(&req->list);
294334f485dSMiklos Szeredi 		__fuse_put_request(req);
295334f485dSMiklos Szeredi 	} else if (!req->finished && req->sent)
296*1e9a4ed9SMiklos Szeredi 		background_request(fc, req);
297334f485dSMiklos Szeredi }
298334f485dSMiklos Szeredi 
299334f485dSMiklos Szeredi static unsigned len_args(unsigned numargs, struct fuse_arg *args)
300334f485dSMiklos Szeredi {
301334f485dSMiklos Szeredi 	unsigned nbytes = 0;
302334f485dSMiklos Szeredi 	unsigned i;
303334f485dSMiklos Szeredi 
304334f485dSMiklos Szeredi 	for (i = 0; i < numargs; i++)
305334f485dSMiklos Szeredi 		nbytes += args[i].size;
306334f485dSMiklos Szeredi 
307334f485dSMiklos Szeredi 	return nbytes;
308334f485dSMiklos Szeredi }
309334f485dSMiklos Szeredi 
310334f485dSMiklos Szeredi static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
311334f485dSMiklos Szeredi {
312334f485dSMiklos Szeredi 	fc->reqctr++;
313334f485dSMiklos Szeredi 	/* zero is special */
314334f485dSMiklos Szeredi 	if (fc->reqctr == 0)
315334f485dSMiklos Szeredi 		fc->reqctr = 1;
316334f485dSMiklos Szeredi 	req->in.h.unique = fc->reqctr;
317334f485dSMiklos Szeredi 	req->in.h.len = sizeof(struct fuse_in_header) +
318334f485dSMiklos Szeredi 		len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
319334f485dSMiklos Szeredi 	if (!req->preallocated) {
320334f485dSMiklos Szeredi 		/* If request is not preallocated (either FORGET or
321334f485dSMiklos Szeredi 		   RELEASE), then still decrease outstanding_sem, so
322334f485dSMiklos Szeredi 		   user can't open infinite number of files while not
323334f485dSMiklos Szeredi 		   processing the RELEASE requests.  However for
324334f485dSMiklos Szeredi 		   efficiency do it without blocking, so if down()
325334f485dSMiklos Szeredi 		   would block, just increase the debt instead */
326334f485dSMiklos Szeredi 		if (down_trylock(&fc->outstanding_sem))
327334f485dSMiklos Szeredi 			fc->outstanding_debt++;
328334f485dSMiklos Szeredi 	}
329334f485dSMiklos Szeredi 	list_add_tail(&req->list, &fc->pending);
330334f485dSMiklos Szeredi 	wake_up(&fc->waitq);
331334f485dSMiklos Szeredi }
332334f485dSMiklos Szeredi 
333334f485dSMiklos Szeredi static void request_send_wait(struct fuse_conn *fc, struct fuse_req *req,
334334f485dSMiklos Szeredi 			      int interruptible)
335334f485dSMiklos Szeredi {
336334f485dSMiklos Szeredi 	req->isreply = 1;
337334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
338*1e9a4ed9SMiklos Szeredi 	if (!fc->connected)
339334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
340334f485dSMiklos Szeredi 	else if (fc->conn_error)
341334f485dSMiklos Szeredi 		req->out.h.error = -ECONNREFUSED;
342334f485dSMiklos Szeredi 	else {
343334f485dSMiklos Szeredi 		queue_request(fc, req);
344334f485dSMiklos Szeredi 		/* acquire extra reference, since request is still needed
345334f485dSMiklos Szeredi 		   after request_end() */
346334f485dSMiklos Szeredi 		__fuse_get_request(req);
347334f485dSMiklos Szeredi 
348*1e9a4ed9SMiklos Szeredi 		request_wait_answer(fc, req, interruptible);
349334f485dSMiklos Szeredi 	}
350334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
351334f485dSMiklos Szeredi }
352334f485dSMiklos Szeredi 
353334f485dSMiklos Szeredi void request_send(struct fuse_conn *fc, struct fuse_req *req)
354334f485dSMiklos Szeredi {
355334f485dSMiklos Szeredi 	request_send_wait(fc, req, 1);
356334f485dSMiklos Szeredi }
357334f485dSMiklos Szeredi 
358334f485dSMiklos Szeredi /*
359334f485dSMiklos Szeredi  * Non-interruptible version of the above function is for operations
360334f485dSMiklos Szeredi  * which can't legally return -ERESTART{SYS,NOINTR}.  This can still
361334f485dSMiklos Szeredi  * be interrupted but only with SIGKILL.
362334f485dSMiklos Szeredi  */
363334f485dSMiklos Szeredi void request_send_nonint(struct fuse_conn *fc, struct fuse_req *req)
364334f485dSMiklos Szeredi {
365334f485dSMiklos Szeredi 	request_send_wait(fc, req, 0);
366334f485dSMiklos Szeredi }
367334f485dSMiklos Szeredi 
368334f485dSMiklos Szeredi static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
369334f485dSMiklos Szeredi {
370334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
371*1e9a4ed9SMiklos Szeredi 	if (fc->connected) {
372334f485dSMiklos Szeredi 		queue_request(fc, req);
373334f485dSMiklos Szeredi 		spin_unlock(&fuse_lock);
374334f485dSMiklos Szeredi 	} else {
375334f485dSMiklos Szeredi 		req->out.h.error = -ENOTCONN;
376334f485dSMiklos Szeredi 		request_end(fc, req);
377334f485dSMiklos Szeredi 	}
378334f485dSMiklos Szeredi }
379334f485dSMiklos Szeredi 
380334f485dSMiklos Szeredi void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req)
381334f485dSMiklos Szeredi {
382334f485dSMiklos Szeredi 	req->isreply = 0;
383334f485dSMiklos Szeredi 	request_send_nowait(fc, req);
384334f485dSMiklos Szeredi }
385334f485dSMiklos Szeredi 
386334f485dSMiklos Szeredi void request_send_background(struct fuse_conn *fc, struct fuse_req *req)
387334f485dSMiklos Szeredi {
388334f485dSMiklos Szeredi 	req->isreply = 1;
389*1e9a4ed9SMiklos Szeredi 	spin_lock(&fuse_lock);
390*1e9a4ed9SMiklos Szeredi 	background_request(fc, req);
391*1e9a4ed9SMiklos Szeredi 	spin_unlock(&fuse_lock);
392334f485dSMiklos Szeredi 	request_send_nowait(fc, req);
393334f485dSMiklos Szeredi }
394334f485dSMiklos Szeredi 
395334f485dSMiklos Szeredi void fuse_send_init(struct fuse_conn *fc)
396334f485dSMiklos Szeredi {
397334f485dSMiklos Szeredi 	/* This is called from fuse_read_super() so there's guaranteed
398334f485dSMiklos Szeredi 	   to be a request available */
399334f485dSMiklos Szeredi 	struct fuse_req *req = do_get_request(fc);
400334f485dSMiklos Szeredi 	struct fuse_init_in_out *arg = &req->misc.init_in_out;
401334f485dSMiklos Szeredi 	arg->major = FUSE_KERNEL_VERSION;
402334f485dSMiklos Szeredi 	arg->minor = FUSE_KERNEL_MINOR_VERSION;
403334f485dSMiklos Szeredi 	req->in.h.opcode = FUSE_INIT;
404334f485dSMiklos Szeredi 	req->in.numargs = 1;
405334f485dSMiklos Szeredi 	req->in.args[0].size = sizeof(*arg);
406334f485dSMiklos Szeredi 	req->in.args[0].value = arg;
407334f485dSMiklos Szeredi 	req->out.numargs = 1;
408334f485dSMiklos Szeredi 	req->out.args[0].size = sizeof(*arg);
409334f485dSMiklos Szeredi 	req->out.args[0].value = arg;
410334f485dSMiklos Szeredi 	request_send_background(fc, req);
411334f485dSMiklos Szeredi }
412334f485dSMiklos Szeredi 
413334f485dSMiklos Szeredi /*
414334f485dSMiklos Szeredi  * Lock the request.  Up to the next unlock_request() there mustn't be
415334f485dSMiklos Szeredi  * anything that could cause a page-fault.  If the request was already
416334f485dSMiklos Szeredi  * interrupted bail out.
417334f485dSMiklos Szeredi  */
418334f485dSMiklos Szeredi static inline int lock_request(struct fuse_req *req)
419334f485dSMiklos Szeredi {
420334f485dSMiklos Szeredi 	int err = 0;
421334f485dSMiklos Szeredi 	if (req) {
422334f485dSMiklos Szeredi 		spin_lock(&fuse_lock);
423334f485dSMiklos Szeredi 		if (req->interrupted)
424334f485dSMiklos Szeredi 			err = -ENOENT;
425334f485dSMiklos Szeredi 		else
426334f485dSMiklos Szeredi 			req->locked = 1;
427334f485dSMiklos Szeredi 		spin_unlock(&fuse_lock);
428334f485dSMiklos Szeredi 	}
429334f485dSMiklos Szeredi 	return err;
430334f485dSMiklos Szeredi }
431334f485dSMiklos Szeredi 
432334f485dSMiklos Szeredi /*
433334f485dSMiklos Szeredi  * Unlock request.  If it was interrupted during being locked, the
434334f485dSMiklos Szeredi  * requester thread is currently waiting for it to be unlocked, so
435334f485dSMiklos Szeredi  * wake it up.
436334f485dSMiklos Szeredi  */
437334f485dSMiklos Szeredi static inline void unlock_request(struct fuse_req *req)
438334f485dSMiklos Szeredi {
439334f485dSMiklos Szeredi 	if (req) {
440334f485dSMiklos Szeredi 		spin_lock(&fuse_lock);
441334f485dSMiklos Szeredi 		req->locked = 0;
442334f485dSMiklos Szeredi 		if (req->interrupted)
443334f485dSMiklos Szeredi 			wake_up(&req->waitq);
444334f485dSMiklos Szeredi 		spin_unlock(&fuse_lock);
445334f485dSMiklos Szeredi 	}
446334f485dSMiklos Szeredi }
447334f485dSMiklos Szeredi 
448334f485dSMiklos Szeredi struct fuse_copy_state {
449334f485dSMiklos Szeredi 	int write;
450334f485dSMiklos Szeredi 	struct fuse_req *req;
451334f485dSMiklos Szeredi 	const struct iovec *iov;
452334f485dSMiklos Szeredi 	unsigned long nr_segs;
453334f485dSMiklos Szeredi 	unsigned long seglen;
454334f485dSMiklos Szeredi 	unsigned long addr;
455334f485dSMiklos Szeredi 	struct page *pg;
456334f485dSMiklos Szeredi 	void *mapaddr;
457334f485dSMiklos Szeredi 	void *buf;
458334f485dSMiklos Szeredi 	unsigned len;
459334f485dSMiklos Szeredi };
460334f485dSMiklos Szeredi 
461334f485dSMiklos Szeredi static void fuse_copy_init(struct fuse_copy_state *cs, int write,
462334f485dSMiklos Szeredi 			   struct fuse_req *req, const struct iovec *iov,
463334f485dSMiklos Szeredi 			   unsigned long nr_segs)
464334f485dSMiklos Szeredi {
465334f485dSMiklos Szeredi 	memset(cs, 0, sizeof(*cs));
466334f485dSMiklos Szeredi 	cs->write = write;
467334f485dSMiklos Szeredi 	cs->req = req;
468334f485dSMiklos Szeredi 	cs->iov = iov;
469334f485dSMiklos Szeredi 	cs->nr_segs = nr_segs;
470334f485dSMiklos Szeredi }
471334f485dSMiklos Szeredi 
472334f485dSMiklos Szeredi /* Unmap and put previous page of userspace buffer */
473334f485dSMiklos Szeredi static inline void fuse_copy_finish(struct fuse_copy_state *cs)
474334f485dSMiklos Szeredi {
475334f485dSMiklos Szeredi 	if (cs->mapaddr) {
476334f485dSMiklos Szeredi 		kunmap_atomic(cs->mapaddr, KM_USER0);
477334f485dSMiklos Szeredi 		if (cs->write) {
478334f485dSMiklos Szeredi 			flush_dcache_page(cs->pg);
479334f485dSMiklos Szeredi 			set_page_dirty_lock(cs->pg);
480334f485dSMiklos Szeredi 		}
481334f485dSMiklos Szeredi 		put_page(cs->pg);
482334f485dSMiklos Szeredi 		cs->mapaddr = NULL;
483334f485dSMiklos Szeredi 	}
484334f485dSMiklos Szeredi }
485334f485dSMiklos Szeredi 
486334f485dSMiklos Szeredi /*
487334f485dSMiklos Szeredi  * Get another pagefull of userspace buffer, and map it to kernel
488334f485dSMiklos Szeredi  * address space, and lock request
489334f485dSMiklos Szeredi  */
490334f485dSMiklos Szeredi static int fuse_copy_fill(struct fuse_copy_state *cs)
491334f485dSMiklos Szeredi {
492334f485dSMiklos Szeredi 	unsigned long offset;
493334f485dSMiklos Szeredi 	int err;
494334f485dSMiklos Szeredi 
495334f485dSMiklos Szeredi 	unlock_request(cs->req);
496334f485dSMiklos Szeredi 	fuse_copy_finish(cs);
497334f485dSMiklos Szeredi 	if (!cs->seglen) {
498334f485dSMiklos Szeredi 		BUG_ON(!cs->nr_segs);
499334f485dSMiklos Szeredi 		cs->seglen = cs->iov[0].iov_len;
500334f485dSMiklos Szeredi 		cs->addr = (unsigned long) cs->iov[0].iov_base;
501334f485dSMiklos Szeredi 		cs->iov ++;
502334f485dSMiklos Szeredi 		cs->nr_segs --;
503334f485dSMiklos Szeredi 	}
504334f485dSMiklos Szeredi 	down_read(&current->mm->mmap_sem);
505334f485dSMiklos Szeredi 	err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
506334f485dSMiklos Szeredi 			     &cs->pg, NULL);
507334f485dSMiklos Szeredi 	up_read(&current->mm->mmap_sem);
508334f485dSMiklos Szeredi 	if (err < 0)
509334f485dSMiklos Szeredi 		return err;
510334f485dSMiklos Szeredi 	BUG_ON(err != 1);
511334f485dSMiklos Szeredi 	offset = cs->addr % PAGE_SIZE;
512334f485dSMiklos Szeredi 	cs->mapaddr = kmap_atomic(cs->pg, KM_USER0);
513334f485dSMiklos Szeredi 	cs->buf = cs->mapaddr + offset;
514334f485dSMiklos Szeredi 	cs->len = min(PAGE_SIZE - offset, cs->seglen);
515334f485dSMiklos Szeredi 	cs->seglen -= cs->len;
516334f485dSMiklos Szeredi 	cs->addr += cs->len;
517334f485dSMiklos Szeredi 
518334f485dSMiklos Szeredi 	return lock_request(cs->req);
519334f485dSMiklos Szeredi }
520334f485dSMiklos Szeredi 
521334f485dSMiklos Szeredi /* Do as much copy to/from userspace buffer as we can */
522334f485dSMiklos Szeredi static inline int fuse_copy_do(struct fuse_copy_state *cs, void **val,
523334f485dSMiklos Szeredi 			       unsigned *size)
524334f485dSMiklos Szeredi {
525334f485dSMiklos Szeredi 	unsigned ncpy = min(*size, cs->len);
526334f485dSMiklos Szeredi 	if (val) {
527334f485dSMiklos Szeredi 		if (cs->write)
528334f485dSMiklos Szeredi 			memcpy(cs->buf, *val, ncpy);
529334f485dSMiklos Szeredi 		else
530334f485dSMiklos Szeredi 			memcpy(*val, cs->buf, ncpy);
531334f485dSMiklos Szeredi 		*val += ncpy;
532334f485dSMiklos Szeredi 	}
533334f485dSMiklos Szeredi 	*size -= ncpy;
534334f485dSMiklos Szeredi 	cs->len -= ncpy;
535334f485dSMiklos Szeredi 	cs->buf += ncpy;
536334f485dSMiklos Szeredi 	return ncpy;
537334f485dSMiklos Szeredi }
538334f485dSMiklos Szeredi 
539334f485dSMiklos Szeredi /*
540334f485dSMiklos Szeredi  * Copy a page in the request to/from the userspace buffer.  Must be
541334f485dSMiklos Szeredi  * done atomically
542334f485dSMiklos Szeredi  */
543334f485dSMiklos Szeredi static inline int fuse_copy_page(struct fuse_copy_state *cs, struct page *page,
544334f485dSMiklos Szeredi 				 unsigned offset, unsigned count, int zeroing)
545334f485dSMiklos Szeredi {
546334f485dSMiklos Szeredi 	if (page && zeroing && count < PAGE_SIZE) {
547334f485dSMiklos Szeredi 		void *mapaddr = kmap_atomic(page, KM_USER1);
548334f485dSMiklos Szeredi 		memset(mapaddr, 0, PAGE_SIZE);
549334f485dSMiklos Szeredi 		kunmap_atomic(mapaddr, KM_USER1);
550334f485dSMiklos Szeredi 	}
551334f485dSMiklos Szeredi 	while (count) {
552334f485dSMiklos Szeredi 		int err;
553334f485dSMiklos Szeredi 		if (!cs->len && (err = fuse_copy_fill(cs)))
554334f485dSMiklos Szeredi 			return err;
555334f485dSMiklos Szeredi 		if (page) {
556334f485dSMiklos Szeredi 			void *mapaddr = kmap_atomic(page, KM_USER1);
557334f485dSMiklos Szeredi 			void *buf = mapaddr + offset;
558334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, &buf, &count);
559334f485dSMiklos Szeredi 			kunmap_atomic(mapaddr, KM_USER1);
560334f485dSMiklos Szeredi 		} else
561334f485dSMiklos Szeredi 			offset += fuse_copy_do(cs, NULL, &count);
562334f485dSMiklos Szeredi 	}
563334f485dSMiklos Szeredi 	if (page && !cs->write)
564334f485dSMiklos Szeredi 		flush_dcache_page(page);
565334f485dSMiklos Szeredi 	return 0;
566334f485dSMiklos Szeredi }
567334f485dSMiklos Szeredi 
568334f485dSMiklos Szeredi /* Copy pages in the request to/from userspace buffer */
569334f485dSMiklos Szeredi static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
570334f485dSMiklos Szeredi 			   int zeroing)
571334f485dSMiklos Szeredi {
572334f485dSMiklos Szeredi 	unsigned i;
573334f485dSMiklos Szeredi 	struct fuse_req *req = cs->req;
574334f485dSMiklos Szeredi 	unsigned offset = req->page_offset;
575334f485dSMiklos Szeredi 	unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);
576334f485dSMiklos Szeredi 
577334f485dSMiklos Szeredi 	for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
578334f485dSMiklos Szeredi 		struct page *page = req->pages[i];
579334f485dSMiklos Szeredi 		int err = fuse_copy_page(cs, page, offset, count, zeroing);
580334f485dSMiklos Szeredi 		if (err)
581334f485dSMiklos Szeredi 			return err;
582334f485dSMiklos Szeredi 
583334f485dSMiklos Szeredi 		nbytes -= count;
584334f485dSMiklos Szeredi 		count = min(nbytes, (unsigned) PAGE_SIZE);
585334f485dSMiklos Szeredi 		offset = 0;
586334f485dSMiklos Szeredi 	}
587334f485dSMiklos Szeredi 	return 0;
588334f485dSMiklos Szeredi }
589334f485dSMiklos Szeredi 
590334f485dSMiklos Szeredi /* Copy a single argument in the request to/from userspace buffer */
591334f485dSMiklos Szeredi static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
592334f485dSMiklos Szeredi {
593334f485dSMiklos Szeredi 	while (size) {
594334f485dSMiklos Szeredi 		int err;
595334f485dSMiklos Szeredi 		if (!cs->len && (err = fuse_copy_fill(cs)))
596334f485dSMiklos Szeredi 			return err;
597334f485dSMiklos Szeredi 		fuse_copy_do(cs, &val, &size);
598334f485dSMiklos Szeredi 	}
599334f485dSMiklos Szeredi 	return 0;
600334f485dSMiklos Szeredi }
601334f485dSMiklos Szeredi 
602334f485dSMiklos Szeredi /* Copy request arguments to/from userspace buffer */
603334f485dSMiklos Szeredi static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
604334f485dSMiklos Szeredi 			  unsigned argpages, struct fuse_arg *args,
605334f485dSMiklos Szeredi 			  int zeroing)
606334f485dSMiklos Szeredi {
607334f485dSMiklos Szeredi 	int err = 0;
608334f485dSMiklos Szeredi 	unsigned i;
609334f485dSMiklos Szeredi 
610334f485dSMiklos Szeredi 	for (i = 0; !err && i < numargs; i++)  {
611334f485dSMiklos Szeredi 		struct fuse_arg *arg = &args[i];
612334f485dSMiklos Szeredi 		if (i == numargs - 1 && argpages)
613334f485dSMiklos Szeredi 			err = fuse_copy_pages(cs, arg->size, zeroing);
614334f485dSMiklos Szeredi 		else
615334f485dSMiklos Szeredi 			err = fuse_copy_one(cs, arg->value, arg->size);
616334f485dSMiklos Szeredi 	}
617334f485dSMiklos Szeredi 	return err;
618334f485dSMiklos Szeredi }
619334f485dSMiklos Szeredi 
620334f485dSMiklos Szeredi /* Wait until a request is available on the pending list */
621334f485dSMiklos Szeredi static void request_wait(struct fuse_conn *fc)
622334f485dSMiklos Szeredi {
623334f485dSMiklos Szeredi 	DECLARE_WAITQUEUE(wait, current);
624334f485dSMiklos Szeredi 
625334f485dSMiklos Szeredi 	add_wait_queue_exclusive(&fc->waitq, &wait);
626*1e9a4ed9SMiklos Szeredi 	while (fc->mounted && list_empty(&fc->pending)) {
627334f485dSMiklos Szeredi 		set_current_state(TASK_INTERRUPTIBLE);
628334f485dSMiklos Szeredi 		if (signal_pending(current))
629334f485dSMiklos Szeredi 			break;
630334f485dSMiklos Szeredi 
631334f485dSMiklos Szeredi 		spin_unlock(&fuse_lock);
632334f485dSMiklos Szeredi 		schedule();
633334f485dSMiklos Szeredi 		spin_lock(&fuse_lock);
634334f485dSMiklos Szeredi 	}
635334f485dSMiklos Szeredi 	set_current_state(TASK_RUNNING);
636334f485dSMiklos Szeredi 	remove_wait_queue(&fc->waitq, &wait);
637334f485dSMiklos Szeredi }
638334f485dSMiklos Szeredi 
639334f485dSMiklos Szeredi /*
640334f485dSMiklos Szeredi  * Read a single request into the userspace filesystem's buffer.  This
641334f485dSMiklos Szeredi  * function waits until a request is available, then removes it from
642334f485dSMiklos Szeredi  * the pending list and copies request data to userspace buffer.  If
643334f485dSMiklos Szeredi  * no reply is needed (FORGET) or request has been interrupted or
644334f485dSMiklos Szeredi  * there was an error during the copying then it's finished by calling
645334f485dSMiklos Szeredi  * request_end().  Otherwise add it to the processing list, and set
646334f485dSMiklos Szeredi  * the 'sent' flag.
647334f485dSMiklos Szeredi  */
648334f485dSMiklos Szeredi static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
649334f485dSMiklos Szeredi 			      unsigned long nr_segs, loff_t *off)
650334f485dSMiklos Szeredi {
651334f485dSMiklos Szeredi 	int err;
652334f485dSMiklos Szeredi 	struct fuse_conn *fc;
653334f485dSMiklos Szeredi 	struct fuse_req *req;
654334f485dSMiklos Szeredi 	struct fuse_in *in;
655334f485dSMiklos Szeredi 	struct fuse_copy_state cs;
656334f485dSMiklos Szeredi 	unsigned reqsize;
657334f485dSMiklos Szeredi 
658334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
659334f485dSMiklos Szeredi 	fc = file->private_data;
660334f485dSMiklos Szeredi 	err = -EPERM;
661334f485dSMiklos Szeredi 	if (!fc)
662334f485dSMiklos Szeredi 		goto err_unlock;
663334f485dSMiklos Szeredi 	request_wait(fc);
664334f485dSMiklos Szeredi 	err = -ENODEV;
665*1e9a4ed9SMiklos Szeredi 	if (!fc->mounted)
666334f485dSMiklos Szeredi 		goto err_unlock;
667334f485dSMiklos Szeredi 	err = -ERESTARTSYS;
668334f485dSMiklos Szeredi 	if (list_empty(&fc->pending))
669334f485dSMiklos Szeredi 		goto err_unlock;
670334f485dSMiklos Szeredi 
671334f485dSMiklos Szeredi 	req = list_entry(fc->pending.next, struct fuse_req, list);
672334f485dSMiklos Szeredi 	list_del_init(&req->list);
673334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
674334f485dSMiklos Szeredi 
675334f485dSMiklos Szeredi 	in = &req->in;
676334f485dSMiklos Szeredi 	reqsize = req->in.h.len;
677334f485dSMiklos Szeredi 	fuse_copy_init(&cs, 1, req, iov, nr_segs);
678334f485dSMiklos Szeredi 	err = -EINVAL;
679334f485dSMiklos Szeredi 	if (iov_length(iov, nr_segs) >= reqsize) {
680334f485dSMiklos Szeredi 		err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
681334f485dSMiklos Szeredi 		if (!err)
682334f485dSMiklos Szeredi 			err = fuse_copy_args(&cs, in->numargs, in->argpages,
683334f485dSMiklos Szeredi 					     (struct fuse_arg *) in->args, 0);
684334f485dSMiklos Szeredi 	}
685334f485dSMiklos Szeredi 	fuse_copy_finish(&cs);
686334f485dSMiklos Szeredi 
687334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
688334f485dSMiklos Szeredi 	req->locked = 0;
689334f485dSMiklos Szeredi 	if (!err && req->interrupted)
690334f485dSMiklos Szeredi 		err = -ENOENT;
691334f485dSMiklos Szeredi 	if (err) {
692334f485dSMiklos Szeredi 		if (!req->interrupted)
693334f485dSMiklos Szeredi 			req->out.h.error = -EIO;
694334f485dSMiklos Szeredi 		request_end(fc, req);
695334f485dSMiklos Szeredi 		return err;
696334f485dSMiklos Szeredi 	}
697334f485dSMiklos Szeredi 	if (!req->isreply)
698334f485dSMiklos Szeredi 		request_end(fc, req);
699334f485dSMiklos Szeredi 	else {
700334f485dSMiklos Szeredi 		req->sent = 1;
701334f485dSMiklos Szeredi 		list_add_tail(&req->list, &fc->processing);
702334f485dSMiklos Szeredi 		spin_unlock(&fuse_lock);
703334f485dSMiklos Szeredi 	}
704334f485dSMiklos Szeredi 	return reqsize;
705334f485dSMiklos Szeredi 
706334f485dSMiklos Szeredi  err_unlock:
707334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
708334f485dSMiklos Szeredi 	return err;
709334f485dSMiklos Szeredi }
710334f485dSMiklos Szeredi 
711334f485dSMiklos Szeredi static ssize_t fuse_dev_read(struct file *file, char __user *buf,
712334f485dSMiklos Szeredi 			     size_t nbytes, loff_t *off)
713334f485dSMiklos Szeredi {
714334f485dSMiklos Szeredi 	struct iovec iov;
715334f485dSMiklos Szeredi 	iov.iov_len = nbytes;
716334f485dSMiklos Szeredi 	iov.iov_base = buf;
717334f485dSMiklos Szeredi 	return fuse_dev_readv(file, &iov, 1, off);
718334f485dSMiklos Szeredi }
719334f485dSMiklos Szeredi 
720334f485dSMiklos Szeredi /* Look up request on processing list by unique ID */
721334f485dSMiklos Szeredi static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
722334f485dSMiklos Szeredi {
723334f485dSMiklos Szeredi 	struct list_head *entry;
724334f485dSMiklos Szeredi 
725334f485dSMiklos Szeredi 	list_for_each(entry, &fc->processing) {
726334f485dSMiklos Szeredi 		struct fuse_req *req;
727334f485dSMiklos Szeredi 		req = list_entry(entry, struct fuse_req, list);
728334f485dSMiklos Szeredi 		if (req->in.h.unique == unique)
729334f485dSMiklos Szeredi 			return req;
730334f485dSMiklos Szeredi 	}
731334f485dSMiklos Szeredi 	return NULL;
732334f485dSMiklos Szeredi }
733334f485dSMiklos Szeredi 
734e5e5558eSMiklos Szeredi /* fget() needs to be done in this context */
735e5e5558eSMiklos Szeredi static void process_getdir(struct fuse_req *req)
736e5e5558eSMiklos Szeredi {
737e5e5558eSMiklos Szeredi 	struct fuse_getdir_out_i *arg = req->out.args[0].value;
738e5e5558eSMiklos Szeredi 	arg->file = fget(arg->fd);
739e5e5558eSMiklos Szeredi }
740e5e5558eSMiklos Szeredi 
741334f485dSMiklos Szeredi static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
742334f485dSMiklos Szeredi 			 unsigned nbytes)
743334f485dSMiklos Szeredi {
744334f485dSMiklos Szeredi 	unsigned reqsize = sizeof(struct fuse_out_header);
745334f485dSMiklos Szeredi 
746334f485dSMiklos Szeredi 	if (out->h.error)
747334f485dSMiklos Szeredi 		return nbytes != reqsize ? -EINVAL : 0;
748334f485dSMiklos Szeredi 
749334f485dSMiklos Szeredi 	reqsize += len_args(out->numargs, out->args);
750334f485dSMiklos Szeredi 
751334f485dSMiklos Szeredi 	if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))
752334f485dSMiklos Szeredi 		return -EINVAL;
753334f485dSMiklos Szeredi 	else if (reqsize > nbytes) {
754334f485dSMiklos Szeredi 		struct fuse_arg *lastarg = &out->args[out->numargs-1];
755334f485dSMiklos Szeredi 		unsigned diffsize = reqsize - nbytes;
756334f485dSMiklos Szeredi 		if (diffsize > lastarg->size)
757334f485dSMiklos Szeredi 			return -EINVAL;
758334f485dSMiklos Szeredi 		lastarg->size -= diffsize;
759334f485dSMiklos Szeredi 	}
760334f485dSMiklos Szeredi 	return fuse_copy_args(cs, out->numargs, out->argpages, out->args,
761334f485dSMiklos Szeredi 			      out->page_zeroing);
762334f485dSMiklos Szeredi }
763334f485dSMiklos Szeredi 
764334f485dSMiklos Szeredi /*
765334f485dSMiklos Szeredi  * Write a single reply to a request.  First the header is copied from
766334f485dSMiklos Szeredi  * the write buffer.  The request is then searched on the processing
767334f485dSMiklos Szeredi  * list by the unique ID found in the header.  If found, then remove
768334f485dSMiklos Szeredi  * it from the list and copy the rest of the buffer to the request.
769334f485dSMiklos Szeredi  * The request is finished by calling request_end()
770334f485dSMiklos Szeredi  */
771334f485dSMiklos Szeredi static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
772334f485dSMiklos Szeredi 			       unsigned long nr_segs, loff_t *off)
773334f485dSMiklos Szeredi {
774334f485dSMiklos Szeredi 	int err;
775334f485dSMiklos Szeredi 	unsigned nbytes = iov_length(iov, nr_segs);
776334f485dSMiklos Szeredi 	struct fuse_req *req;
777334f485dSMiklos Szeredi 	struct fuse_out_header oh;
778334f485dSMiklos Szeredi 	struct fuse_copy_state cs;
779334f485dSMiklos Szeredi 	struct fuse_conn *fc = fuse_get_conn(file);
780334f485dSMiklos Szeredi 	if (!fc)
781334f485dSMiklos Szeredi 		return -ENODEV;
782334f485dSMiklos Szeredi 
783334f485dSMiklos Szeredi 	fuse_copy_init(&cs, 0, NULL, iov, nr_segs);
784334f485dSMiklos Szeredi 	if (nbytes < sizeof(struct fuse_out_header))
785334f485dSMiklos Szeredi 		return -EINVAL;
786334f485dSMiklos Szeredi 
787334f485dSMiklos Szeredi 	err = fuse_copy_one(&cs, &oh, sizeof(oh));
788334f485dSMiklos Szeredi 	if (err)
789334f485dSMiklos Szeredi 		goto err_finish;
790334f485dSMiklos Szeredi 	err = -EINVAL;
791334f485dSMiklos Szeredi 	if (!oh.unique || oh.error <= -1000 || oh.error > 0 ||
792334f485dSMiklos Szeredi 	    oh.len != nbytes)
793334f485dSMiklos Szeredi 		goto err_finish;
794334f485dSMiklos Szeredi 
795334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
796334f485dSMiklos Szeredi 	req = request_find(fc, oh.unique);
797334f485dSMiklos Szeredi 	err = -EINVAL;
798334f485dSMiklos Szeredi 	if (!req)
799334f485dSMiklos Szeredi 		goto err_unlock;
800334f485dSMiklos Szeredi 
801334f485dSMiklos Szeredi 	list_del_init(&req->list);
802334f485dSMiklos Szeredi 	if (req->interrupted) {
803334f485dSMiklos Szeredi 		request_end(fc, req);
804334f485dSMiklos Szeredi 		fuse_copy_finish(&cs);
805334f485dSMiklos Szeredi 		return -ENOENT;
806334f485dSMiklos Szeredi 	}
807334f485dSMiklos Szeredi 	req->out.h = oh;
808334f485dSMiklos Szeredi 	req->locked = 1;
809334f485dSMiklos Szeredi 	cs.req = req;
810334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
811334f485dSMiklos Szeredi 
812334f485dSMiklos Szeredi 	err = copy_out_args(&cs, &req->out, nbytes);
813334f485dSMiklos Szeredi 	fuse_copy_finish(&cs);
814334f485dSMiklos Szeredi 
815334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
816334f485dSMiklos Szeredi 	req->locked = 0;
817334f485dSMiklos Szeredi 	if (!err) {
818334f485dSMiklos Szeredi 		if (req->interrupted)
819334f485dSMiklos Szeredi 			err = -ENOENT;
820e5e5558eSMiklos Szeredi 		else if (req->in.h.opcode == FUSE_GETDIR && !oh.error)
821e5e5558eSMiklos Szeredi 			process_getdir(req);
822334f485dSMiklos Szeredi 	} else if (!req->interrupted)
823334f485dSMiklos Szeredi 		req->out.h.error = -EIO;
824334f485dSMiklos Szeredi 	request_end(fc, req);
825334f485dSMiklos Szeredi 
826334f485dSMiklos Szeredi 	return err ? err : nbytes;
827334f485dSMiklos Szeredi 
828334f485dSMiklos Szeredi  err_unlock:
829334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
830334f485dSMiklos Szeredi  err_finish:
831334f485dSMiklos Szeredi 	fuse_copy_finish(&cs);
832334f485dSMiklos Szeredi 	return err;
833334f485dSMiklos Szeredi }
834334f485dSMiklos Szeredi 
835334f485dSMiklos Szeredi static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
836334f485dSMiklos Szeredi 			      size_t nbytes, loff_t *off)
837334f485dSMiklos Szeredi {
838334f485dSMiklos Szeredi 	struct iovec iov;
839334f485dSMiklos Szeredi 	iov.iov_len = nbytes;
840334f485dSMiklos Szeredi 	iov.iov_base = (char __user *) buf;
841334f485dSMiklos Szeredi 	return fuse_dev_writev(file, &iov, 1, off);
842334f485dSMiklos Szeredi }
843334f485dSMiklos Szeredi 
844334f485dSMiklos Szeredi static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
845334f485dSMiklos Szeredi {
846334f485dSMiklos Szeredi 	struct fuse_conn *fc = fuse_get_conn(file);
847334f485dSMiklos Szeredi 	unsigned mask = POLLOUT | POLLWRNORM;
848334f485dSMiklos Szeredi 
849334f485dSMiklos Szeredi 	if (!fc)
850334f485dSMiklos Szeredi 		return -ENODEV;
851334f485dSMiklos Szeredi 
852334f485dSMiklos Szeredi 	poll_wait(file, &fc->waitq, wait);
853334f485dSMiklos Szeredi 
854334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
855334f485dSMiklos Szeredi 	if (!list_empty(&fc->pending))
856334f485dSMiklos Szeredi                 mask |= POLLIN | POLLRDNORM;
857334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
858334f485dSMiklos Szeredi 
859334f485dSMiklos Szeredi 	return mask;
860334f485dSMiklos Szeredi }
861334f485dSMiklos Szeredi 
862334f485dSMiklos Szeredi /* Abort all requests on the given list (pending or processing) */
863334f485dSMiklos Szeredi static void end_requests(struct fuse_conn *fc, struct list_head *head)
864334f485dSMiklos Szeredi {
865334f485dSMiklos Szeredi 	while (!list_empty(head)) {
866334f485dSMiklos Szeredi 		struct fuse_req *req;
867334f485dSMiklos Szeredi 		req = list_entry(head->next, struct fuse_req, list);
868334f485dSMiklos Szeredi 		list_del_init(&req->list);
869334f485dSMiklos Szeredi 		req->out.h.error = -ECONNABORTED;
870334f485dSMiklos Szeredi 		request_end(fc, req);
871334f485dSMiklos Szeredi 		spin_lock(&fuse_lock);
872334f485dSMiklos Szeredi 	}
873334f485dSMiklos Szeredi }
874334f485dSMiklos Szeredi 
875334f485dSMiklos Szeredi static int fuse_dev_release(struct inode *inode, struct file *file)
876334f485dSMiklos Szeredi {
877334f485dSMiklos Szeredi 	struct fuse_conn *fc;
878334f485dSMiklos Szeredi 
879334f485dSMiklos Szeredi 	spin_lock(&fuse_lock);
880334f485dSMiklos Szeredi 	fc = file->private_data;
881334f485dSMiklos Szeredi 	if (fc) {
882*1e9a4ed9SMiklos Szeredi 		fc->connected = 0;
883334f485dSMiklos Szeredi 		end_requests(fc, &fc->pending);
884334f485dSMiklos Szeredi 		end_requests(fc, &fc->processing);
885334f485dSMiklos Szeredi 		fuse_release_conn(fc);
886334f485dSMiklos Szeredi 	}
887334f485dSMiklos Szeredi 	spin_unlock(&fuse_lock);
888334f485dSMiklos Szeredi 	return 0;
889334f485dSMiklos Szeredi }
890334f485dSMiklos Szeredi 
891334f485dSMiklos Szeredi struct file_operations fuse_dev_operations = {
892334f485dSMiklos Szeredi 	.owner		= THIS_MODULE,
893334f485dSMiklos Szeredi 	.llseek		= no_llseek,
894334f485dSMiklos Szeredi 	.read		= fuse_dev_read,
895334f485dSMiklos Szeredi 	.readv		= fuse_dev_readv,
896334f485dSMiklos Szeredi 	.write		= fuse_dev_write,
897334f485dSMiklos Szeredi 	.writev		= fuse_dev_writev,
898334f485dSMiklos Szeredi 	.poll		= fuse_dev_poll,
899334f485dSMiklos Szeredi 	.release	= fuse_dev_release,
900334f485dSMiklos Szeredi };
901334f485dSMiklos Szeredi 
902334f485dSMiklos Szeredi static struct miscdevice fuse_miscdevice = {
903334f485dSMiklos Szeredi 	.minor = FUSE_MINOR,
904334f485dSMiklos Szeredi 	.name  = "fuse",
905334f485dSMiklos Szeredi 	.fops = &fuse_dev_operations,
906334f485dSMiklos Szeredi };
907334f485dSMiklos Szeredi 
908334f485dSMiklos Szeredi int __init fuse_dev_init(void)
909334f485dSMiklos Szeredi {
910334f485dSMiklos Szeredi 	int err = -ENOMEM;
911334f485dSMiklos Szeredi 	fuse_req_cachep = kmem_cache_create("fuse_request",
912334f485dSMiklos Szeredi 					    sizeof(struct fuse_req),
913334f485dSMiklos Szeredi 					    0, 0, NULL, NULL);
914334f485dSMiklos Szeredi 	if (!fuse_req_cachep)
915334f485dSMiklos Szeredi 		goto out;
916334f485dSMiklos Szeredi 
917334f485dSMiklos Szeredi 	err = misc_register(&fuse_miscdevice);
918334f485dSMiklos Szeredi 	if (err)
919334f485dSMiklos Szeredi 		goto out_cache_clean;
920334f485dSMiklos Szeredi 
921334f485dSMiklos Szeredi 	return 0;
922334f485dSMiklos Szeredi 
923334f485dSMiklos Szeredi  out_cache_clean:
924334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
925334f485dSMiklos Szeredi  out:
926334f485dSMiklos Szeredi 	return err;
927334f485dSMiklos Szeredi }
928334f485dSMiklos Szeredi 
929334f485dSMiklos Szeredi void fuse_dev_cleanup(void)
930334f485dSMiklos Szeredi {
931334f485dSMiklos Szeredi 	misc_deregister(&fuse_miscdevice);
932334f485dSMiklos Szeredi 	kmem_cache_destroy(fuse_req_cachep);
933334f485dSMiklos Szeredi }
934