diff options
author | Joel Becker <joel.becker@oracle.com> | 2010-10-15 16:03:09 -0400 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2010-10-15 16:03:09 -0400 |
commit | fc3718918f13ad72827d62d36ea0f5fb55090644 (patch) | |
tree | 4f9551256e02d08be37bab137f3d94182a67504c /fs/ocfs2/super.c | |
parent | 7bdb0d18bfd381cc5491eb95973ec5604b356c7e (diff) | |
parent | d4396eafe402b710a8535137b3bf2abe6c059a15 (diff) |
Merge branch 'globalheartbeat-2' of git://oss.oracle.com/git/smushran/linux-2.6 into ocfs2-merge-window
Conflicts:
fs/ocfs2/ocfs2.h
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r-- | fs/ocfs2/super.c | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 9122d59f8127..a8a0ca44f88f 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -162,6 +162,7 @@ enum { | |||
162 | Opt_nointr, | 162 | Opt_nointr, |
163 | Opt_hb_none, | 163 | Opt_hb_none, |
164 | Opt_hb_local, | 164 | Opt_hb_local, |
165 | Opt_hb_global, | ||
165 | Opt_data_ordered, | 166 | Opt_data_ordered, |
166 | Opt_data_writeback, | 167 | Opt_data_writeback, |
167 | Opt_atime_quantum, | 168 | Opt_atime_quantum, |
@@ -192,6 +193,7 @@ static const match_table_t tokens = { | |||
192 | {Opt_nointr, "nointr"}, | 193 | {Opt_nointr, "nointr"}, |
193 | {Opt_hb_none, OCFS2_HB_NONE}, | 194 | {Opt_hb_none, OCFS2_HB_NONE}, |
194 | {Opt_hb_local, OCFS2_HB_LOCAL}, | 195 | {Opt_hb_local, OCFS2_HB_LOCAL}, |
196 | {Opt_hb_global, OCFS2_HB_GLOBAL}, | ||
195 | {Opt_data_ordered, "data=ordered"}, | 197 | {Opt_data_ordered, "data=ordered"}, |
196 | {Opt_data_writeback, "data=writeback"}, | 198 | {Opt_data_writeback, "data=writeback"}, |
197 | {Opt_atime_quantum, "atime_quantum=%u"}, | 199 | {Opt_atime_quantum, "atime_quantum=%u"}, |
@@ -626,6 +628,7 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) | |||
626 | int ret = 0; | 628 | int ret = 0; |
627 | struct mount_options parsed_options; | 629 | struct mount_options parsed_options; |
628 | struct ocfs2_super *osb = OCFS2_SB(sb); | 630 | struct ocfs2_super *osb = OCFS2_SB(sb); |
631 | u32 tmp; | ||
629 | 632 | ||
630 | lock_kernel(); | 633 | lock_kernel(); |
631 | 634 | ||
@@ -635,8 +638,9 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) | |||
635 | goto out; | 638 | goto out; |
636 | } | 639 | } |
637 | 640 | ||
638 | if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) != | 641 | tmp = OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL | |
639 | (parsed_options.mount_opt & OCFS2_MOUNT_HB_LOCAL)) { | 642 | OCFS2_MOUNT_HB_NONE; |
643 | if ((osb->s_mount_opt & tmp) != (parsed_options.mount_opt & tmp)) { | ||
640 | ret = -EINVAL; | 644 | ret = -EINVAL; |
641 | mlog(ML_ERROR, "Cannot change heartbeat mode on remount\n"); | 645 | mlog(ML_ERROR, "Cannot change heartbeat mode on remount\n"); |
642 | goto out; | 646 | goto out; |
@@ -827,23 +831,29 @@ bail: | |||
827 | 831 | ||
828 | static int ocfs2_verify_heartbeat(struct ocfs2_super *osb) | 832 | static int ocfs2_verify_heartbeat(struct ocfs2_super *osb) |
829 | { | 833 | { |
830 | if (ocfs2_mount_local(osb)) { | 834 | u32 hb_enabled = OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL; |
831 | if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) { | 835 | |
836 | if (osb->s_mount_opt & hb_enabled) { | ||
837 | if (ocfs2_mount_local(osb)) { | ||
832 | mlog(ML_ERROR, "Cannot heartbeat on a locally " | 838 | mlog(ML_ERROR, "Cannot heartbeat on a locally " |
833 | "mounted device.\n"); | 839 | "mounted device.\n"); |
834 | return -EINVAL; | 840 | return -EINVAL; |
835 | } | 841 | } |
836 | } | 842 | if (ocfs2_userspace_stack(osb)) { |
837 | |||
838 | if (ocfs2_userspace_stack(osb)) { | ||
839 | if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) { | ||
840 | mlog(ML_ERROR, "Userspace stack expected, but " | 843 | mlog(ML_ERROR, "Userspace stack expected, but " |
841 | "o2cb heartbeat arguments passed to mount\n"); | 844 | "o2cb heartbeat arguments passed to mount\n"); |
842 | return -EINVAL; | 845 | return -EINVAL; |
843 | } | 846 | } |
847 | if (((osb->s_mount_opt & OCFS2_MOUNT_HB_GLOBAL) && | ||
848 | !ocfs2_cluster_o2cb_global_heartbeat(osb)) || | ||
849 | ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) && | ||
850 | ocfs2_cluster_o2cb_global_heartbeat(osb))) { | ||
851 | mlog(ML_ERROR, "Mismatching o2cb heartbeat modes\n"); | ||
852 | return -EINVAL; | ||
853 | } | ||
844 | } | 854 | } |
845 | 855 | ||
846 | if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) { | 856 | if (!(osb->s_mount_opt & hb_enabled)) { |
847 | if (!ocfs2_mount_local(osb) && !ocfs2_is_hard_readonly(osb) && | 857 | if (!ocfs2_mount_local(osb) && !ocfs2_is_hard_readonly(osb) && |
848 | !ocfs2_userspace_stack(osb)) { | 858 | !ocfs2_userspace_stack(osb)) { |
849 | mlog(ML_ERROR, "Heartbeat has to be started to mount " | 859 | mlog(ML_ERROR, "Heartbeat has to be started to mount " |
@@ -1309,6 +1319,7 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1309 | { | 1319 | { |
1310 | int status; | 1320 | int status; |
1311 | char *p; | 1321 | char *p; |
1322 | u32 tmp; | ||
1312 | 1323 | ||
1313 | mlog_entry("remount: %d, options: \"%s\"\n", is_remount, | 1324 | mlog_entry("remount: %d, options: \"%s\"\n", is_remount, |
1314 | options ? options : "(none)"); | 1325 | options ? options : "(none)"); |
@@ -1340,7 +1351,10 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1340 | mopt->mount_opt |= OCFS2_MOUNT_HB_LOCAL; | 1351 | mopt->mount_opt |= OCFS2_MOUNT_HB_LOCAL; |
1341 | break; | 1352 | break; |
1342 | case Opt_hb_none: | 1353 | case Opt_hb_none: |
1343 | mopt->mount_opt &= ~OCFS2_MOUNT_HB_LOCAL; | 1354 | mopt->mount_opt |= OCFS2_MOUNT_HB_NONE; |
1355 | break; | ||
1356 | case Opt_hb_global: | ||
1357 | mopt->mount_opt |= OCFS2_MOUNT_HB_GLOBAL; | ||
1344 | break; | 1358 | break; |
1345 | case Opt_barrier: | 1359 | case Opt_barrier: |
1346 | if (match_int(&args[0], &option)) { | 1360 | if (match_int(&args[0], &option)) { |
@@ -1501,6 +1515,15 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1501 | } | 1515 | } |
1502 | } | 1516 | } |
1503 | 1517 | ||
1518 | /* Ensure only one heartbeat mode */ | ||
1519 | tmp = mopt->mount_opt & (OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL | | ||
1520 | OCFS2_MOUNT_HB_NONE); | ||
1521 | if (hweight32(tmp) != 1) { | ||
1522 | mlog(ML_ERROR, "Invalid heartbeat mount options\n"); | ||
1523 | status = 0; | ||
1524 | goto bail; | ||
1525 | } | ||
1526 | |||
1504 | status = 1; | 1527 | status = 1; |
1505 | 1528 | ||
1506 | bail: | 1529 | bail: |
@@ -1514,10 +1537,14 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1514 | unsigned long opts = osb->s_mount_opt; | 1537 | unsigned long opts = osb->s_mount_opt; |
1515 | unsigned int local_alloc_megs; | 1538 | unsigned int local_alloc_megs; |
1516 | 1539 | ||
1517 | if (opts & OCFS2_MOUNT_HB_LOCAL) | 1540 | if (opts & (OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL)) { |
1518 | seq_printf(s, ",_netdev,heartbeat=local"); | 1541 | seq_printf(s, ",_netdev"); |
1519 | else | 1542 | if (opts & OCFS2_MOUNT_HB_LOCAL) |
1520 | seq_printf(s, ",heartbeat=none"); | 1543 | seq_printf(s, ",%s", OCFS2_HB_LOCAL); |
1544 | else | ||
1545 | seq_printf(s, ",%s", OCFS2_HB_GLOBAL); | ||
1546 | } else | ||
1547 | seq_printf(s, ",%s", OCFS2_HB_NONE); | ||
1521 | 1548 | ||
1522 | if (opts & OCFS2_MOUNT_NOINTR) | 1549 | if (opts & OCFS2_MOUNT_NOINTR) |
1523 | seq_printf(s, ",nointr"); | 1550 | seq_printf(s, ",nointr"); |
@@ -2209,7 +2236,9 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
2209 | goto bail; | 2236 | goto bail; |
2210 | } | 2237 | } |
2211 | 2238 | ||
2212 | if (ocfs2_userspace_stack(osb)) { | 2239 | if (ocfs2_clusterinfo_valid(osb)) { |
2240 | osb->osb_stackflags = | ||
2241 | OCFS2_RAW_SB(di)->s_cluster_info.ci_stackflags; | ||
2213 | memcpy(osb->osb_cluster_stack, | 2242 | memcpy(osb->osb_cluster_stack, |
2214 | OCFS2_RAW_SB(di)->s_cluster_info.ci_stack, | 2243 | OCFS2_RAW_SB(di)->s_cluster_info.ci_stack, |
2215 | OCFS2_STACK_LABEL_LEN); | 2244 | OCFS2_STACK_LABEL_LEN); |