blob: de402e4d8bcec33c3523a7cb4d0998dbd7cc56fc [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
24static inline struct fuse_conn *fuse_get_conn(struct file *file)
25{
26 struct fuse_conn *fc;
27 spin_lock(&fuse_lock);
28 fc = file->private_data;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -070029 if (fc && !fc->mounted)
Miklos Szeredi334f4852005-09-09 13:10:27 -070030 fc = NULL;
31 spin_unlock(&fuse_lock);
32 return fc;
33}
34
35static inline void fuse_request_init(struct fuse_req *req)
36{
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
56static inline void block_sigs(sigset_t *oldset)
57{
58 sigset_t mask;
59
60 siginitsetinv(&mask, sigmask(SIGKILL));
61 sigprocmask(SIG_BLOCK, &mask, oldset);
62}
63
64static inline void restore_sigs(sigset_t *oldset)
65{
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
112 block_sigs(&oldset);
113 intr = down_interruptible(&fc->outstanding_sem);
114 restore_sigs(&oldset);
115 return intr ? NULL : do_get_request(fc);
116}
117
118static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req)
119{
120 spin_lock(&fuse_lock);
121 if (req->preallocated)
122 list_add(&req->list, &fc->unused_list);
123 else
124 fuse_request_free(req);
125
126 /* If we are in debt decrease that first */
127 if (fc->outstanding_debt)
128 fc->outstanding_debt--;
129 else
130 up(&fc->outstanding_sem);
131 spin_unlock(&fuse_lock);
132}
133
134void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
135{
136 if (atomic_dec_and_test(&req->count))
137 fuse_putback_request(fc, req);
138}
139
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700140void fuse_release_background(struct fuse_req *req)
141{
142 iput(req->inode);
143 iput(req->inode2);
144 if (req->file)
145 fput(req->file);
146 spin_lock(&fuse_lock);
147 list_del(&req->bg_entry);
148 spin_unlock(&fuse_lock);
149}
150
Miklos Szeredi3ec870d2006-01-06 00:19:41 -0800151static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
152{
153 int i;
154 struct fuse_init_out *arg = &req->misc.init_out;
155
156 if (arg->major != FUSE_KERNEL_VERSION)
157 fc->conn_error = 1;
158 else {
159 fc->minor = arg->minor;
160 fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
161 }
162
163 /* After INIT reply is received other requests can go
164 out. So do (FUSE_MAX_OUTSTANDING - 1) number of
165 up()s on outstanding_sem. The last up() is done in
166 fuse_putback_request() */
167 for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
168 up(&fc->outstanding_sem);
169}
170
Miklos Szeredi334f4852005-09-09 13:10:27 -0700171/*
172 * This function is called when a request is finished. Either a reply
173 * has arrived or it was interrupted (and not yet sent) or some error
Miklos Szeredif43b1552006-01-16 22:14:26 -0800174 * occurred during communication with userspace, or the device file
175 * was closed. In case of a background request the reference to the
176 * stored objects are released. The requester thread is woken up (if
177 * still waiting), and finally the reference to the request is
178 * released
Miklos Szeredi334f4852005-09-09 13:10:27 -0700179 *
180 * Called with fuse_lock, unlocks it
181 */
182static void request_end(struct fuse_conn *fc, struct fuse_req *req)
183{
Miklos Szeredi334f4852005-09-09 13:10:27 -0700184 req->finished = 1;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700185 spin_unlock(&fuse_lock);
186 if (req->background) {
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700187 down_read(&fc->sbput_sem);
188 if (fc->mounted)
189 fuse_release_background(req);
190 up_read(&fc->sbput_sem);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700191 }
192 wake_up(&req->waitq);
Miklos Szeredi3ec870d2006-01-06 00:19:41 -0800193 if (req->in.h.opcode == FUSE_INIT)
194 process_init_reply(fc, req);
195 else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) {
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800196 /* Special case for failed iget in CREATE */
197 u64 nodeid = req->in.h.nodeid;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800198 fuse_reset_request(req);
199 fuse_send_forget(fc, req, nodeid, 1);
Miklos Szeredif43b1552006-01-16 22:14:26 -0800200 return;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700201 }
Miklos Szeredif43b1552006-01-16 22:14:26 -0800202 fuse_put_request(fc, req);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700203}
204
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700205/*
206 * Unfortunately request interruption not just solves the deadlock
207 * problem, it causes problems too. These stem from the fact, that an
208 * interrupted request is continued to be processed in userspace,
209 * while all the locks and object references (inode and file) held
210 * during the operation are released.
211 *
212 * To release the locks is exactly why there's a need to interrupt the
213 * request, so there's not a lot that can be done about this, except
214 * introduce additional locking in userspace.
215 *
216 * More important is to keep inode and file references until userspace
217 * has replied, otherwise FORGET and RELEASE could be sent while the
218 * inode/file is still used by the filesystem.
219 *
220 * For this reason the concept of "background" request is introduced.
221 * An interrupted request is backgrounded if it has been already sent
222 * to userspace. Backgrounding involves getting an extra reference to
223 * inode(s) or file used in the request, and adding the request to
224 * fc->background list. When a reply is received for a background
225 * request, the object references are released, and the request is
226 * removed from the list. If the filesystem is unmounted while there
227 * are still background requests, the list is walked and references
228 * are released as if a reply was received.
229 *
230 * There's one more use for a background request. The RELEASE message is
231 * always sent as background, since it doesn't return an error or
232 * data.
233 */
234static void background_request(struct fuse_conn *fc, struct fuse_req *req)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700235{
Miklos Szeredi334f4852005-09-09 13:10:27 -0700236 req->background = 1;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700237 list_add(&req->bg_entry, &fc->background);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700238 if (req->inode)
239 req->inode = igrab(req->inode);
240 if (req->inode2)
241 req->inode2 = igrab(req->inode2);
242 if (req->file)
243 get_file(req->file);
244}
245
Miklos Szeredi334f4852005-09-09 13:10:27 -0700246/* Called with fuse_lock held. Releases, and then reacquires it. */
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700247static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700248{
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700249 sigset_t oldset;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700250
251 spin_unlock(&fuse_lock);
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700252 block_sigs(&oldset);
253 wait_event_interruptible(req->waitq, req->finished);
254 restore_sigs(&oldset);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700255 spin_lock(&fuse_lock);
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700256 if (req->finished)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700257 return;
258
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700259 req->out.h.error = -EINTR;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700260 req->interrupted = 1;
261 if (req->locked) {
262 /* This is uninterruptible sleep, because data is
263 being copied to/from the buffers of req. During
264 locked state, there mustn't be any filesystem
265 operation (e.g. page fault), since that could lead
266 to deadlock */
267 spin_unlock(&fuse_lock);
268 wait_event(req->waitq, !req->locked);
269 spin_lock(&fuse_lock);
270 }
271 if (!req->sent && !list_empty(&req->list)) {
272 list_del(&req->list);
273 __fuse_put_request(req);
274 } else if (!req->finished && req->sent)
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700275 background_request(fc, req);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700276}
277
278static unsigned len_args(unsigned numargs, struct fuse_arg *args)
279{
280 unsigned nbytes = 0;
281 unsigned i;
282
283 for (i = 0; i < numargs; i++)
284 nbytes += args[i].size;
285
286 return nbytes;
287}
288
289static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
290{
291 fc->reqctr++;
292 /* zero is special */
293 if (fc->reqctr == 0)
294 fc->reqctr = 1;
295 req->in.h.unique = fc->reqctr;
296 req->in.h.len = sizeof(struct fuse_in_header) +
297 len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
298 if (!req->preallocated) {
299 /* If request is not preallocated (either FORGET or
300 RELEASE), then still decrease outstanding_sem, so
301 user can't open infinite number of files while not
302 processing the RELEASE requests. However for
303 efficiency do it without blocking, so if down()
304 would block, just increase the debt instead */
305 if (down_trylock(&fc->outstanding_sem))
306 fc->outstanding_debt++;
307 }
308 list_add_tail(&req->list, &fc->pending);
309 wake_up(&fc->waitq);
310}
311
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700312/*
313 * This can only be interrupted by a SIGKILL
314 */
315void request_send(struct fuse_conn *fc, struct fuse_req *req)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700316{
317 req->isreply = 1;
318 spin_lock(&fuse_lock);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700319 if (!fc->connected)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700320 req->out.h.error = -ENOTCONN;
321 else if (fc->conn_error)
322 req->out.h.error = -ECONNREFUSED;
323 else {
324 queue_request(fc, req);
325 /* acquire extra reference, since request is still needed
326 after request_end() */
327 __fuse_get_request(req);
328
Miklos Szeredi7c352bd2005-09-09 13:10:39 -0700329 request_wait_answer(fc, req);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700330 }
331 spin_unlock(&fuse_lock);
332}
333
Miklos Szeredi334f4852005-09-09 13:10:27 -0700334static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req)
335{
336 spin_lock(&fuse_lock);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700337 if (fc->connected) {
Miklos Szeredi334f4852005-09-09 13:10:27 -0700338 queue_request(fc, req);
339 spin_unlock(&fuse_lock);
340 } else {
341 req->out.h.error = -ENOTCONN;
342 request_end(fc, req);
343 }
344}
345
346void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req)
347{
348 req->isreply = 0;
349 request_send_nowait(fc, req);
350}
351
352void request_send_background(struct fuse_conn *fc, struct fuse_req *req)
353{
354 req->isreply = 1;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700355 spin_lock(&fuse_lock);
356 background_request(fc, req);
357 spin_unlock(&fuse_lock);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700358 request_send_nowait(fc, req);
359}
360
361void fuse_send_init(struct fuse_conn *fc)
362{
363 /* This is called from fuse_read_super() so there's guaranteed
364 to be a request available */
365 struct fuse_req *req = do_get_request(fc);
Miklos Szeredi3ec870d2006-01-06 00:19:41 -0800366 struct fuse_init_in *arg = &req->misc.init_in;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700367 arg->major = FUSE_KERNEL_VERSION;
368 arg->minor = FUSE_KERNEL_MINOR_VERSION;
369 req->in.h.opcode = FUSE_INIT;
370 req->in.numargs = 1;
371 req->in.args[0].size = sizeof(*arg);
372 req->in.args[0].value = arg;
373 req->out.numargs = 1;
Miklos Szeredi3ec870d2006-01-06 00:19:41 -0800374 /* Variable length arguement used for backward compatibility
375 with interface version < 7.5. Rest of init_out is zeroed
376 by do_get_request(), so a short reply is not a problem */
377 req->out.argvar = 1;
378 req->out.args[0].size = sizeof(struct fuse_init_out);
379 req->out.args[0].value = &req->misc.init_out;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700380 request_send_background(fc, req);
381}
382
383/*
384 * Lock the request. Up to the next unlock_request() there mustn't be
385 * anything that could cause a page-fault. If the request was already
386 * interrupted bail out.
387 */
388static inline int lock_request(struct fuse_req *req)
389{
390 int err = 0;
391 if (req) {
392 spin_lock(&fuse_lock);
393 if (req->interrupted)
394 err = -ENOENT;
395 else
396 req->locked = 1;
397 spin_unlock(&fuse_lock);
398 }
399 return err;
400}
401
402/*
403 * Unlock request. If it was interrupted during being locked, the
404 * requester thread is currently waiting for it to be unlocked, so
405 * wake it up.
406 */
407static inline void unlock_request(struct fuse_req *req)
408{
409 if (req) {
410 spin_lock(&fuse_lock);
411 req->locked = 0;
412 if (req->interrupted)
413 wake_up(&req->waitq);
414 spin_unlock(&fuse_lock);
415 }
416}
417
418struct fuse_copy_state {
419 int write;
420 struct fuse_req *req;
421 const struct iovec *iov;
422 unsigned long nr_segs;
423 unsigned long seglen;
424 unsigned long addr;
425 struct page *pg;
426 void *mapaddr;
427 void *buf;
428 unsigned len;
429};
430
431static void fuse_copy_init(struct fuse_copy_state *cs, int write,
432 struct fuse_req *req, const struct iovec *iov,
433 unsigned long nr_segs)
434{
435 memset(cs, 0, sizeof(*cs));
436 cs->write = write;
437 cs->req = req;
438 cs->iov = iov;
439 cs->nr_segs = nr_segs;
440}
441
442/* Unmap and put previous page of userspace buffer */
443static inline void fuse_copy_finish(struct fuse_copy_state *cs)
444{
445 if (cs->mapaddr) {
446 kunmap_atomic(cs->mapaddr, KM_USER0);
447 if (cs->write) {
448 flush_dcache_page(cs->pg);
449 set_page_dirty_lock(cs->pg);
450 }
451 put_page(cs->pg);
452 cs->mapaddr = NULL;
453 }
454}
455
456/*
457 * Get another pagefull of userspace buffer, and map it to kernel
458 * address space, and lock request
459 */
460static int fuse_copy_fill(struct fuse_copy_state *cs)
461{
462 unsigned long offset;
463 int err;
464
465 unlock_request(cs->req);
466 fuse_copy_finish(cs);
467 if (!cs->seglen) {
468 BUG_ON(!cs->nr_segs);
469 cs->seglen = cs->iov[0].iov_len;
470 cs->addr = (unsigned long) cs->iov[0].iov_base;
471 cs->iov ++;
472 cs->nr_segs --;
473 }
474 down_read(&current->mm->mmap_sem);
475 err = get_user_pages(current, current->mm, cs->addr, 1, cs->write, 0,
476 &cs->pg, NULL);
477 up_read(&current->mm->mmap_sem);
478 if (err < 0)
479 return err;
480 BUG_ON(err != 1);
481 offset = cs->addr % PAGE_SIZE;
482 cs->mapaddr = kmap_atomic(cs->pg, KM_USER0);
483 cs->buf = cs->mapaddr + offset;
484 cs->len = min(PAGE_SIZE - offset, cs->seglen);
485 cs->seglen -= cs->len;
486 cs->addr += cs->len;
487
488 return lock_request(cs->req);
489}
490
491/* Do as much copy to/from userspace buffer as we can */
492static inline int fuse_copy_do(struct fuse_copy_state *cs, void **val,
493 unsigned *size)
494{
495 unsigned ncpy = min(*size, cs->len);
496 if (val) {
497 if (cs->write)
498 memcpy(cs->buf, *val, ncpy);
499 else
500 memcpy(*val, cs->buf, ncpy);
501 *val += ncpy;
502 }
503 *size -= ncpy;
504 cs->len -= ncpy;
505 cs->buf += ncpy;
506 return ncpy;
507}
508
509/*
510 * Copy a page in the request to/from the userspace buffer. Must be
511 * done atomically
512 */
513static inline int fuse_copy_page(struct fuse_copy_state *cs, struct page *page,
514 unsigned offset, unsigned count, int zeroing)
515{
516 if (page && zeroing && count < PAGE_SIZE) {
517 void *mapaddr = kmap_atomic(page, KM_USER1);
518 memset(mapaddr, 0, PAGE_SIZE);
519 kunmap_atomic(mapaddr, KM_USER1);
520 }
521 while (count) {
522 int err;
523 if (!cs->len && (err = fuse_copy_fill(cs)))
524 return err;
525 if (page) {
526 void *mapaddr = kmap_atomic(page, KM_USER1);
527 void *buf = mapaddr + offset;
528 offset += fuse_copy_do(cs, &buf, &count);
529 kunmap_atomic(mapaddr, KM_USER1);
530 } else
531 offset += fuse_copy_do(cs, NULL, &count);
532 }
533 if (page && !cs->write)
534 flush_dcache_page(page);
535 return 0;
536}
537
538/* Copy pages in the request to/from userspace buffer */
539static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
540 int zeroing)
541{
542 unsigned i;
543 struct fuse_req *req = cs->req;
544 unsigned offset = req->page_offset;
545 unsigned count = min(nbytes, (unsigned) PAGE_SIZE - offset);
546
547 for (i = 0; i < req->num_pages && (nbytes || zeroing); i++) {
548 struct page *page = req->pages[i];
549 int err = fuse_copy_page(cs, page, offset, count, zeroing);
550 if (err)
551 return err;
552
553 nbytes -= count;
554 count = min(nbytes, (unsigned) PAGE_SIZE);
555 offset = 0;
556 }
557 return 0;
558}
559
560/* Copy a single argument in the request to/from userspace buffer */
561static int fuse_copy_one(struct fuse_copy_state *cs, void *val, unsigned size)
562{
563 while (size) {
564 int err;
565 if (!cs->len && (err = fuse_copy_fill(cs)))
566 return err;
567 fuse_copy_do(cs, &val, &size);
568 }
569 return 0;
570}
571
572/* Copy request arguments to/from userspace buffer */
573static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
574 unsigned argpages, struct fuse_arg *args,
575 int zeroing)
576{
577 int err = 0;
578 unsigned i;
579
580 for (i = 0; !err && i < numargs; i++) {
581 struct fuse_arg *arg = &args[i];
582 if (i == numargs - 1 && argpages)
583 err = fuse_copy_pages(cs, arg->size, zeroing);
584 else
585 err = fuse_copy_one(cs, arg->value, arg->size);
586 }
587 return err;
588}
589
590/* Wait until a request is available on the pending list */
591static void request_wait(struct fuse_conn *fc)
592{
593 DECLARE_WAITQUEUE(wait, current);
594
595 add_wait_queue_exclusive(&fc->waitq, &wait);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700596 while (fc->mounted && list_empty(&fc->pending)) {
Miklos Szeredi334f4852005-09-09 13:10:27 -0700597 set_current_state(TASK_INTERRUPTIBLE);
598 if (signal_pending(current))
599 break;
600
601 spin_unlock(&fuse_lock);
602 schedule();
603 spin_lock(&fuse_lock);
604 }
605 set_current_state(TASK_RUNNING);
606 remove_wait_queue(&fc->waitq, &wait);
607}
608
609/*
610 * Read a single request into the userspace filesystem's buffer. This
611 * function waits until a request is available, then removes it from
612 * the pending list and copies request data to userspace buffer. If
613 * no reply is needed (FORGET) or request has been interrupted or
614 * there was an error during the copying then it's finished by calling
615 * request_end(). Otherwise add it to the processing list, and set
616 * the 'sent' flag.
617 */
618static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
619 unsigned long nr_segs, loff_t *off)
620{
621 int err;
622 struct fuse_conn *fc;
623 struct fuse_req *req;
624 struct fuse_in *in;
625 struct fuse_copy_state cs;
626 unsigned reqsize;
627
Miklos Szeredi1d3d7522006-01-06 00:19:40 -0800628 restart:
Miklos Szeredi334f4852005-09-09 13:10:27 -0700629 spin_lock(&fuse_lock);
630 fc = file->private_data;
631 err = -EPERM;
632 if (!fc)
633 goto err_unlock;
634 request_wait(fc);
635 err = -ENODEV;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700636 if (!fc->mounted)
Miklos Szeredi334f4852005-09-09 13:10:27 -0700637 goto err_unlock;
638 err = -ERESTARTSYS;
639 if (list_empty(&fc->pending))
640 goto err_unlock;
641
642 req = list_entry(fc->pending.next, struct fuse_req, list);
643 list_del_init(&req->list);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700644
645 in = &req->in;
Miklos Szeredi1d3d7522006-01-06 00:19:40 -0800646 reqsize = in->h.len;
647 /* If request is too large, reply with an error and restart the read */
648 if (iov_length(iov, nr_segs) < reqsize) {
649 req->out.h.error = -EIO;
650 /* SETXATTR is special, since it may contain too large data */
651 if (in->h.opcode == FUSE_SETXATTR)
652 req->out.h.error = -E2BIG;
653 request_end(fc, req);
654 goto restart;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700655 }
Miklos Szeredi1d3d7522006-01-06 00:19:40 -0800656 spin_unlock(&fuse_lock);
657 fuse_copy_init(&cs, 1, req, iov, nr_segs);
658 err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
659 if (!err)
660 err = fuse_copy_args(&cs, in->numargs, in->argpages,
661 (struct fuse_arg *) in->args, 0);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700662 fuse_copy_finish(&cs);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700663 spin_lock(&fuse_lock);
664 req->locked = 0;
665 if (!err && req->interrupted)
666 err = -ENOENT;
667 if (err) {
668 if (!req->interrupted)
669 req->out.h.error = -EIO;
670 request_end(fc, req);
671 return err;
672 }
673 if (!req->isreply)
674 request_end(fc, req);
675 else {
676 req->sent = 1;
677 list_add_tail(&req->list, &fc->processing);
678 spin_unlock(&fuse_lock);
679 }
680 return reqsize;
681
682 err_unlock:
683 spin_unlock(&fuse_lock);
684 return err;
685}
686
687static ssize_t fuse_dev_read(struct file *file, char __user *buf,
688 size_t nbytes, loff_t *off)
689{
690 struct iovec iov;
691 iov.iov_len = nbytes;
692 iov.iov_base = buf;
693 return fuse_dev_readv(file, &iov, 1, off);
694}
695
696/* Look up request on processing list by unique ID */
697static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
698{
699 struct list_head *entry;
700
701 list_for_each(entry, &fc->processing) {
702 struct fuse_req *req;
703 req = list_entry(entry, struct fuse_req, list);
704 if (req->in.h.unique == unique)
705 return req;
706 }
707 return NULL;
708}
709
710static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
711 unsigned nbytes)
712{
713 unsigned reqsize = sizeof(struct fuse_out_header);
714
715 if (out->h.error)
716 return nbytes != reqsize ? -EINVAL : 0;
717
718 reqsize += len_args(out->numargs, out->args);
719
720 if (reqsize < nbytes || (reqsize > nbytes && !out->argvar))
721 return -EINVAL;
722 else if (reqsize > nbytes) {
723 struct fuse_arg *lastarg = &out->args[out->numargs-1];
724 unsigned diffsize = reqsize - nbytes;
725 if (diffsize > lastarg->size)
726 return -EINVAL;
727 lastarg->size -= diffsize;
728 }
729 return fuse_copy_args(cs, out->numargs, out->argpages, out->args,
730 out->page_zeroing);
731}
732
733/*
734 * Write a single reply to a request. First the header is copied from
735 * the write buffer. The request is then searched on the processing
736 * list by the unique ID found in the header. If found, then remove
737 * it from the list and copy the rest of the buffer to the request.
738 * The request is finished by calling request_end()
739 */
740static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
741 unsigned long nr_segs, loff_t *off)
742{
743 int err;
744 unsigned nbytes = iov_length(iov, nr_segs);
745 struct fuse_req *req;
746 struct fuse_out_header oh;
747 struct fuse_copy_state cs;
748 struct fuse_conn *fc = fuse_get_conn(file);
749 if (!fc)
750 return -ENODEV;
751
752 fuse_copy_init(&cs, 0, NULL, iov, nr_segs);
753 if (nbytes < sizeof(struct fuse_out_header))
754 return -EINVAL;
755
756 err = fuse_copy_one(&cs, &oh, sizeof(oh));
757 if (err)
758 goto err_finish;
759 err = -EINVAL;
760 if (!oh.unique || oh.error <= -1000 || oh.error > 0 ||
761 oh.len != nbytes)
762 goto err_finish;
763
764 spin_lock(&fuse_lock);
765 req = request_find(fc, oh.unique);
766 err = -EINVAL;
767 if (!req)
768 goto err_unlock;
769
770 list_del_init(&req->list);
771 if (req->interrupted) {
Miklos Szeredi222f1d62006-01-16 22:14:25 -0800772 spin_unlock(&fuse_lock);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700773 fuse_copy_finish(&cs);
Miklos Szeredi222f1d62006-01-16 22:14:25 -0800774 spin_lock(&fuse_lock);
775 request_end(fc, req);
Miklos Szeredi334f4852005-09-09 13:10:27 -0700776 return -ENOENT;
777 }
778 req->out.h = oh;
779 req->locked = 1;
780 cs.req = req;
781 spin_unlock(&fuse_lock);
782
783 err = copy_out_args(&cs, &req->out, nbytes);
784 fuse_copy_finish(&cs);
785
786 spin_lock(&fuse_lock);
787 req->locked = 0;
788 if (!err) {
789 if (req->interrupted)
790 err = -ENOENT;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700791 } else if (!req->interrupted)
792 req->out.h.error = -EIO;
793 request_end(fc, req);
794
795 return err ? err : nbytes;
796
797 err_unlock:
798 spin_unlock(&fuse_lock);
799 err_finish:
800 fuse_copy_finish(&cs);
801 return err;
802}
803
804static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
805 size_t nbytes, loff_t *off)
806{
807 struct iovec iov;
808 iov.iov_len = nbytes;
809 iov.iov_base = (char __user *) buf;
810 return fuse_dev_writev(file, &iov, 1, off);
811}
812
813static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
814{
815 struct fuse_conn *fc = fuse_get_conn(file);
816 unsigned mask = POLLOUT | POLLWRNORM;
817
818 if (!fc)
819 return -ENODEV;
820
821 poll_wait(file, &fc->waitq, wait);
822
823 spin_lock(&fuse_lock);
824 if (!list_empty(&fc->pending))
825 mask |= POLLIN | POLLRDNORM;
826 spin_unlock(&fuse_lock);
827
828 return mask;
829}
830
831/* Abort all requests on the given list (pending or processing) */
832static void end_requests(struct fuse_conn *fc, struct list_head *head)
833{
834 while (!list_empty(head)) {
835 struct fuse_req *req;
836 req = list_entry(head->next, struct fuse_req, list);
837 list_del_init(&req->list);
838 req->out.h.error = -ECONNABORTED;
839 request_end(fc, req);
840 spin_lock(&fuse_lock);
841 }
842}
843
844static int fuse_dev_release(struct inode *inode, struct file *file)
845{
846 struct fuse_conn *fc;
847
848 spin_lock(&fuse_lock);
849 fc = file->private_data;
850 if (fc) {
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -0700851 fc->connected = 0;
Miklos Szeredi334f4852005-09-09 13:10:27 -0700852 end_requests(fc, &fc->pending);
853 end_requests(fc, &fc->processing);
854 fuse_release_conn(fc);
855 }
856 spin_unlock(&fuse_lock);
857 return 0;
858}
859
860struct file_operations fuse_dev_operations = {
861 .owner = THIS_MODULE,
862 .llseek = no_llseek,
863 .read = fuse_dev_read,
864 .readv = fuse_dev_readv,
865 .write = fuse_dev_write,
866 .writev = fuse_dev_writev,
867 .poll = fuse_dev_poll,
868 .release = fuse_dev_release,
869};
870
871static struct miscdevice fuse_miscdevice = {
872 .minor = FUSE_MINOR,
873 .name = "fuse",
874 .fops = &fuse_dev_operations,
875};
876
877int __init fuse_dev_init(void)
878{
879 int err = -ENOMEM;
880 fuse_req_cachep = kmem_cache_create("fuse_request",
881 sizeof(struct fuse_req),
882 0, 0, NULL, NULL);
883 if (!fuse_req_cachep)
884 goto out;
885
886 err = misc_register(&fuse_miscdevice);
887 if (err)
888 goto out_cache_clean;
889
890 return 0;
891
892 out_cache_clean:
893 kmem_cache_destroy(fuse_req_cachep);
894 out:
895 return err;
896}
897
898void fuse_dev_cleanup(void)
899{
900 misc_deregister(&fuse_miscdevice);
901 kmem_cache_destroy(fuse_req_cachep);
902}