diff options
Diffstat (limited to 'fs/ceph/super.c')
-rw-r--r-- | fs/ceph/super.c | 106 |
1 files changed, 48 insertions, 58 deletions
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index b094f5003ef8..9b7815dfc035 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c | |||
@@ -110,7 +110,7 @@ static int ceph_syncfs(struct super_block *sb, int wait) | |||
110 | static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) | 110 | static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) |
111 | { | 111 | { |
112 | struct ceph_client *client = ceph_sb_to_client(mnt->mnt_sb); | 112 | struct ceph_client *client = ceph_sb_to_client(mnt->mnt_sb); |
113 | struct ceph_mount_args *args = &client->mount_args; | 113 | struct ceph_mount_args *args = client->mount_args; |
114 | 114 | ||
115 | if (args->flags & CEPH_OPT_FSID) | 115 | if (args->flags & CEPH_OPT_FSID) |
116 | seq_printf(m, ",fsidmajor=%llu,fsidminor%llu", | 116 | seq_printf(m, ",fsidmajor=%llu,fsidminor%llu", |
@@ -307,24 +307,24 @@ static match_table_t arg_tokens = { | |||
307 | }; | 307 | }; |
308 | 308 | ||
309 | 309 | ||
310 | static int parse_mount_args(struct ceph_client *client, | 310 | static struct ceph_mount_args *parse_mount_args(int flags, char *options, |
311 | int flags, char *options, const char *dev_name, | 311 | const char *dev_name, |
312 | const char **path) | 312 | const char **path) |
313 | { | 313 | { |
314 | struct ceph_mount_args *args = &client->mount_args; | 314 | struct ceph_mount_args *args; |
315 | const char *c; | 315 | const char *c; |
316 | int err; | 316 | int err = -ENOMEM; |
317 | substring_t argstr[MAX_OPT_ARGS]; | 317 | substring_t argstr[MAX_OPT_ARGS]; |
318 | int num_mon; | ||
319 | struct ceph_entity_addr *mon_addr; | ||
320 | int i; | ||
321 | 318 | ||
322 | dout("parse_mount_args dev_name '%s'\n", dev_name); | 319 | args = kzalloc(sizeof(*args), GFP_KERNEL); |
323 | memset(args, 0, sizeof(*args)); | 320 | if (!args) |
321 | return ERR_PTR(-ENOMEM); | ||
322 | args->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*args->mon_addr), | ||
323 | GFP_KERNEL); | ||
324 | if (!args->mon_addr) | ||
325 | goto out; | ||
324 | 326 | ||
325 | mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*mon_addr), GFP_KERNEL); | 327 | dout("parse_mount_args %p, dev_name '%s'\n", args, dev_name); |
326 | if (!mon_addr) | ||
327 | return -ENOMEM; | ||
328 | 328 | ||
329 | /* start with defaults */ | 329 | /* start with defaults */ |
330 | args->sb_flags = flags; | 330 | args->sb_flags = flags; |
@@ -350,29 +350,11 @@ static int parse_mount_args(struct ceph_client *client, | |||
350 | } | 350 | } |
351 | 351 | ||
352 | /* get mon ip(s) */ | 352 | /* get mon ip(s) */ |
353 | err = ceph_parse_ips(dev_name, *path, mon_addr, | 353 | err = ceph_parse_ips(dev_name, *path, args->mon_addr, |
354 | CEPH_MAX_MON, &num_mon); | 354 | CEPH_MAX_MON, &args->num_mon); |
355 | if (err < 0) | 355 | if (err < 0) |
356 | goto out; | 356 | goto out; |
357 | 357 | ||
358 | /* build initial monmap */ | ||
359 | err = -ENOMEM; | ||
360 | client->monc.monmap = kzalloc(sizeof(*client->monc.monmap) + | ||
361 | num_mon*sizeof(client->monc.monmap->mon_inst[0]), | ||
362 | GFP_KERNEL); | ||
363 | if (!client->monc.monmap) | ||
364 | goto out; | ||
365 | for (i = 0; i < num_mon; i++) { | ||
366 | client->monc.monmap->mon_inst[i].addr = mon_addr[i]; | ||
367 | client->monc.monmap->mon_inst[i].addr.erank = 0; | ||
368 | client->monc.monmap->mon_inst[i].addr.nonce = 0; | ||
369 | client->monc.monmap->mon_inst[i].name.type = | ||
370 | CEPH_ENTITY_TYPE_MON; | ||
371 | client->monc.monmap->mon_inst[i].name.num = cpu_to_le64(i); | ||
372 | } | ||
373 | client->monc.monmap->num_mon = num_mon; | ||
374 | memset(&args->my_addr.in_addr, 0, sizeof(args->my_addr.in_addr)); | ||
375 | |||
376 | /* path on server */ | 358 | /* path on server */ |
377 | *path += 2; | 359 | *path += 2; |
378 | dout("server path '%s'\n", *path); | 360 | dout("server path '%s'\n", *path); |
@@ -415,7 +397,7 @@ static int parse_mount_args(struct ceph_client *client, | |||
415 | &args->my_addr, | 397 | &args->my_addr, |
416 | 1, NULL); | 398 | 1, NULL); |
417 | if (err < 0) | 399 | if (err < 0) |
418 | return err; | 400 | goto out; |
419 | args->flags |= CEPH_OPT_MYIP; | 401 | args->flags |= CEPH_OPT_MYIP; |
420 | break; | 402 | break; |
421 | 403 | ||
@@ -481,25 +463,28 @@ static int parse_mount_args(struct ceph_client *client, | |||
481 | BUG_ON(token); | 463 | BUG_ON(token); |
482 | } | 464 | } |
483 | } | 465 | } |
484 | err = 0; | 466 | return args; |
485 | 467 | ||
486 | out: | 468 | out: |
487 | kfree(mon_addr); | 469 | kfree(args->mon_addr); |
488 | return err; | 470 | kfree(args); |
471 | return ERR_PTR(err); | ||
489 | } | 472 | } |
490 | 473 | ||
491 | static void release_mount_args(struct ceph_mount_args *args) | 474 | static void destroy_mount_args(struct ceph_mount_args *args) |
492 | { | 475 | { |
476 | dout("destroy_mount_args %p\n", args); | ||
493 | kfree(args->snapdir_name); | 477 | kfree(args->snapdir_name); |
494 | args->snapdir_name = NULL; | 478 | args->snapdir_name = NULL; |
495 | kfree(args->secret); | 479 | kfree(args->secret); |
496 | args->secret = NULL; | 480 | args->secret = NULL; |
481 | kfree(args); | ||
497 | } | 482 | } |
498 | 483 | ||
499 | /* | 484 | /* |
500 | * create a fresh client instance | 485 | * create a fresh client instance |
501 | */ | 486 | */ |
502 | static struct ceph_client *ceph_create_client(void) | 487 | static struct ceph_client *ceph_create_client(struct ceph_mount_args *args) |
503 | { | 488 | { |
504 | struct ceph_client *client; | 489 | struct ceph_client *client; |
505 | int err = -ENOMEM; | 490 | int err = -ENOMEM; |
@@ -515,6 +500,7 @@ static struct ceph_client *ceph_create_client(void) | |||
515 | client->sb = NULL; | 500 | client->sb = NULL; |
516 | client->mount_state = CEPH_MOUNT_MOUNTING; | 501 | client->mount_state = CEPH_MOUNT_MOUNTING; |
517 | client->whoami = -1; | 502 | client->whoami = -1; |
503 | client->mount_args = args; | ||
518 | 504 | ||
519 | client->msgr = NULL; | 505 | client->msgr = NULL; |
520 | 506 | ||
@@ -577,7 +563,7 @@ static void ceph_destroy_client(struct ceph_client *client) | |||
577 | if (client->wb_pagevec_pool) | 563 | if (client->wb_pagevec_pool) |
578 | mempool_destroy(client->wb_pagevec_pool); | 564 | mempool_destroy(client->wb_pagevec_pool); |
579 | 565 | ||
580 | release_mount_args(&client->mount_args); | 566 | destroy_mount_args(client->mount_args); |
581 | 567 | ||
582 | kfree(client); | 568 | kfree(client); |
583 | dout("destroy_client %p done\n", client); | 569 | dout("destroy_client %p done\n", client); |
@@ -613,7 +599,7 @@ static struct dentry *open_root_dentry(struct ceph_client *client, | |||
613 | req->r_ino1.ino = CEPH_INO_ROOT; | 599 | req->r_ino1.ino = CEPH_INO_ROOT; |
614 | req->r_ino1.snap = CEPH_NOSNAP; | 600 | req->r_ino1.snap = CEPH_NOSNAP; |
615 | req->r_started = started; | 601 | req->r_started = started; |
616 | req->r_timeout = client->mount_args.mount_timeout * HZ; | 602 | req->r_timeout = client->mount_args->mount_timeout * HZ; |
617 | req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE); | 603 | req->r_args.getattr.mask = cpu_to_le32(CEPH_STAT_CAP_INODE); |
618 | req->r_num_caps = 2; | 604 | req->r_num_caps = 2; |
619 | err = ceph_mdsc_do_request(mdsc, NULL, req); | 605 | err = ceph_mdsc_do_request(mdsc, NULL, req); |
@@ -641,7 +627,7 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, | |||
641 | { | 627 | { |
642 | struct ceph_entity_addr *myaddr = NULL; | 628 | struct ceph_entity_addr *myaddr = NULL; |
643 | int err; | 629 | int err; |
644 | unsigned long timeout = client->mount_args.mount_timeout * HZ; | 630 | unsigned long timeout = client->mount_args->mount_timeout * HZ; |
645 | unsigned long started = jiffies; /* note the start time */ | 631 | unsigned long started = jiffies; /* note the start time */ |
646 | struct dentry *root; | 632 | struct dentry *root; |
647 | 633 | ||
@@ -651,7 +637,7 @@ static int ceph_mount(struct ceph_client *client, struct vfsmount *mnt, | |||
651 | /* initialize the messenger */ | 637 | /* initialize the messenger */ |
652 | if (client->msgr == NULL) { | 638 | if (client->msgr == NULL) { |
653 | if (ceph_test_opt(client, MYIP)) | 639 | if (ceph_test_opt(client, MYIP)) |
654 | myaddr = &client->mount_args.my_addr; | 640 | myaddr = &client->mount_args->my_addr; |
655 | client->msgr = ceph_messenger_create(myaddr); | 641 | client->msgr = ceph_messenger_create(myaddr); |
656 | if (IS_ERR(client->msgr)) { | 642 | if (IS_ERR(client->msgr)) { |
657 | err = PTR_ERR(client->msgr); | 643 | err = PTR_ERR(client->msgr); |
@@ -727,7 +713,7 @@ static int ceph_set_super(struct super_block *s, void *data) | |||
727 | 713 | ||
728 | dout("set_super %p data %p\n", s, data); | 714 | dout("set_super %p data %p\n", s, data); |
729 | 715 | ||
730 | s->s_flags = client->mount_args.sb_flags; | 716 | s->s_flags = client->mount_args->sb_flags; |
731 | s->s_maxbytes = 1ULL << 40; /* temp value until we get mdsmap */ | 717 | s->s_maxbytes = 1ULL << 40; /* temp value until we get mdsmap */ |
732 | 718 | ||
733 | s->s_fs_info = client; | 719 | s->s_fs_info = client; |
@@ -756,7 +742,7 @@ fail: | |||
756 | static int ceph_compare_super(struct super_block *sb, void *data) | 742 | static int ceph_compare_super(struct super_block *sb, void *data) |
757 | { | 743 | { |
758 | struct ceph_client *new = data; | 744 | struct ceph_client *new = data; |
759 | struct ceph_mount_args *args = &new->mount_args; | 745 | struct ceph_mount_args *args = new->mount_args; |
760 | struct ceph_client *other = ceph_sb_to_client(sb); | 746 | struct ceph_client *other = ceph_sb_to_client(sb); |
761 | int i; | 747 | int i; |
762 | 748 | ||
@@ -778,7 +764,7 @@ static int ceph_compare_super(struct super_block *sb, void *data) | |||
778 | } | 764 | } |
779 | dout("mon ip matches existing sb %p\n", sb); | 765 | dout("mon ip matches existing sb %p\n", sb); |
780 | } | 766 | } |
781 | if (args->sb_flags != other->mount_args.sb_flags) { | 767 | if (args->sb_flags != other->mount_args->sb_flags) { |
782 | dout("flags differ\n"); | 768 | dout("flags differ\n"); |
783 | return 0; | 769 | return 0; |
784 | } | 770 | } |
@@ -798,9 +784,9 @@ static int ceph_init_bdi(struct super_block *sb, struct ceph_client *client) | |||
798 | sb->s_bdi = &client->backing_dev_info; | 784 | sb->s_bdi = &client->backing_dev_info; |
799 | 785 | ||
800 | /* set ra_pages based on rsize mount option? */ | 786 | /* set ra_pages based on rsize mount option? */ |
801 | if (client->mount_args.rsize >= PAGE_CACHE_SIZE) | 787 | if (client->mount_args->rsize >= PAGE_CACHE_SIZE) |
802 | client->backing_dev_info.ra_pages = | 788 | client->backing_dev_info.ra_pages = |
803 | (client->mount_args.rsize + PAGE_CACHE_SIZE - 1) | 789 | (client->mount_args->rsize + PAGE_CACHE_SIZE - 1) |
804 | >> PAGE_SHIFT; | 790 | >> PAGE_SHIFT; |
805 | 791 | ||
806 | err = bdi_register_dev(&client->backing_dev_info, sb->s_dev); | 792 | err = bdi_register_dev(&client->backing_dev_info, sb->s_dev); |
@@ -816,19 +802,23 @@ static int ceph_get_sb(struct file_system_type *fs_type, | |||
816 | int err; | 802 | int err; |
817 | int (*compare_super)(struct super_block *, void *) = ceph_compare_super; | 803 | int (*compare_super)(struct super_block *, void *) = ceph_compare_super; |
818 | const char *path = 0; | 804 | const char *path = 0; |
805 | struct ceph_mount_args *args; | ||
819 | 806 | ||
820 | dout("ceph_get_sb\n"); | 807 | dout("ceph_get_sb\n"); |
808 | args = parse_mount_args(flags, data, dev_name, &path); | ||
809 | if (IS_ERR(args)) { | ||
810 | err = PTR_ERR(args); | ||
811 | goto out_final; | ||
812 | } | ||
821 | 813 | ||
822 | /* create client (which we may/may not use) */ | 814 | /* create client (which we may/may not use) */ |
823 | client = ceph_create_client(); | 815 | client = ceph_create_client(args); |
824 | if (IS_ERR(client)) | 816 | if (IS_ERR(client)) { |
825 | return PTR_ERR(client); | 817 | err = PTR_ERR(client); |
826 | 818 | goto out_final; | |
827 | err = parse_mount_args(client, flags, data, dev_name, &path); | 819 | } |
828 | if (err < 0) | ||
829 | goto out; | ||
830 | 820 | ||
831 | if (client->mount_args.flags & CEPH_OPT_NOSHARE) | 821 | if (client->mount_args->flags & CEPH_OPT_NOSHARE) |
832 | compare_super = NULL; | 822 | compare_super = NULL; |
833 | sb = sget(fs_type, compare_super, ceph_set_super, client); | 823 | sb = sget(fs_type, compare_super, ceph_set_super, client); |
834 | if (IS_ERR(sb)) { | 824 | if (IS_ERR(sb)) { |
@@ -846,7 +836,7 @@ static int ceph_get_sb(struct file_system_type *fs_type, | |||
846 | /* set up mempools */ | 836 | /* set up mempools */ |
847 | err = -ENOMEM; | 837 | err = -ENOMEM; |
848 | client->wb_pagevec_pool = mempool_create_kmalloc_pool(10, | 838 | client->wb_pagevec_pool = mempool_create_kmalloc_pool(10, |
849 | client->mount_args.wsize >> PAGE_CACHE_SHIFT); | 839 | client->mount_args->wsize >> PAGE_CACHE_SHIFT); |
850 | if (!client->wb_pagevec_pool) | 840 | if (!client->wb_pagevec_pool) |
851 | goto out_splat; | 841 | goto out_splat; |
852 | 842 | ||