aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
authorTiger Yang <tiger.yang@oracle.com>2007-09-07 12:16:10 -0400
committerMark Fasheh <mark.fasheh@oracle.com>2007-09-11 14:38:48 -0400
commitc0123adef626607535f3c2c93b530c36780885e0 (patch)
treece61b2efb74c14632fa2584fb45ef37df3b3dedd /fs/ocfs2
parent10b0845bed2b93f88d9758880a0a0e53f50c5139 (diff)
[PATCH] ocfs2: fix mount option parsing
For some mount option types, ocfs2_parse_options() will try to access sb->s_fs_info to get at the ocfs2 private superblock. Unfortunately, that hasn't been allocated yet and will cause a kernel crash. Fix this by storing options in a struct which can then get pushed into the ocfs2_super once it's been allocated later. If we need more options which store to the ocfs2_super in the future, we can just fields to this struct. Signed-off-by: Tiger Yang <tiger.yang@oracle.com> Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/super.c69
1 files changed, 37 insertions, 32 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index f2fc9a795deb..c034b5129c1e 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -81,8 +81,15 @@ static struct dentry *ocfs2_debugfs_root = NULL;
81MODULE_AUTHOR("Oracle"); 81MODULE_AUTHOR("Oracle");
82MODULE_LICENSE("GPL"); 82MODULE_LICENSE("GPL");
83 83
84struct mount_options
85{
86 unsigned long mount_opt;
87 unsigned int atime_quantum;
88 signed short slot;
89};
90
84static int ocfs2_parse_options(struct super_block *sb, char *options, 91static int ocfs2_parse_options(struct super_block *sb, char *options,
85 unsigned long *mount_opt, s16 *slot, 92 struct mount_options *mopt,
86 int is_remount); 93 int is_remount);
87static void ocfs2_put_super(struct super_block *sb); 94static void ocfs2_put_super(struct super_block *sb);
88static int ocfs2_mount_volume(struct super_block *sb); 95static int ocfs2_mount_volume(struct super_block *sb);
@@ -367,24 +374,23 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
367{ 374{
368 int incompat_features; 375 int incompat_features;
369 int ret = 0; 376 int ret = 0;
370 unsigned long parsed_options; 377 struct mount_options parsed_options;
371 s16 slot;
372 struct ocfs2_super *osb = OCFS2_SB(sb); 378 struct ocfs2_super *osb = OCFS2_SB(sb);
373 379
374 if (!ocfs2_parse_options(sb, data, &parsed_options, &slot, 1)) { 380 if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) {
375 ret = -EINVAL; 381 ret = -EINVAL;
376 goto out; 382 goto out;
377 } 383 }
378 384
379 if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) != 385 if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) !=
380 (parsed_options & OCFS2_MOUNT_HB_LOCAL)) { 386 (parsed_options.mount_opt & OCFS2_MOUNT_HB_LOCAL)) {
381 ret = -EINVAL; 387 ret = -EINVAL;
382 mlog(ML_ERROR, "Cannot change heartbeat mode on remount\n"); 388 mlog(ML_ERROR, "Cannot change heartbeat mode on remount\n");
383 goto out; 389 goto out;
384 } 390 }
385 391
386 if ((osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK) != 392 if ((osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK) !=
387 (parsed_options & OCFS2_MOUNT_DATA_WRITEBACK)) { 393 (parsed_options.mount_opt & OCFS2_MOUNT_DATA_WRITEBACK)) {
388 ret = -EINVAL; 394 ret = -EINVAL;
389 mlog(ML_ERROR, "Cannot change data mode on remount\n"); 395 mlog(ML_ERROR, "Cannot change data mode on remount\n");
390 goto out; 396 goto out;
@@ -435,7 +441,9 @@ unlock_osb:
435 441
436 /* Only save off the new mount options in case of a successful 442 /* Only save off the new mount options in case of a successful
437 * remount. */ 443 * remount. */
438 osb->s_mount_opt = parsed_options; 444 osb->s_mount_opt = parsed_options.mount_opt;
445 osb->s_atime_quantum = parsed_options.atime_quantum;
446 osb->preferred_slot = parsed_options.slot;
439 } 447 }
440out: 448out:
441 return ret; 449 return ret;
@@ -547,8 +555,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
547{ 555{
548 struct dentry *root; 556 struct dentry *root;
549 int status, sector_size; 557 int status, sector_size;
550 unsigned long parsed_opt; 558 struct mount_options parsed_options;
551 s16 slot;
552 struct inode *inode = NULL; 559 struct inode *inode = NULL;
553 struct ocfs2_super *osb = NULL; 560 struct ocfs2_super *osb = NULL;
554 struct buffer_head *bh = NULL; 561 struct buffer_head *bh = NULL;
@@ -556,14 +563,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
556 563
557 mlog_entry("%p, %p, %i", sb, data, silent); 564 mlog_entry("%p, %p, %i", sb, data, silent);
558 565
559 if (!ocfs2_parse_options(sb, data, &parsed_opt, &slot, 0)) { 566 if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) {
560 status = -EINVAL; 567 status = -EINVAL;
561 goto read_super_error; 568 goto read_super_error;
562 } 569 }
563 570
564 /* for now we only have one cluster/node, make sure we see it 571 /* for now we only have one cluster/node, make sure we see it
565 * in the heartbeat universe */ 572 * in the heartbeat universe */
566 if (parsed_opt & OCFS2_MOUNT_HB_LOCAL) { 573 if (parsed_options.mount_opt & OCFS2_MOUNT_HB_LOCAL) {
567 if (!o2hb_check_local_node_heartbeating()) { 574 if (!o2hb_check_local_node_heartbeating()) {
568 status = -EINVAL; 575 status = -EINVAL;
569 goto read_super_error; 576 goto read_super_error;
@@ -585,8 +592,9 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
585 } 592 }
586 brelse(bh); 593 brelse(bh);
587 bh = NULL; 594 bh = NULL;
588 osb->s_mount_opt = parsed_opt; 595 osb->s_mount_opt = parsed_options.mount_opt;
589 osb->preferred_slot = slot; 596 osb->s_atime_quantum = parsed_options.atime_quantum;
597 osb->preferred_slot = parsed_options.slot;
590 598
591 sb->s_magic = OCFS2_SUPER_MAGIC; 599 sb->s_magic = OCFS2_SUPER_MAGIC;
592 600
@@ -728,8 +736,7 @@ static struct file_system_type ocfs2_fs_type = {
728 736
729static int ocfs2_parse_options(struct super_block *sb, 737static int ocfs2_parse_options(struct super_block *sb,
730 char *options, 738 char *options,
731 unsigned long *mount_opt, 739 struct mount_options *mopt,
732 s16 *slot,
733 int is_remount) 740 int is_remount)
734{ 741{
735 int status; 742 int status;
@@ -738,8 +745,9 @@ static int ocfs2_parse_options(struct super_block *sb,
738 mlog_entry("remount: %d, options: \"%s\"\n", is_remount, 745 mlog_entry("remount: %d, options: \"%s\"\n", is_remount,
739 options ? options : "(none)"); 746 options ? options : "(none)");
740 747
741 *mount_opt = 0; 748 mopt->mount_opt = 0;
742 *slot = OCFS2_INVALID_SLOT; 749 mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
750 mopt->slot = OCFS2_INVALID_SLOT;
743 751
744 if (!options) { 752 if (!options) {
745 status = 1; 753 status = 1;
@@ -749,7 +757,6 @@ static int ocfs2_parse_options(struct super_block *sb,
749 while ((p = strsep(&options, ",")) != NULL) { 757 while ((p = strsep(&options, ",")) != NULL) {
750 int token, option; 758 int token, option;
751 substring_t args[MAX_OPT_ARGS]; 759 substring_t args[MAX_OPT_ARGS];
752 struct ocfs2_super * osb = OCFS2_SB(sb);
753 760
754 if (!*p) 761 if (!*p)
755 continue; 762 continue;
@@ -757,10 +764,10 @@ static int ocfs2_parse_options(struct super_block *sb,
757 token = match_token(p, tokens, args); 764 token = match_token(p, tokens, args);
758 switch (token) { 765 switch (token) {
759 case Opt_hb_local: 766 case Opt_hb_local:
760 *mount_opt |= OCFS2_MOUNT_HB_LOCAL; 767 mopt->mount_opt |= OCFS2_MOUNT_HB_LOCAL;
761 break; 768 break;
762 case Opt_hb_none: 769 case Opt_hb_none:
763 *mount_opt &= ~OCFS2_MOUNT_HB_LOCAL; 770 mopt->mount_opt &= ~OCFS2_MOUNT_HB_LOCAL;
764 break; 771 break;
765 case Opt_barrier: 772 case Opt_barrier:
766 if (match_int(&args[0], &option)) { 773 if (match_int(&args[0], &option)) {
@@ -768,27 +775,27 @@ static int ocfs2_parse_options(struct super_block *sb,
768 goto bail; 775 goto bail;
769 } 776 }
770 if (option) 777 if (option)
771 *mount_opt |= OCFS2_MOUNT_BARRIER; 778 mopt->mount_opt |= OCFS2_MOUNT_BARRIER;
772 else 779 else
773 *mount_opt &= ~OCFS2_MOUNT_BARRIER; 780 mopt->mount_opt &= ~OCFS2_MOUNT_BARRIER;
774 break; 781 break;
775 case Opt_intr: 782 case Opt_intr:
776 *mount_opt &= ~OCFS2_MOUNT_NOINTR; 783 mopt->mount_opt &= ~OCFS2_MOUNT_NOINTR;
777 break; 784 break;
778 case Opt_nointr: 785 case Opt_nointr:
779 *mount_opt |= OCFS2_MOUNT_NOINTR; 786 mopt->mount_opt |= OCFS2_MOUNT_NOINTR;
780 break; 787 break;
781 case Opt_err_panic: 788 case Opt_err_panic:
782 *mount_opt |= OCFS2_MOUNT_ERRORS_PANIC; 789 mopt->mount_opt |= OCFS2_MOUNT_ERRORS_PANIC;
783 break; 790 break;
784 case Opt_err_ro: 791 case Opt_err_ro:
785 *mount_opt &= ~OCFS2_MOUNT_ERRORS_PANIC; 792 mopt->mount_opt &= ~OCFS2_MOUNT_ERRORS_PANIC;
786 break; 793 break;
787 case Opt_data_ordered: 794 case Opt_data_ordered:
788 *mount_opt &= ~OCFS2_MOUNT_DATA_WRITEBACK; 795 mopt->mount_opt &= ~OCFS2_MOUNT_DATA_WRITEBACK;
789 break; 796 break;
790 case Opt_data_writeback: 797 case Opt_data_writeback:
791 *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK; 798 mopt->mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK;
792 break; 799 break;
793 case Opt_atime_quantum: 800 case Opt_atime_quantum:
794 if (match_int(&args[0], &option)) { 801 if (match_int(&args[0], &option)) {
@@ -796,9 +803,7 @@ static int ocfs2_parse_options(struct super_block *sb,
796 goto bail; 803 goto bail;
797 } 804 }
798 if (option >= 0) 805 if (option >= 0)
799 osb->s_atime_quantum = option; 806 mopt->atime_quantum = option;
800 else
801 osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
802 break; 807 break;
803 case Opt_slot: 808 case Opt_slot:
804 option = 0; 809 option = 0;
@@ -807,7 +812,7 @@ static int ocfs2_parse_options(struct super_block *sb,
807 goto bail; 812 goto bail;
808 } 813 }
809 if (option) 814 if (option)
810 *slot = (s16)option; 815 mopt->slot = (s16)option;
811 break; 816 break;
812 default: 817 default:
813 mlog(ML_ERROR, 818 mlog(ML_ERROR,