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"); |
