diff options
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r-- | fs/fuse/inode.c | 118 |
1 files changed, 68 insertions, 50 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 91f7c85f1ffd..f0df55a52929 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -277,11 +277,14 @@ static void fuse_send_destroy(struct fuse_conn *fc) | |||
277 | } | 277 | } |
278 | } | 278 | } |
279 | 279 | ||
280 | static void fuse_put_super(struct super_block *sb) | 280 | static void fuse_bdi_destroy(struct fuse_conn *fc) |
281 | { | 281 | { |
282 | struct fuse_conn *fc = get_fuse_conn_super(sb); | 282 | if (fc->bdi_initialized) |
283 | bdi_destroy(&fc->bdi); | ||
284 | } | ||
283 | 285 | ||
284 | fuse_send_destroy(fc); | 286 | void fuse_conn_kill(struct fuse_conn *fc) |
287 | { | ||
285 | spin_lock(&fc->lock); | 288 | spin_lock(&fc->lock); |
286 | fc->connected = 0; | 289 | fc->connected = 0; |
287 | fc->blocked = 0; | 290 | fc->blocked = 0; |
@@ -295,7 +298,16 @@ static void fuse_put_super(struct super_block *sb) | |||
295 | list_del(&fc->entry); | 298 | list_del(&fc->entry); |
296 | fuse_ctl_remove_conn(fc); | 299 | fuse_ctl_remove_conn(fc); |
297 | mutex_unlock(&fuse_mutex); | 300 | mutex_unlock(&fuse_mutex); |
298 | bdi_destroy(&fc->bdi); | 301 | fuse_bdi_destroy(fc); |
302 | } | ||
303 | EXPORT_SYMBOL_GPL(fuse_conn_kill); | ||
304 | |||
305 | static void fuse_put_super(struct super_block *sb) | ||
306 | { | ||
307 | struct fuse_conn *fc = get_fuse_conn_super(sb); | ||
308 | |||
309 | fuse_send_destroy(fc); | ||
310 | fuse_conn_kill(fc); | ||
299 | fuse_conn_put(fc); | 311 | fuse_conn_put(fc); |
300 | } | 312 | } |
301 | 313 | ||
@@ -466,10 +478,8 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
466 | return 0; | 478 | return 0; |
467 | } | 479 | } |
468 | 480 | ||
469 | int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb) | 481 | void fuse_conn_init(struct fuse_conn *fc) |
470 | { | 482 | { |
471 | int err; | ||
472 | |||
473 | memset(fc, 0, sizeof(*fc)); | 483 | memset(fc, 0, sizeof(*fc)); |
474 | spin_lock_init(&fc->lock); | 484 | spin_lock_init(&fc->lock); |
475 | mutex_init(&fc->inst_mutex); | 485 | mutex_init(&fc->inst_mutex); |
@@ -484,49 +494,12 @@ int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb) | |||
484 | INIT_LIST_HEAD(&fc->bg_queue); | 494 | INIT_LIST_HEAD(&fc->bg_queue); |
485 | INIT_LIST_HEAD(&fc->entry); | 495 | INIT_LIST_HEAD(&fc->entry); |
486 | atomic_set(&fc->num_waiting, 0); | 496 | atomic_set(&fc->num_waiting, 0); |
487 | fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; | ||
488 | fc->bdi.unplug_io_fn = default_unplug_io_fn; | ||
489 | /* fuse does it's own writeback accounting */ | ||
490 | fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; | ||
491 | fc->khctr = 0; | 497 | fc->khctr = 0; |
492 | fc->polled_files = RB_ROOT; | 498 | fc->polled_files = RB_ROOT; |
493 | fc->dev = sb->s_dev; | ||
494 | err = bdi_init(&fc->bdi); | ||
495 | if (err) | ||
496 | goto error_mutex_destroy; | ||
497 | if (sb->s_bdev) { | ||
498 | err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", | ||
499 | MAJOR(fc->dev), MINOR(fc->dev)); | ||
500 | } else { | ||
501 | err = bdi_register_dev(&fc->bdi, fc->dev); | ||
502 | } | ||
503 | if (err) | ||
504 | goto error_bdi_destroy; | ||
505 | /* | ||
506 | * For a single fuse filesystem use max 1% of dirty + | ||
507 | * writeback threshold. | ||
508 | * | ||
509 | * This gives about 1M of write buffer for memory maps on a | ||
510 | * machine with 1G and 10% dirty_ratio, which should be more | ||
511 | * than enough. | ||
512 | * | ||
513 | * Privileged users can raise it by writing to | ||
514 | * | ||
515 | * /sys/class/bdi/<bdi>/max_ratio | ||
516 | */ | ||
517 | bdi_set_max_ratio(&fc->bdi, 1); | ||
518 | fc->reqctr = 0; | 499 | fc->reqctr = 0; |
519 | fc->blocked = 1; | 500 | fc->blocked = 1; |
520 | fc->attr_version = 1; | 501 | fc->attr_version = 1; |
521 | get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); | 502 | get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); |
522 | |||
523 | return 0; | ||
524 | |||
525 | error_bdi_destroy: | ||
526 | bdi_destroy(&fc->bdi); | ||
527 | error_mutex_destroy: | ||
528 | mutex_destroy(&fc->inst_mutex); | ||
529 | return err; | ||
530 | } | 503 | } |
531 | EXPORT_SYMBOL_GPL(fuse_conn_init); | 504 | EXPORT_SYMBOL_GPL(fuse_conn_init); |
532 | 505 | ||
@@ -539,12 +512,14 @@ void fuse_conn_put(struct fuse_conn *fc) | |||
539 | fc->release(fc); | 512 | fc->release(fc); |
540 | } | 513 | } |
541 | } | 514 | } |
515 | EXPORT_SYMBOL_GPL(fuse_conn_put); | ||
542 | 516 | ||
543 | struct fuse_conn *fuse_conn_get(struct fuse_conn *fc) | 517 | struct fuse_conn *fuse_conn_get(struct fuse_conn *fc) |
544 | { | 518 | { |
545 | atomic_inc(&fc->count); | 519 | atomic_inc(&fc->count); |
546 | return fc; | 520 | return fc; |
547 | } | 521 | } |
522 | EXPORT_SYMBOL_GPL(fuse_conn_get); | ||
548 | 523 | ||
549 | static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned mode) | 524 | static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned mode) |
550 | { | 525 | { |
@@ -797,6 +772,48 @@ static void fuse_free_conn(struct fuse_conn *fc) | |||
797 | kfree(fc); | 772 | kfree(fc); |
798 | } | 773 | } |
799 | 774 | ||
775 | static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb) | ||
776 | { | ||
777 | int err; | ||
778 | |||
779 | fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; | ||
780 | fc->bdi.unplug_io_fn = default_unplug_io_fn; | ||
781 | /* fuse does it's own writeback accounting */ | ||
782 | fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; | ||
783 | |||
784 | err = bdi_init(&fc->bdi); | ||
785 | if (err) | ||
786 | return err; | ||
787 | |||
788 | fc->bdi_initialized = 1; | ||
789 | |||
790 | if (sb->s_bdev) { | ||
791 | err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", | ||
792 | MAJOR(fc->dev), MINOR(fc->dev)); | ||
793 | } else { | ||
794 | err = bdi_register_dev(&fc->bdi, fc->dev); | ||
795 | } | ||
796 | |||
797 | if (err) | ||
798 | return err; | ||
799 | |||
800 | /* | ||
801 | * For a single fuse filesystem use max 1% of dirty + | ||
802 | * writeback threshold. | ||
803 | * | ||
804 | * This gives about 1M of write buffer for memory maps on a | ||
805 | * machine with 1G and 10% dirty_ratio, which should be more | ||
806 | * than enough. | ||
807 | * | ||
808 | * Privileged users can raise it by writing to | ||
809 | * | ||
810 | * /sys/class/bdi/<bdi>/max_ratio | ||
811 | */ | ||
812 | bdi_set_max_ratio(&fc->bdi, 1); | ||
813 | |||
814 | return 0; | ||
815 | } | ||
816 | |||
800 | static int fuse_fill_super(struct super_block *sb, void *data, int silent) | 817 | static int fuse_fill_super(struct super_block *sb, void *data, int silent) |
801 | { | 818 | { |
802 | struct fuse_conn *fc; | 819 | struct fuse_conn *fc; |
@@ -843,11 +860,12 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
843 | if (!fc) | 860 | if (!fc) |
844 | goto err_fput; | 861 | goto err_fput; |
845 | 862 | ||
846 | err = fuse_conn_init(fc, sb); | 863 | fuse_conn_init(fc); |
847 | if (err) { | 864 | |
848 | kfree(fc); | 865 | fc->dev = sb->s_dev; |
849 | goto err_fput; | 866 | err = fuse_bdi_init(fc, sb); |
850 | } | 867 | if (err) |
868 | goto err_put_conn; | ||
851 | 869 | ||
852 | fc->release = fuse_free_conn; | 870 | fc->release = fuse_free_conn; |
853 | fc->flags = d.flags; | 871 | fc->flags = d.flags; |
@@ -911,7 +929,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
911 | err_put_root: | 929 | err_put_root: |
912 | dput(root_dentry); | 930 | dput(root_dentry); |
913 | err_put_conn: | 931 | err_put_conn: |
914 | bdi_destroy(&fc->bdi); | 932 | fuse_bdi_destroy(fc); |
915 | fuse_conn_put(fc); | 933 | fuse_conn_put(fc); |
916 | err_fput: | 934 | err_fput: |
917 | fput(file); | 935 | fput(file); |