aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunil Mushran <sunil.mushran@oracle.com>2010-10-07 18:23:50 -0400
committerSunil Mushran <sunil.mushran@oracle.com>2010-10-07 18:23:50 -0400
commit2c442719e90a44a6982c033d69df4aae4b167cfa (patch)
tree33719bdeeab9dc0fcb5898ca673aaa248b639dbb
parent98f486f23bc5b6a6fa90e1a0707b7e9fe0e7f3e4 (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>
-rw-r--r--fs/ocfs2/ocfs2.h4
-rw-r--r--fs/ocfs2/ocfs2_fs.h1
-rw-r--r--fs/ocfs2/super.c55
3 files changed, 45 insertions, 15 deletions
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index d5496a792bdb..481387b90b21 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -243,7 +243,7 @@ enum ocfs2_local_alloc_state
243 243
244enum ocfs2_mount_options 244enum ocfs2_mount_options
245{ 245{
246 OCFS2_MOUNT_HB_LOCAL = 1 << 0, /* Heartbeat started in local mode */ 246 OCFS2_MOUNT_HB_LOCAL = 1 << 0, /* Local heartbeat */
247 OCFS2_MOUNT_BARRIER = 1 << 1, /* Use block barriers */ 247 OCFS2_MOUNT_BARRIER = 1 << 1, /* Use block barriers */
248 OCFS2_MOUNT_NOINTR = 1 << 2, /* Don't catch signals */ 248 OCFS2_MOUNT_NOINTR = 1 << 2, /* Don't catch signals */
249 OCFS2_MOUNT_ERRORS_PANIC = 1 << 3, /* Panic on errors */ 249 OCFS2_MOUNT_ERRORS_PANIC = 1 << 3, /* Panic on errors */
@@ -256,6 +256,8 @@ enum ocfs2_mount_options
256 control lists */ 256 control lists */
257 OCFS2_MOUNT_USRQUOTA = 1 << 10, /* We support user quotas */ 257 OCFS2_MOUNT_USRQUOTA = 1 << 10, /* We support user quotas */
258 OCFS2_MOUNT_GRPQUOTA = 1 << 11, /* We support group quotas */ 258 OCFS2_MOUNT_GRPQUOTA = 1 << 11, /* We support group quotas */
259 OCFS2_MOUNT_HB_NONE = 1 << 12, /* No heartbeat */
260 OCFS2_MOUNT_HB_GLOBAL = 1 << 13, /* Global heartbeat */
259}; 261};
260 262
261#define OCFS2_OSB_SOFT_RO 0x0001 263#define OCFS2_OSB_SOFT_RO 0x0001
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index d5b1d99abc3c..28ff536b4f8d 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -376,6 +376,7 @@ static struct ocfs2_system_inode_info ocfs2_system_inodes[NUM_SYSTEM_INODES] = {
376/* Parameter passed from mount.ocfs2 to module */ 376/* Parameter passed from mount.ocfs2 to module */
377#define OCFS2_HB_NONE "heartbeat=none" 377#define OCFS2_HB_NONE "heartbeat=none"
378#define OCFS2_HB_LOCAL "heartbeat=local" 378#define OCFS2_HB_LOCAL "heartbeat=local"
379#define OCFS2_HB_GLOBAL "heartbeat=global"
379 380
380/* 381/*
381 * OCFS2 directory file types. Only the low 3 bits are used. The 382 * OCFS2 directory file types. Only the low 3 bits are used. The
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
810static int ocfs2_verify_heartbeat(struct ocfs2_super *osb) 814static 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
1482bail: 1505bail:
@@ -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");