aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r--fs/fuse/inode.c135
1 files changed, 48 insertions, 87 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 879e6fba9480..fd34037b0588 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1,6 +1,6 @@
1/* 1/*
2 FUSE: Filesystem in Userspace 2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2005 Miklos Szeredi <miklos@szeredi.hu> 3 Copyright (C) 2001-2006 Miklos Szeredi <miklos@szeredi.hu>
4 4
5 This program can be distributed under the terms of the GNU GPL. 5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING. 6 See the file COPYING.
@@ -22,7 +22,6 @@ MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
22MODULE_DESCRIPTION("Filesystem in Userspace"); 22MODULE_DESCRIPTION("Filesystem in Userspace");
23MODULE_LICENSE("GPL"); 23MODULE_LICENSE("GPL");
24 24
25spinlock_t fuse_lock;
26static kmem_cache_t *fuse_inode_cachep; 25static kmem_cache_t *fuse_inode_cachep;
27static struct subsystem connections_subsys; 26static struct subsystem connections_subsys;
28 27
@@ -207,15 +206,17 @@ static void fuse_put_super(struct super_block *sb)
207 206
208 down_write(&fc->sbput_sem); 207 down_write(&fc->sbput_sem);
209 while (!list_empty(&fc->background)) 208 while (!list_empty(&fc->background))
210 fuse_release_background(list_entry(fc->background.next, 209 fuse_release_background(fc,
210 list_entry(fc->background.next,
211 struct fuse_req, bg_entry)); 211 struct fuse_req, bg_entry));
212 212
213 spin_lock(&fuse_lock); 213 spin_lock(&fc->lock);
214 fc->mounted = 0; 214 fc->mounted = 0;
215 fc->connected = 0; 215 fc->connected = 0;
216 spin_unlock(&fuse_lock); 216 spin_unlock(&fc->lock);
217 up_write(&fc->sbput_sem); 217 up_write(&fc->sbput_sem);
218 /* Flush all readers on this fs */ 218 /* Flush all readers on this fs */
219 kill_fasync(&fc->fasync, SIGIO, POLL_IN);
219 wake_up_all(&fc->waitq); 220 wake_up_all(&fc->waitq);
220 kobject_del(&fc->kobj); 221 kobject_del(&fc->kobj);
221 kobject_put(&fc->kobj); 222 kobject_put(&fc->kobj);
@@ -242,9 +243,9 @@ static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
242 struct fuse_statfs_out outarg; 243 struct fuse_statfs_out outarg;
243 int err; 244 int err;
244 245
245 req = fuse_get_request(fc); 246 req = fuse_get_req(fc);
246 if (!req) 247 if (IS_ERR(req))
247 return -EINTR; 248 return PTR_ERR(req);
248 249
249 memset(&outarg, 0, sizeof(outarg)); 250 memset(&outarg, 0, sizeof(outarg));
250 req->in.numargs = 0; 251 req->in.numargs = 0;
@@ -369,15 +370,7 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
369 370
370static void fuse_conn_release(struct kobject *kobj) 371static void fuse_conn_release(struct kobject *kobj)
371{ 372{
372 struct fuse_conn *fc = get_fuse_conn_kobj(kobj); 373 kfree(get_fuse_conn_kobj(kobj));
373
374 while (!list_empty(&fc->unused_list)) {
375 struct fuse_req *req;
376 req = list_entry(fc->unused_list.next, struct fuse_req, list);
377 list_del(&req->list);
378 fuse_request_free(req);
379 }
380 kfree(fc);
381} 374}
382 375
383static struct fuse_conn *new_conn(void) 376static struct fuse_conn *new_conn(void)
@@ -386,64 +379,25 @@ static struct fuse_conn *new_conn(void)
386 379
387 fc = kzalloc(sizeof(*fc), GFP_KERNEL); 380 fc = kzalloc(sizeof(*fc), GFP_KERNEL);
388 if (fc) { 381 if (fc) {
389 int i; 382 spin_lock_init(&fc->lock);
390 init_waitqueue_head(&fc->waitq); 383 init_waitqueue_head(&fc->waitq);
384 init_waitqueue_head(&fc->blocked_waitq);
391 INIT_LIST_HEAD(&fc->pending); 385 INIT_LIST_HEAD(&fc->pending);
392 INIT_LIST_HEAD(&fc->processing); 386 INIT_LIST_HEAD(&fc->processing);
393 INIT_LIST_HEAD(&fc->io); 387 INIT_LIST_HEAD(&fc->io);
394 INIT_LIST_HEAD(&fc->unused_list);
395 INIT_LIST_HEAD(&fc->background); 388 INIT_LIST_HEAD(&fc->background);
396 sema_init(&fc->outstanding_sem, 1); /* One for INIT */
397 init_rwsem(&fc->sbput_sem); 389 init_rwsem(&fc->sbput_sem);
398 kobj_set_kset_s(fc, connections_subsys); 390 kobj_set_kset_s(fc, connections_subsys);
399 kobject_init(&fc->kobj); 391 kobject_init(&fc->kobj);
400 atomic_set(&fc->num_waiting, 0); 392 atomic_set(&fc->num_waiting, 0);
401 for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) {
402 struct fuse_req *req = fuse_request_alloc();
403 if (!req) {
404 kobject_put(&fc->kobj);
405 return NULL;
406 }
407 list_add(&req->list, &fc->unused_list);
408 }
409 fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; 393 fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
410 fc->bdi.unplug_io_fn = default_unplug_io_fn; 394 fc->bdi.unplug_io_fn = default_unplug_io_fn;
411 fc->reqctr = 0; 395 fc->reqctr = 0;
396 fc->blocked = 1;
412 } 397 }
413 return fc; 398 return fc;
414} 399}
415 400
416static struct fuse_conn *get_conn(struct file *file, struct super_block *sb)
417{
418 struct fuse_conn *fc;
419 int err;
420
421 err = -EINVAL;
422 if (file->f_op != &fuse_dev_operations)
423 goto out_err;
424
425 err = -ENOMEM;
426 fc = new_conn();
427 if (!fc)
428 goto out_err;
429
430 spin_lock(&fuse_lock);
431 err = -EINVAL;
432 if (file->private_data)
433 goto out_unlock;
434
435 kobject_get(&fc->kobj);
436 file->private_data = fc;
437 spin_unlock(&fuse_lock);
438 return fc;
439
440 out_unlock:
441 spin_unlock(&fuse_lock);
442 kobject_put(&fc->kobj);
443 out_err:
444 return ERR_PTR(err);
445}
446
447static struct inode *get_root_inode(struct super_block *sb, unsigned mode) 401static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
448{ 402{
449 struct fuse_attr attr; 403 struct fuse_attr attr;
@@ -467,7 +421,6 @@ static struct super_operations fuse_super_operations = {
467 421
468static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) 422static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
469{ 423{
470 int i;
471 struct fuse_init_out *arg = &req->misc.init_out; 424 struct fuse_init_out *arg = &req->misc.init_out;
472 425
473 if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION) 426 if (req->out.h.error || arg->major != FUSE_KERNEL_VERSION)
@@ -486,22 +439,13 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
486 fc->minor = arg->minor; 439 fc->minor = arg->minor;
487 fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; 440 fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
488 } 441 }
489
490 /* After INIT reply is received other requests can go
491 out. So do (FUSE_MAX_OUTSTANDING - 1) number of
492 up()s on outstanding_sem. The last up() is done in
493 fuse_putback_request() */
494 for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
495 up(&fc->outstanding_sem);
496
497 fuse_put_request(fc, req); 442 fuse_put_request(fc, req);
443 fc->blocked = 0;
444 wake_up_all(&fc->blocked_waitq);
498} 445}
499 446
500static void fuse_send_init(struct fuse_conn *fc) 447static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
501{ 448{
502 /* This is called from fuse_read_super() so there's guaranteed
503 to be exactly one request available */
504 struct fuse_req *req = fuse_get_request(fc);
505 struct fuse_init_in *arg = &req->misc.init_in; 449 struct fuse_init_in *arg = &req->misc.init_in;
506 450
507 arg->major = FUSE_KERNEL_VERSION; 451 arg->major = FUSE_KERNEL_VERSION;
@@ -525,12 +469,9 @@ static void fuse_send_init(struct fuse_conn *fc)
525 469
526static unsigned long long conn_id(void) 470static unsigned long long conn_id(void)
527{ 471{
472 /* BKL is held for ->get_sb() */
528 static unsigned long long ctr = 1; 473 static unsigned long long ctr = 1;
529 unsigned long long val; 474 return ctr++;
530 spin_lock(&fuse_lock);
531 val = ctr++;
532 spin_unlock(&fuse_lock);
533 return val;
534} 475}
535 476
536static int fuse_fill_super(struct super_block *sb, void *data, int silent) 477static int fuse_fill_super(struct super_block *sb, void *data, int silent)
@@ -540,6 +481,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
540 struct fuse_mount_data d; 481 struct fuse_mount_data d;
541 struct file *file; 482 struct file *file;
542 struct dentry *root_dentry; 483 struct dentry *root_dentry;
484 struct fuse_req *init_req;
543 int err; 485 int err;
544 486
545 if (!parse_fuse_opt((char *) data, &d)) 487 if (!parse_fuse_opt((char *) data, &d))
@@ -555,10 +497,17 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
555 if (!file) 497 if (!file)
556 return -EINVAL; 498 return -EINVAL;
557 499
558 fc = get_conn(file, sb); 500 if (file->f_op != &fuse_dev_operations)
559 fput(file); 501 return -EINVAL;
560 if (IS_ERR(fc)) 502
561 return PTR_ERR(fc); 503 /* Setting file->private_data can't race with other mount()
504 instances, since BKL is held for ->get_sb() */
505 if (file->private_data)
506 return -EINVAL;
507
508 fc = new_conn();
509 if (!fc)
510 return -ENOMEM;
562 511
563 fc->flags = d.flags; 512 fc->flags = d.flags;
564 fc->user_id = d.user_id; 513 fc->user_id = d.user_id;
@@ -579,27 +528,40 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
579 goto err; 528 goto err;
580 } 529 }
581 530
531 init_req = fuse_request_alloc();
532 if (!init_req)
533 goto err_put_root;
534
582 err = kobject_set_name(&fc->kobj, "%llu", conn_id()); 535 err = kobject_set_name(&fc->kobj, "%llu", conn_id());
583 if (err) 536 if (err)
584 goto err_put_root; 537 goto err_free_req;
585 538
586 err = kobject_add(&fc->kobj); 539 err = kobject_add(&fc->kobj);
587 if (err) 540 if (err)
588 goto err_put_root; 541 goto err_free_req;
589 542
590 sb->s_root = root_dentry; 543 sb->s_root = root_dentry;
591 spin_lock(&fuse_lock);
592 fc->mounted = 1; 544 fc->mounted = 1;
593 fc->connected = 1; 545 fc->connected = 1;
594 spin_unlock(&fuse_lock); 546 kobject_get(&fc->kobj);
547 file->private_data = fc;
548 /*
549 * atomic_dec_and_test() in fput() provides the necessary
550 * memory barrier for file->private_data to be visible on all
551 * CPUs after this
552 */
553 fput(file);
595 554
596 fuse_send_init(fc); 555 fuse_send_init(fc, init_req);
597 556
598 return 0; 557 return 0;
599 558
559 err_free_req:
560 fuse_request_free(init_req);
600 err_put_root: 561 err_put_root:
601 dput(root_dentry); 562 dput(root_dentry);
602 err: 563 err:
564 fput(file);
603 kobject_put(&fc->kobj); 565 kobject_put(&fc->kobj);
604 return err; 566 return err;
605} 567}
@@ -753,7 +715,6 @@ static int __init fuse_init(void)
753 printk("fuse init (API version %i.%i)\n", 715 printk("fuse init (API version %i.%i)\n",
754 FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); 716 FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
755 717
756 spin_lock_init(&fuse_lock);
757 res = fuse_fs_init(); 718 res = fuse_fs_init();
758 if (res) 719 if (res)
759 goto err; 720 goto err;