blob: c72e44b58d098b197b740ec720389e2ae7c63583 [file] [log] [blame]
Miklos Szeredi334f4852005-09-09 13:10:27 -07001/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include "fuse_i.h"
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/poll.h>
14#include <linux/uio.h>
15#include <linux/miscdevice.h>
16#include <linux/pagemap.h>
17#include <linux/file.h>
18#include <linux/slab.h>
19
20MODULE_ALIAS_MISCDEV(FUSE_MINOR);
21
22static kmem_cache_t *fuse_req_cachep;
23
Miklos Szeredi8bfc0162006-01-16 22:14:28 -080024static struct fuse_conn *fuse_get_conn(struct file *file)
Miklos Szeredi334f4852005-09-09 13:10:27 -070025{
26 struct fuse_conn *fc;
27 spin_lock(&fuse_lock);
28 fc = file->private_data;
Miklos Szeredi9ba7cbb2006-01-16 22:14:34 -080029 if (fc && !fc->connected)
Miklos Szeredi334f4852005-09-09 13:10:27 -070030 fc = NULL;
31 spin_unlock(&fuse_lock);
32 return fc;
33}
34
Miklos Szeredi8bfc0162006-01-16 22:14:28 -080035static void fuse_request_init(struct fuse_req *req)
Miklos Szeredi334f4852005-09-09 13:10:27 -070036{
37 memset(req, 0, sizeof(*req));
38 INIT_LIST_HEAD(&req->list);
39 init_waitqueue_head(&req->waitq);
40 atomic_set(&req->count, 1);
41}
42
43struct fuse_req *fuse_request_alloc(void)
44{
45 struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, SLAB_KERNEL);
46 if (req)
47 fuse_request_init(req);
48 return req;
49}
50
51void fuse_request_free(struct fuse_req *req)
52{
53 kmem_cache_free(fuse_req_cachep, req);
54}
55
Miklos Szeredi8bfc0162006-01-16 22:14:28 -080056static void block_sigs(sigset_t *oldset)
Miklos Szeredi334f4852005-09-09 13:10:27 -070057{
58 sigset_t mask;
59
60 siginitsetinv(&mask, sigmask(SIGKILL));
61 sigprocmask(SIG_BLOCK, &mask, oldset);
62}
63
Miklos Szeredi8bfc0162006-01-16 22:14:28 -080064static void restore_sigs(sigset_t *oldset)
Miklos Szeredi334f4852005-09-09 13:10:27 -070065{
66 sigprocmask(SIG_SETMASK, oldset, NULL);
67}
68
69void fuse_reset_request(struct fuse_req *req)
70{
71 int preallocated = req->preallocated;
72 BUG_ON(atomic_read(&req->count) != 1);
73 fuse_request_init(req);
74 req->preallocated = preallocated;
75}
76
77static void __fuse_get_request(struct fuse_req *req)
78{
79 atomic_inc(&req->count);
80}
81
82/* Must be called with > 1 refcount */
83static void __fuse_put_request(struct fuse_req *req)
84{
85 BUG_ON(atomic_read(&req->count) < 2);
86 atomic_dec(&req->count);
87}
88
89static struct fuse_req *do_get_request(struct fuse_conn *fc)
90{
91 struct fuse_req *req;
92
93 spin_lock(&fuse_lock);
94 BUG_ON(list_empty(&fc->unused_list));
95 req = list_entry(fc->unused_list.next, struct fuse_req, list);
96 list_del_init(&req->list);
97 spin_unlock(&fuse_lock);
98 fuse_request_init(req);
99 req->preallocated = 1;
100 req->in.h.uid = current->fsuid;
101 req->in.h.gid = current->fsgid;
102 req->in.h.pid = current->pid;
103 return req;
104}
105
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700106/* This can return NULL, but only in case it's interrupted by a SIGKILL */
Miklos Szeredi334f4852005-09-09 13:10:27 -0700107struct fuse_req *fuse_get_request(struct fuse_conn *fc)
108{
Miklos Szeredi334f4852005-09-09 13:10:27 -0700109 int intr;
110 sigset_t oldset;
111
Miklos Szeredi0cd5b882006-01-16 22:14:38 -0800112 atomic_inc(&fc->num_waiting);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700113 block_sigs(&oldset);
114 intr = down_interruptible(&fc->outstanding_sem);
115 restore_sigs(&oldset);
Miklos Szeredi0cd5b882006-01-16 22:14:38 -0800116 if (intr) {
117 atomic_dec(&fc->num_waiting);
118 return NULL;
119 }
120 return do_get_request(fc);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700121}
122
123static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req)
124{
125 spin_lock(&fuse_lock);
Miklos Szeredi0cd5b882006-01-16 22:14:38 -0800126 if (req->preallocated) {
127 atomic_dec(&fc->num_waiting);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700128 list_add(&req->list, &fc->unused_list);
Miklos Szeredi0cd5b882006-01-16 22:14:38 -0800129 } else
Miklos Szeredi334f4852005-09-09 13:10:27 -0700130 fuse_request_free(req);
131
132 /* If we are in debt decrease that first */
133 if (fc->outstanding_debt)
134 fc->outstanding_debt--;
135 else
136 up(&fc->outstanding_sem);
137 spin_unlock(&fuse_lock);
138}
139
140void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
141{
142 if (atomic_dec_and_test(&req->count))
143 fuse_putback_request(fc, req);
144}
145
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700146void fuse_release_background(struct fuse_req *req)
147{
148 iput(req->inode);
149 iput(req->inode2);
150 if (req->file)
151 fput(req->file);
152 spin_lock(&fuse_lock);
153 list_del(&req->bg_entry);
154 spin_unlock(&fuse_lock);
155}
156
Miklos Szeredi3ec870d2006-01-06 00:19:41 -0800157static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
158{
159 int i;
160 struct fuse_init_out *arg = &req->misc.init_out;
161
Miklos Szeredib3bebd92006-01-16 22:14:27 -0800162 if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION)
Miklos Szeredi3ec870d2006-01-06 00:19:41 -0800163 fc->conn_error = 1;
164 else {
165 fc->minor = arg->minor;
166 fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
167 }
168
169 /* After INIT reply is received other requests can go
170 out. So do (FUSE_MAX_OUTSTANDING - 1) number of
171 up()s on outstanding_sem. The last up() is done in
172 fuse_putback_request() */
173 for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
174 up(&fc->outstanding_sem);
175}
176
Miklos Szeredi334f4852005-09-09 13:10:27 -0700177/*
178 * This function is called when a request is finished. Either a reply
179 * has arrived or it was interrupted (and not yet sent) or some error
Miklos Szeredif43b1552006-01-16 22:14:26 -0800180 * occurred during communication with userspace, or the device file
181 * was closed. In case of a background request the reference to the
182 * stored objects are released. The requester thread is woken up (if
183 * still waiting), and finally the reference to the request is
184 * released
Miklos Szeredi334f4852005-09-09 13:10:27 -0700185 *
186 * Called with fuse_lock, unlocks it
187 */
188static void request_end(struct fuse_conn *fc, struct fuse_req *req)
189{
Miklos Szeredid77a1d52006-01-16 22:14:31 -0800190 list_del(&req->list);
Miklos Szeredi83cfd492006-01-16 22:14:31 -0800191 req->state = FUSE_REQ_FINISHED;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700192 spin_unlock(&fuse_lock);
193 if (req->background) {
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700194 down_read(&fc->sbput_sem);
195 if (fc->mounted)
196 fuse_release_background(req);
197 up_read(&fc->sbput_sem);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700198 }
199 wake_up(&req->waitq);
Miklos Szeredi3ec870d2006-01-06 00:19:41 -0800200 if (req->in.h.opcode == FUSE_INIT)
201 process_init_reply(fc, req);
202 else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) {
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800203 /* Special case for failed iget in CREATE */
204 u64 nodeid = req->in.h.nodeid;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800205 fuse_reset_request(req);
206 fuse_send_forget(fc, req, nodeid, 1);
Miklos Szeredif43b1552006-01-16 22:14:26 -0800207 return;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700208 }
Miklos Szeredif43b1552006-01-16 22:14:26 -0800209 fuse_put_request(fc, req);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700210}
211
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700212/*
213 * Unfortunately request interruption not just solves the deadlock
214 * problem, it causes problems too. These stem from the fact, that an
215 * interrupted request is continued to be processed in userspace,
216 * while all the locks and object references (inode and file) held
217 * during the operation are released.
218 *
219 * To release the locks is exactly why there's a need to interrupt the
220 * request, so there's not a lot that can be done about this, except
221 * introduce additional locking in userspace.
222 *
223 * More important is to keep inode and file references until userspace
224 * has replied, otherwise FORGET and RELEASE could be sent while the
225 * inode/file is still used by the filesystem.
226 *
227 * For this reason the concept of "background" request is introduced.
228 * An interrupted request is backgrounded if it has been already sent
229 * to userspace. Backgrounding involves getting an extra reference to
230 * inode(s) or file used in the request, and adding the request to
231 * fc->background list. When a reply is received for a background
232 * request, the object references are released, and the request is
233 * removed from the list. If the filesystem is unmounted while there
234 * are still background requests, the list is walked and references
235 * are released as if a reply was received.
236 *
237 * There's one more use for a background request. The RELEASE message is
238 * always sent as background, since it doesn't return an error or
239 * data.
240 */
241static void background_request(struct fuse_conn *fc, struct fuse_req *req)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700242{
Miklos Szeredi334f4852005-09-09 13:10:27 -0700243 req->background = 1;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700244 list_add(&req->bg_entry, &fc->background);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700245 if (req->inode)
246 req->inode = igrab(req->inode);
247 if (req->inode2)
248 req->inode2 = igrab(req->inode2);
249 if (req->file)
250 get_file(req->file);
251}
252
Miklos Szeredi334f4852005-09-09 13:10:27 -0700253/* Called with fuse_lock held. Releases, and then reacquires it. */
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700254static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700255{
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700256 sigset_t oldset;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700257
258 spin_unlock(&fuse_lock);
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700259 block_sigs(&oldset);
Miklos Szeredi83cfd492006-01-16 22:14:31 -0800260 wait_event_interruptible(req->waitq, req->state == FUSE_REQ_FINISHED);
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700261 restore_sigs(&oldset);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700262 spin_lock(&fuse_lock);
Miklos Szeredi83cfd492006-01-16 22:14:31 -0800263 if (req->state == FUSE_REQ_FINISHED)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700264 return;
265
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700266 req->out.h.error = -EINTR;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700267 req->interrupted = 1;
268 if (req->locked) {
269 /* This is uninterruptible sleep, because data is
270 being copied to/from the buffers of req. During
271 locked state, there mustn't be any filesystem
272 operation (e.g. page fault), since that could lead
273 to deadlock */
274 spin_unlock(&fuse_lock);
275 wait_event(req->waitq, !req->locked);
276 spin_lock(&fuse_lock);
277 }
Miklos Szeredi83cfd492006-01-16 22:14:31 -0800278 if (req->state == FUSE_REQ_PENDING) {
Miklos Szeredi334f4852005-09-09 13:10:27 -0700279 list_del(&req->list);
280 __fuse_put_request(req);
Miklos Szeredi83cfd492006-01-16 22:14:31 -0800281 } else if (req->state == FUSE_REQ_SENT)
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700282 background_request(fc, req);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700283}
284
285static unsigned len_args(unsigned numargs, struct fuse_arg *args)
286{
287 unsigned nbytes = 0;
288 unsigned i;
289
290 for (i = 0; i < numargs; i++)
291 nbytes += args[i].size;
292
293 return nbytes;
294}
295
296static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
297{
298 fc->reqctr++;
299 /* zero is special */
300 if (fc->reqctr == 0)
301 fc->reqctr = 1;
302 req->in.h.unique = fc->reqctr;
303 req->in.h.len = sizeof(struct fuse_in_header) +
304 len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
305 if (!req->preallocated) {
306 /* If request is not preallocated (either FORGET or
307 RELEASE), then still decrease outstanding_sem, so
308 user can't open infinite number of files while not
309 processing the RELEASE requests. However for
310 efficiency do it without blocking, so if down()
311 would block, just increase the debt instead */
312 if (down_trylock(&fc->outstanding_sem))
313 fc->outstanding_debt++;
314 }
315 list_add_tail(&req->list, &fc->pending);
Miklos Szeredi83cfd492006-01-16 22:14:31 -0800316 req->state = FUSE_REQ_PENDING;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700317 wake_up(&fc->waitq);
318}
319
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700320/*
321 * This can only be interrupted by a SIGKILL
322 */
323void request_send(struct fuse_conn *fc, struct fuse_req *req)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700324{
325 req->isreply = 1;
326 spin_lock(&fuse_lock);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700327 if (!fc->connected)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700328 req->out.h.error = -ENOTCONN;
329 else if (fc->conn_error)
330 req->out.h.error = -ECONNREFUSED;
331 else {
332 queue_request(fc, req);
333 /* acquire extra reference, since request is still needed
334 after request_end() */
335 __fuse_get_request(req);
336
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700337 request_wait_answer(fc, req);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700338 }
339 spin_unlock(&fuse_lock);
340}
341
Miklos Szeredi334f4852005-09-09 13:10:27 -0700342static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
343{
344 spin_lock(&fuse_lock);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700345 if (fc->connected) {
Miklos Szeredi334f4852005-09-09 13:10:27 -0700346 queue_request(fc, req);
347 spin_unlock(&fuse_lock);
348 } else {
349 req->out.h.error = -ENOTCONN;
350 request_end(fc, req);
351 }
352}
353
354void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req)
355{
356 req->isreply = 0;
357 request_send_nowait(fc, req);
358}
359
360void request_send_background(struct fuse_conn *fc, struct fuse_req *req)
361{
362 req->isreply = 1;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700363 spin_lock(&fuse_lock);
364 background_request(fc, req);
365 spin_unlock(&fuse_lock);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700366 request_send_nowait(fc, req);
367}
368
369void fuse_send_init(struct fuse_conn *fc)
370{
371 /* This is called from fuse_read_super() so there's guaranteed
Miklos Szeredi6383bda2006-01-16 22:14:29 -0800372 to be exactly one request available */
373 struct fuse_req *req = fuse_get_request(fc);
Miklos Szeredi3ec870d2006-01-06 00:19:41 -0800374 struct fuse_init_in *arg = &req->misc.init_in;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700375 arg->major = FUSE_KERNEL_VERSION;
376 arg->minor = FUSE_KERNEL_MINOR_VERSION;
377 req->in.h.opcode = FUSE_INIT;
378 req->in.numargs = 1;
379 req->in.args[0].size = sizeof(*arg);
380 req->in.args[0].value = arg;
381 req->out.numargs = 1;
Miklos Szeredi3ec870d2006-01-06 00:19:41 -0800382 /* Variable length arguement used for backward compatibility
383 with interface version < 7.5. Rest of init_out is zeroed
384 by do_get_request(), so a short reply is not a problem */
385 req->out.argvar = 1;
386 req->out.args[0].size = sizeof(struct fuse_init_out);
387 req->out.args[0].value = &req->misc.init_out;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700388 request_send_background(fc, req);
389}
390
391/*
392 * Lock the request. Up to the next unlock_request() there mustn't be
393 * anything that could cause a page-fault. If the request was already
394 * interrupted bail out.
395 */
Miklos Szeredi8bfc0162006-01-16 22:14:28 -0800396static int lock_request(struct fuse_req *req)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700397{
398 int err = 0;
399 if (req) {
400 spin_lock(&fuse_lock);
401 if (req->interrupted)
402 err = -ENOENT;
403 else
404 req->locked = 1;
405 spin_unlock(&fuse_lock);
406 }
407 return err;
408}
409
410/*
411 * Unlock request. If it was interrupted during being locked, the
412 * requester thread is currently waiting for it to be unlocked, so
413 * wake it up.
414 */
Miklos Szeredi8bfc0162006-01-16 22:14:28 -0800415static void unlock_request(struct fuse_req *req)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700416{
417 if (req) {
418 spin_lock(&fuse_lock);
419 req->locked = 0;
420 if (req->interrupted)
421 wake_up(&req->waitq);
422 spin_unlock(&fuse_lock);
423 }
424}
425
426struct fuse_copy_state {
427 int write;
428 struct fuse_req *req;
429 const struct iovec *iov;
430 unsigned long nr_segs;
431 unsigned long seglen;
432 unsigned long addr;
433 struct page *pg;
434 void *mapaddr;
435 void *buf;
436 unsigned len;
437};
438
439static void fuse_copy_init(struct fuse_copy_state *cs, int write,
440 struct fuse_req *req, const struct iovec *iov,
441 unsigned long nr_segs)
442{
443 memset(cs, 0, sizeof(*cs));
444 cs->write = write;
445 cs->req = req;
446 cs->iov = iov;
447 cs->nr_segs = nr_segs;
448}
449
450/* Unmap and put previous page of userspace buffer */
Miklos Szeredi8bfc0162006-01-16 22:14:28 -0800451static void fuse_copy_finish(struct fuse_copy_state *cs)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700452{
453 if (cs->mapaddr) {
454 kunmap_atomic(cs->mapaddr, KM_USER0);
455 if (cs->write) {
456 flush_dcache_page(cs->pg);
457 set_page_dirty_lock(cs->pg);
458 }
459 put_page(cs->pg);
460 cs->mapaddr = NULL;
461 }
462}
463
464/*
465 * Get another pagefull of userspace buffer, and map it to kernel
466 * address space, and lock request
467 */
468static int fuse_copy_fill(struct fuse_copy_state *cs)
469{
470 unsigned long offset;
471 int err;
472
473 unlock_request(cs->req);
474 fuse_copy_finish(cs);
475 if (!cs->seglen) {
476 BUG_ON(!cs->nr_segs);
477 cs->seglen = cs->iov[0].iov_len;
478 cs->addr = (unsigned long) cs->iov[0].iov_base;
479 cs->iov ++;
480 cs->nr_segs --;
481 }
482 down_read(&current->mm->mmap_sem);
483 err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
484 &cs->pg, NULL);
485 up_read(&current->mm->mmap_sem);
486 if (err < 0)
487 return err;
488 BUG_ON(err != 1);
489 offset = cs->addr % PAGE_SIZE;
490 cs->mapaddr = kmap_atomic(cs->pg, KM_USER0);
491 cs->buf = cs->mapaddr + offset;
492 cs->len = min(PAGE_SIZE - offset, cs->seglen);
493 cs->seglen -= cs->len;
494 cs->addr += cs->len;
495
496 return lock_request(cs->req);
497}
498
499/* Do as much copy to/from userspace buffer as we can */
Miklos Szeredi8bfc0162006-01-16 22:14:28 -0800500static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700501{
502 unsigned ncpy = min(*size, cs->len);
503 if (val) {
504 if (cs->write)
505 memcpy(cs->buf, *val, ncpy);
506 else
507 memcpy(*val, cs->buf, ncpy);
508 *val += ncpy;
509 }
510 *size -= ncpy;
511 cs->len -= ncpy;
512 cs->buf += ncpy;
513 return ncpy;
514}
515
516/*
517 * Copy a page in the request to/from the userspace buffer. Must be
518 * done atomically
519 */
Miklos Szeredi8bfc0162006-01-16 22:14:28 -0800520static int fuse_copy_page(struct fuse_copy_state *cs, struct page *page,
521 unsigned offset, unsigned count, int zeroing)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700522{
523 if (page && zeroing && count < PAGE_SIZE) {
524 void *mapaddr = kmap_atomic(page, KM_USER1);
525 memset(mapaddr, 0, PAGE_SIZE);
526 kunmap_atomic(mapaddr, KM_USER1);
527 }
528 while (count) {
529 int err;
530 if (!cs->len && (err = fuse_copy_fill(cs)))
531 return err;
532 if (page) {
533 void *mapaddr = kmap_atomic(page, KM_USER1);
534 void *buf = mapaddr + offset;
535 offset += fuse_copy_do(cs, &buf, &count);
536 kunmap_atomic(mapaddr, KM_USER1);
537 } else
538 offset += fuse_copy_do(cs, NULL, &count);
539 }
540 if (page && !cs->write)
541 flush_dcache_page(page);
542 return 0;
543}
544
545/* Copy pages in the request to/from userspace buffer */
546static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
547 int zeroing)
548{
549 unsigned i;
550 struct fuse_req *req = cs->req;
551 unsigned offset = req->page_offset;
552 unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);
553
554 for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
555 struct page *page = req->pages[i];
556 int err = fuse_copy_page(cs, page, offset, count, zeroing);
557 if (err)
558 return err;
559
560 nbytes -= count;
561 count = min(nbytes, (unsigned) PAGE_SIZE);
562 offset = 0;
563 }
564 return 0;
565}
566
567/* Copy a single argument in the request to/from userspace buffer */
568static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
569{
570 while (size) {
571 int err;
572 if (!cs->len && (err = fuse_copy_fill(cs)))
573 return err;
574 fuse_copy_do(cs, &val, &size);
575 }
576 return 0;
577}
578
579/* Copy request arguments to/from userspace buffer */
580static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
581 unsigned argpages, struct fuse_arg *args,
582 int zeroing)
583{
584 int err = 0;
585 unsigned i;
586
587 for (i = 0; !err && i < numargs; i++) {
588 struct fuse_arg *arg = &args[i];
589 if (i == numargs - 1 && argpages)
590 err = fuse_copy_pages(cs, arg->size, zeroing);
591 else
592 err = fuse_copy_one(cs, arg->value, arg->size);
593 }
594 return err;
595}
596
597/* Wait until a request is available on the pending list */
598static void request_wait(struct fuse_conn *fc)
599{
600 DECLARE_WAITQUEUE(wait, current);
601
602 add_wait_queue_exclusive(&fc->waitq, &wait);
Miklos Szeredi9ba7cbb2006-01-16 22:14:34 -0800603 while (fc->connected && list_empty(&fc->pending)) {
Miklos Szeredi334f4852005-09-09 13:10:27 -0700604 set_current_state(TASK_INTERRUPTIBLE);
605 if (signal_pending(current))
606 break;
607
608 spin_unlock(&fuse_lock);
609 schedule();
610 spin_lock(&fuse_lock);
611 }
612 set_current_state(TASK_RUNNING);
613 remove_wait_queue(&fc->waitq, &wait);
614}
615
616/*
617 * Read a single request into the userspace filesystem's buffer. This
618 * function waits until a request is available, then removes it from
619 * the pending list and copies request data to userspace buffer. If
620 * no reply is needed (FORGET) or request has been interrupted or
621 * there was an error during the copying then it's finished by calling
622 * request_end(). Otherwise add it to the processing list, and set
623 * the 'sent' flag.
624 */
625static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
626 unsigned long nr_segs, loff_t *off)
627{
628 int err;
629 struct fuse_conn *fc;
630 struct fuse_req *req;
631 struct fuse_in *in;
632 struct fuse_copy_state cs;
633 unsigned reqsize;
634
Miklos Szeredi1d3d7522006-01-06 00:19:40 -0800635 restart:
Miklos Szeredi334f4852005-09-09 13:10:27 -0700636 spin_lock(&fuse_lock);
637 fc = file->private_data;
638 err = -EPERM;
639 if (!fc)
640 goto err_unlock;
641 request_wait(fc);
642 err = -ENODEV;
Miklos Szeredi9ba7cbb2006-01-16 22:14:34 -0800643 if (!fc->connected)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700644 goto err_unlock;
645 err = -ERESTARTSYS;
646 if (list_empty(&fc->pending))
647 goto err_unlock;
648
649 req = list_entry(fc->pending.next, struct fuse_req, list);
Miklos Szeredi83cfd492006-01-16 22:14:31 -0800650 req->state = FUSE_REQ_READING;
Miklos Szeredid77a1d52006-01-16 22:14:31 -0800651 list_move(&req->list, &fc->io);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700652
653 in = &req->in;
Miklos Szeredi1d3d7522006-01-06 00:19:40 -0800654 reqsize = in->h.len;
655 /* If request is too large, reply with an error and restart the read */
656 if (iov_length(iov, nr_segs) < reqsize) {
657 req->out.h.error = -EIO;
658 /* SETXATTR is special, since it may contain too large data */
659 if (in->h.opcode == FUSE_SETXATTR)
660 req->out.h.error = -E2BIG;
661 request_end(fc, req);
662 goto restart;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700663 }
Miklos Szeredi1d3d7522006-01-06 00:19:40 -0800664 spin_unlock(&fuse_lock);
665 fuse_copy_init(&cs, 1, req, iov, nr_segs);
666 err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
667 if (!err)
668 err = fuse_copy_args(&cs, in->numargs, in->argpages,
669 (struct fuse_arg *) in->args, 0);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700670 fuse_copy_finish(&cs);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700671 spin_lock(&fuse_lock);
672 req->locked = 0;
673 if (!err && req->interrupted)
674 err = -ENOENT;
675 if (err) {
676 if (!req->interrupted)
677 req->out.h.error = -EIO;
678 request_end(fc, req);
679 return err;
680 }
681 if (!req->isreply)
682 request_end(fc, req);
683 else {
Miklos Szeredi83cfd492006-01-16 22:14:31 -0800684 req->state = FUSE_REQ_SENT;
Miklos Szeredid77a1d52006-01-16 22:14:31 -0800685 list_move_tail(&req->list, &fc->processing);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700686 spin_unlock(&fuse_lock);
687 }
688 return reqsize;
689
690 err_unlock:
691 spin_unlock(&fuse_lock);
692 return err;
693}
694
695static ssize_t fuse_dev_read(struct file *file, char __user *buf,
696 size_t nbytes, loff_t *off)
697{
698 struct iovec iov;
699 iov.iov_len = nbytes;
700 iov.iov_base = buf;
701 return fuse_dev_readv(file, &iov, 1, off);
702}
703
704/* Look up request on processing list by unique ID */
705static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
706{
707 struct list_head *entry;
708
709 list_for_each(entry, &fc->processing) {
710 struct fuse_req *req;
711 req = list_entry(entry, struct fuse_req, list);
712 if (req->in.h.unique == unique)
713 return req;
714 }
715 return NULL;
716}
717
718static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
719 unsigned nbytes)
720{
721 unsigned reqsize = sizeof(struct fuse_out_header);
722
723 if (out->h.error)
724 return nbytes != reqsize ? -EINVAL : 0;
725
726 reqsize += len_args(out->numargs, out->args);
727
728 if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))
729 return -EINVAL;
730 else if (reqsize > nbytes) {
731 struct fuse_arg *lastarg = &out->args[out->numargs-1];
732 unsigned diffsize = reqsize - nbytes;
733 if (diffsize > lastarg->size)
734 return -EINVAL;
735 lastarg->size -= diffsize;
736 }
737 return fuse_copy_args(cs, out->numargs, out->argpages, out->args,
738 out->page_zeroing);
739}
740
741/*
742 * Write a single reply to a request. First the header is copied from
743 * the write buffer. The request is then searched on the processing
744 * list by the unique ID found in the header. If found, then remove
745 * it from the list and copy the rest of the buffer to the request.
746 * The request is finished by calling request_end()
747 */
748static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
749 unsigned long nr_segs, loff_t *off)
750{
751 int err;
752 unsigned nbytes = iov_length(iov, nr_segs);
753 struct fuse_req *req;
754 struct fuse_out_header oh;
755 struct fuse_copy_state cs;
756 struct fuse_conn *fc = fuse_get_conn(file);
757 if (!fc)
758 return -ENODEV;
759
760 fuse_copy_init(&cs, 0, NULL, iov, nr_segs);
761 if (nbytes < sizeof(struct fuse_out_header))
762 return -EINVAL;
763
764 err = fuse_copy_one(&cs, &oh, sizeof(oh));
765 if (err)
766 goto err_finish;
767 err = -EINVAL;
768 if (!oh.unique || oh.error <= -1000 || oh.error > 0 ||
769 oh.len != nbytes)
770 goto err_finish;
771
772 spin_lock(&fuse_lock);
773 req = request_find(fc, oh.unique);
774 err = -EINVAL;
775 if (!req)
776 goto err_unlock;
777
Miklos Szeredi334f4852005-09-09 13:10:27 -0700778 if (req->interrupted) {
Miklos Szeredi222f1d62006-01-16 22:14:25 -0800779 spin_unlock(&fuse_lock);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700780 fuse_copy_finish(&cs);
Miklos Szeredi222f1d62006-01-16 22:14:25 -0800781 spin_lock(&fuse_lock);
782 request_end(fc, req);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700783 return -ENOENT;
784 }
Miklos Szeredid77a1d52006-01-16 22:14:31 -0800785 list_move(&req->list, &fc->io);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700786 req->out.h = oh;
787 req->locked = 1;
788 cs.req = req;
789 spin_unlock(&fuse_lock);
790
791 err = copy_out_args(&cs, &req->out, nbytes);
792 fuse_copy_finish(&cs);
793
794 spin_lock(&fuse_lock);
795 req->locked = 0;
796 if (!err) {
797 if (req->interrupted)
798 err = -ENOENT;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700799 } else if (!req->interrupted)
800 req->out.h.error = -EIO;
801 request_end(fc, req);
802
803 return err ? err : nbytes;
804
805 err_unlock:
806 spin_unlock(&fuse_lock);
807 err_finish:
808 fuse_copy_finish(&cs);
809 return err;
810}
811
812static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
813 size_t nbytes, loff_t *off)
814{
815 struct iovec iov;
816 iov.iov_len = nbytes;
817 iov.iov_base = (char __user *) buf;
818 return fuse_dev_writev(file, &iov, 1, off);
819}
820
821static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
822{
823 struct fuse_conn *fc = fuse_get_conn(file);
824 unsigned mask = POLLOUT | POLLWRNORM;
825
826 if (!fc)
827 return -ENODEV;
828
829 poll_wait(file, &fc->waitq, wait);
830
831 spin_lock(&fuse_lock);
832 if (!list_empty(&fc->pending))
833 mask |= POLLIN | POLLRDNORM;
834 spin_unlock(&fuse_lock);
835
836 return mask;
837}
838
839/* Abort all requests on the given list (pending or processing) */
840static void end_requests(struct fuse_conn *fc, struct list_head *head)
841{
842 while (!list_empty(head)) {
843 struct fuse_req *req;
844 req = list_entry(head->next, struct fuse_req, list);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700845 req->out.h.error = -ECONNABORTED;
846 request_end(fc, req);
847 spin_lock(&fuse_lock);
848 }
849}
850
851static int fuse_dev_release(struct inode *inode, struct file *file)
852{
853 struct fuse_conn *fc;
854
855 spin_lock(&fuse_lock);
856 fc = file->private_data;
857 if (fc) {
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700858 fc->connected = 0;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700859 end_requests(fc, &fc->pending);
860 end_requests(fc, &fc->processing);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700861 }
862 spin_unlock(&fuse_lock);
Miklos Szeredif543f252006-01-16 22:14:35 -0800863 if (fc)
864 kobject_put(&fc->kobj);
865
Miklos Szeredi334f4852005-09-09 13:10:27 -0700866 return 0;
867}
868
869struct file_operations fuse_dev_operations = {
870 .owner = THIS_MODULE,
871 .llseek = no_llseek,
872 .read = fuse_dev_read,
873 .readv = fuse_dev_readv,
874 .write = fuse_dev_write,
875 .writev = fuse_dev_writev,
876 .poll = fuse_dev_poll,
877 .release = fuse_dev_release,
878};
879
880static struct miscdevice fuse_miscdevice = {
881 .minor = FUSE_MINOR,
882 .name = "fuse",
883 .fops = &fuse_dev_operations,
884};
885
886int __init fuse_dev_init(void)
887{
888 int err = -ENOMEM;
889 fuse_req_cachep = kmem_cache_create("fuse_request",
890 sizeof(struct fuse_req),
891 0, 0, NULL, NULL);
892 if (!fuse_req_cachep)
893 goto out;
894
895 err = misc_register(&fuse_miscdevice);
896 if (err)
897 goto out_cache_clean;
898
899 return 0;
900
901 out_cache_clean:
902 kmem_cache_destroy(fuse_req_cachep);
903 out:
904 return err;
905}
906
907void fuse_dev_cleanup(void)
908{
909 misc_deregister(&fuse_miscdevice);
910 kmem_cache_destroy(fuse_req_cachep);
911}