aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/super.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2009-10-27 14:50:50 -0400
committerSage Weil <sage@newdream.net>2009-10-27 14:57:03 -0400
commit6b8051855d983db8480ff1ea1b02ef2b49203c22 (patch)
treeafb72be534ddd4c474a2ec9b7cf2ea5ab86799bc /fs/ceph/super.c
parente53c2fe075feda1fd4f009956ac026dc24c3a199 (diff)
ceph: allocate and parse mount args before client instance
This simplifies much of the error handling during mount. It also means that we have the mount args before client creation, and we can initialize based on those options. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/super.c')
-rw-r--r--fs/ceph/super.c106
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)
110static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) 110static 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
310static int parse_mount_args(struct ceph_client *client, 310static 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
486out: 468out:
487 kfree(mon_addr); 469 kfree(args->mon_addr);
488 return err; 470 kfree(args);
471 return ERR_PTR(err);
489} 472}
490 473
491static void release_mount_args(struct ceph_mount_args *args) 474static 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 */
502static struct ceph_client *ceph_create_client(void) 487static 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:
756static int ceph_compare_super(struct super_block *sb, void *data) 742static 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