diff options
author | Sunil Mushran <sunil.mushran@oracle.com> | 2010-10-07 18:23:50 -0400 |
---|---|---|
committer | Sunil Mushran <sunil.mushran@oracle.com> | 2010-10-07 18:23:50 -0400 |
commit | 2c442719e90a44a6982c033d69df4aae4b167cfa (patch) | |
tree | 33719bdeeab9dc0fcb5898ca673aaa248b639dbb /fs/ocfs2/super.c | |
parent | 98f486f23bc5b6a6fa90e1a0707b7e9fe0e7f3e4 (diff) |
ocfs2: Add support for heartbeat=global mount option
Adds support for heartbeat=global mount option. It ensures that the heartbeat
mode passed matches the one enabled on disk.
Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r-- | fs/ocfs2/super.c | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 755431739396..4e009ad303a1 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, |
@@ -190,6 +191,7 @@ static const match_table_t tokens = { | |||
190 | {Opt_nointr, "nointr"}, | 191 | {Opt_nointr, "nointr"}, |
191 | {Opt_hb_none, OCFS2_HB_NONE}, | 192 | {Opt_hb_none, OCFS2_HB_NONE}, |
192 | {Opt_hb_local, OCFS2_HB_LOCAL}, | 193 | {Opt_hb_local, OCFS2_HB_LOCAL}, |
194 | {Opt_hb_global, OCFS2_HB_GLOBAL}, | ||
193 | {Opt_data_ordered, "data=ordered"}, | 195 | {Opt_data_ordered, "data=ordered"}, |
194 | {Opt_data_writeback, "data=writeback"}, | 196 | {Opt_data_writeback, "data=writeback"}, |
195 | {Opt_atime_quantum, "atime_quantum=%u"}, | 197 | {Opt_atime_quantum, "atime_quantum=%u"}, |
@@ -608,6 +610,7 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) | |||
608 | int ret = 0; | 610 | int ret = 0; |
609 | struct mount_options parsed_options; | 611 | struct mount_options parsed_options; |
610 | struct ocfs2_super *osb = OCFS2_SB(sb); | 612 | struct ocfs2_super *osb = OCFS2_SB(sb); |
613 | u32 tmp; | ||
611 | 614 | ||
612 | lock_kernel(); | 615 | lock_kernel(); |
613 | 616 | ||
@@ -617,8 +620,9 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) | |||
617 | goto out; | 620 | goto out; |
618 | } | 621 | } |
619 | 622 | ||
620 | if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) != | 623 | tmp = OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL | |
621 | (parsed_options.mount_opt & OCFS2_MOUNT_HB_LOCAL)) { | 624 | OCFS2_MOUNT_HB_NONE; |
625 | if ((osb->s_mount_opt & tmp) != (parsed_options.mount_opt & tmp)) { | ||
622 | ret = -EINVAL; | 626 | ret = -EINVAL; |
623 | mlog(ML_ERROR, "Cannot change heartbeat mode on remount\n"); | 627 | mlog(ML_ERROR, "Cannot change heartbeat mode on remount\n"); |
624 | goto out; | 628 | goto out; |
@@ -809,23 +813,29 @@ bail: | |||
809 | 813 | ||
810 | static int ocfs2_verify_heartbeat(struct ocfs2_super *osb) | 814 | static int ocfs2_verify_heartbeat(struct ocfs2_super *osb) |
811 | { | 815 | { |
812 | if (ocfs2_mount_local(osb)) { | 816 | u32 hb_enabled = OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL; |
813 | if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) { | 817 | |
818 | if (osb->s_mount_opt & hb_enabled) { | ||
819 | if (ocfs2_mount_local(osb)) { | ||
814 | mlog(ML_ERROR, "Cannot heartbeat on a locally " | 820 | mlog(ML_ERROR, "Cannot heartbeat on a locally " |
815 | "mounted device.\n"); | 821 | "mounted device.\n"); |
816 | return -EINVAL; | 822 | return -EINVAL; |
817 | } | 823 | } |
818 | } | 824 | if (ocfs2_userspace_stack(osb)) { |
819 | |||
820 | if (ocfs2_userspace_stack(osb)) { | ||
821 | if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) { | ||
822 | mlog(ML_ERROR, "Userspace stack expected, but " | 825 | mlog(ML_ERROR, "Userspace stack expected, but " |
823 | "o2cb heartbeat arguments passed to mount\n"); | 826 | "o2cb heartbeat arguments passed to mount\n"); |
824 | return -EINVAL; | 827 | return -EINVAL; |
825 | } | 828 | } |
829 | if (((osb->s_mount_opt & OCFS2_MOUNT_HB_GLOBAL) && | ||
830 | !ocfs2_cluster_o2cb_global_heartbeat(osb)) || | ||
831 | ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) && | ||
832 | ocfs2_cluster_o2cb_global_heartbeat(osb))) { | ||
833 | mlog(ML_ERROR, "Mismatching o2cb heartbeat modes\n"); | ||
834 | return -EINVAL; | ||
835 | } | ||
826 | } | 836 | } |
827 | 837 | ||
828 | if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) { | 838 | if (!(osb->s_mount_opt & hb_enabled)) { |
829 | if (!ocfs2_mount_local(osb) && !ocfs2_is_hard_readonly(osb) && | 839 | if (!ocfs2_mount_local(osb) && !ocfs2_is_hard_readonly(osb) && |
830 | !ocfs2_userspace_stack(osb)) { | 840 | !ocfs2_userspace_stack(osb)) { |
831 | mlog(ML_ERROR, "Heartbeat has to be started to mount " | 841 | mlog(ML_ERROR, "Heartbeat has to be started to mount " |
@@ -1291,6 +1301,7 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1291 | { | 1301 | { |
1292 | int status; | 1302 | int status; |
1293 | char *p; | 1303 | char *p; |
1304 | u32 tmp; | ||
1294 | 1305 | ||
1295 | mlog_entry("remount: %d, options: \"%s\"\n", is_remount, | 1306 | mlog_entry("remount: %d, options: \"%s\"\n", is_remount, |
1296 | options ? options : "(none)"); | 1307 | options ? options : "(none)"); |
@@ -1322,7 +1333,10 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1322 | mopt->mount_opt |= OCFS2_MOUNT_HB_LOCAL; | 1333 | mopt->mount_opt |= OCFS2_MOUNT_HB_LOCAL; |
1323 | break; | 1334 | break; |
1324 | case Opt_hb_none: | 1335 | case Opt_hb_none: |
1325 | mopt->mount_opt &= ~OCFS2_MOUNT_HB_LOCAL; | 1336 | mopt->mount_opt |= OCFS2_MOUNT_HB_NONE; |
1337 | break; | ||
1338 | case Opt_hb_global: | ||
1339 | mopt->mount_opt |= OCFS2_MOUNT_HB_GLOBAL; | ||
1326 | break; | 1340 | break; |
1327 | case Opt_barrier: | 1341 | case Opt_barrier: |
1328 | if (match_int(&args[0], &option)) { | 1342 | if (match_int(&args[0], &option)) { |
@@ -1477,6 +1491,15 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1477 | } | 1491 | } |
1478 | } | 1492 | } |
1479 | 1493 | ||
1494 | /* Ensure only one heartbeat mode */ | ||
1495 | tmp = mopt->mount_opt & (OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL | | ||
1496 | OCFS2_MOUNT_HB_NONE); | ||
1497 | if (hweight32(tmp) != 1) { | ||
1498 | mlog(ML_ERROR, "Invalid heartbeat mount options\n"); | ||
1499 | status = 0; | ||
1500 | goto bail; | ||
1501 | } | ||
1502 | |||
1480 | status = 1; | 1503 | status = 1; |
1481 | 1504 | ||
1482 | bail: | 1505 | bail: |
@@ -1490,10 +1513,14 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1490 | unsigned long opts = osb->s_mount_opt; | 1513 | unsigned long opts = osb->s_mount_opt; |
1491 | unsigned int local_alloc_megs; | 1514 | unsigned int local_alloc_megs; |
1492 | 1515 | ||
1493 | if (opts & OCFS2_MOUNT_HB_LOCAL) | 1516 | if (opts & (OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL)) { |
1494 | seq_printf(s, ",_netdev,heartbeat=local"); | 1517 | seq_printf(s, ",_netdev"); |
1495 | else | 1518 | if (opts & OCFS2_MOUNT_HB_LOCAL) |
1496 | seq_printf(s, ",heartbeat=none"); | 1519 | seq_printf(s, ",%s", OCFS2_HB_LOCAL); |
1520 | else | ||
1521 | seq_printf(s, ",%s", OCFS2_HB_GLOBAL); | ||
1522 | } else | ||
1523 | seq_printf(s, ",%s", OCFS2_HB_NONE); | ||
1497 | 1524 | ||
1498 | if (opts & OCFS2_MOUNT_NOINTR) | 1525 | if (opts & OCFS2_MOUNT_NOINTR) |
1499 | seq_printf(s, ",nointr"); | 1526 | seq_printf(s, ",nointr"); |