[Ocfs2-tools-devel] [PATCH 20/25] libocfs2: Add a compat feature flag OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2

Sunil Mushran sunil.mushran at oracle.com
Wed Jun 23 11:44:30 PDT 2010


OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2 denotes an enhanced s_cluster_info in
the super block. This field now allows the storage of cluster stack specific
flag.

This patch also introduces a clusterinfo flag OCFS2_CLUSTER_O2CB_GLOBAL_HEARTBEAT
to denote the enabled global heartbeat mode.

This flag is set and cleared using tunefs.ocfs2 --fs-features=[no]clusterinfo-v2.

The global heartbeat flag is set and cleared using tunefs.ocfs2 --update-cluster-stack.

Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
---
 debugfs.ocfs2/dump.c                  |    4 +
 debugfs.ocfs2/include/utils.h         |    2 +
 debugfs.ocfs2/utils.c                 |   18 +++++
 include/ocfs2-kernel/ocfs2_fs.h       |   27 +++++++-
 include/ocfs2/ocfs2.h                 |   16 ++++
 libocfs2/feature_string.c             |   47 +++++++++++--
 tunefs.ocfs2/Makefile                 |    3 +-
 tunefs.ocfs2/feature_clusterinfo_v2.c |  125 +++++++++++++++++++++++++++++++++
 tunefs.ocfs2/op_features.c            |    2 +
 9 files changed, 234 insertions(+), 10 deletions(-)
 create mode 100644 tunefs.ocfs2/feature_clusterinfo_v2.c

diff --git a/debugfs.ocfs2/dump.c b/debugfs.ocfs2/dump.c
index dc59071..762f923 100644
--- a/debugfs.ocfs2/dump.c
+++ b/debugfs.ocfs2/dump.c
@@ -102,6 +102,10 @@ void dump_super_block(FILE *out, struct ocfs2_super_block *sb)
 	else
 		fprintf(out, "\tCluster stack: classic o2cb\n");
 
+	get_cluster_info_flag(sb, buf, sizeof(buf));
+	fprintf(out, "\tCluster flags: %u %s\n",
+		sb->s_cluster_info.ci_stackflags, buf);
+
 	return ;
 }
 
diff --git a/debugfs.ocfs2/include/utils.h b/debugfs.ocfs2/include/utils.h
index 96de0cf..8b5c90c 100644
--- a/debugfs.ocfs2/include/utils.h
+++ b/debugfs.ocfs2/include/utils.h
@@ -41,6 +41,8 @@ void get_incompat_flag(struct ocfs2_super_block *sb, char *buf, size_t count);
 void get_tunefs_flag(struct ocfs2_super_block *sb, char *buf, size_t count);
 void get_compat_flag(struct ocfs2_super_block *sb, char *buf, size_t count);
 void get_rocompat_flag(struct ocfs2_super_block *sb, char *buf, size_t count);
+void get_cluster_info_flag(struct ocfs2_super_block *sb, char *buf,
+			   size_t count);
 void get_journal_block_type (uint32_t jtype, GString *str);
 void get_tag_flag (uint32_t flags, GString *str);
 FILE *open_pager(int interactive);
diff --git a/debugfs.ocfs2/utils.c b/debugfs.ocfs2/utils.c
index 38b4f6d..d14ba98 100644
--- a/debugfs.ocfs2/utils.c
+++ b/debugfs.ocfs2/utils.c
@@ -78,6 +78,24 @@ void get_rocompat_flag(struct ocfs2_super_block *sb, char *buf, size_t count)
 		com_err(gbls.cmd, err, "while processing ro compat flags");
 }
 
+void get_cluster_info_flag(struct ocfs2_super_block *sb, char *buf,
+			   size_t count)
+{
+	errcode_t err = 0;
+
+	*buf = '\0';
+	if (!ocfs2_clusterinfo_v2(sb))
+		return;
+
+	if (!ocfs2_o2cb_stack(sb))
+		return;
+
+	err = ocfs2_snprint_cluster_o2cb_flags(buf, count,
+					sb->s_cluster_info.ci_stackflags);
+	if (err)
+		com_err(gbls.cmd, err, "while processing clusterinfo flags");
+}
+
 /*
  * get_journal_block_type()
  *
diff --git a/include/ocfs2-kernel/ocfs2_fs.h b/include/ocfs2-kernel/ocfs2_fs.h
index 7b7de72..e6b4da1 100644
--- a/include/ocfs2-kernel/ocfs2_fs.h
+++ b/include/ocfs2-kernel/ocfs2_fs.h
@@ -91,7 +91,8 @@
 	OCFS2_SB(sb)->s_feature_incompat &= ~(mask)
 
 #define OCFS2_FEATURE_COMPAT_SUPP	(OCFS2_FEATURE_COMPAT_BACKUP_SB	\
-					 | OCFS2_FEATURE_COMPAT_JBD2_SB)
+					 | OCFS2_FEATURE_COMPAT_JBD2_SB \
+					 | OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2)
 #define OCFS2_FEATURE_INCOMPAT_SUPP	(OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT \
 					 | OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC \
 					 | OCFS2_FEATURE_INCOMPAT_INLINE_DATA \
@@ -185,6 +186,11 @@
 #define OCFS2_FEATURE_COMPAT_JBD2_SB		0x0002
 
 /*
+ * With this bit set, the ci_flag in ocfs2_cluster_info can be trusted.
+ */
+#define OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2	0x0004
+
+/*
  * Unwritten extents support.
  */
 #define OCFS2_FEATURE_RO_COMPAT_UNWRITTEN	0x0001
@@ -307,6 +313,11 @@
  */
 #define OCFS2_MIN_XATTR_INLINE_SIZE     256
 
+/*
+ * Cluster info flags (ocfs2_cluster_info.ci_stackflags)
+ */
+#define OCFS2_CLUSTER_O2CB_GLOBAL_HEARTBEAT	(0x01)
+
 struct ocfs2_system_inode_info {
 	char	*si_name;
 	int	si_iflags;
@@ -564,9 +575,21 @@ struct ocfs2_slot_map_extended {
  */
 };
 
+/*
+ * ci_stackflags is only valid if the compat bit
+ * OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2 is set.
+ */
 struct ocfs2_cluster_info {
 /*00*/	__u8   ci_stack[OCFS2_STACK_LABEL_LEN];
-	__le32 ci_reserved;
+	union {
+		__le32 ci_reserved;
+		struct {
+			__u8 ci_reserved1;
+			__u8 ci_reserved2;
+			__u8 ci_reserved3;
+			__u8 ci_stackflags;
+		};
+	};
 /*08*/	__u8   ci_cluster[OCFS2_CLUSTER_NAME_LEN];
 /*18*/
 };
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index 34e83f4..b4cb4dd 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -961,6 +961,8 @@ errcode_t ocfs2_snprint_feature_flags(char *str, size_t size,
 errcode_t ocfs2_snprint_tunefs_flags(char *str, size_t size, uint16_t flags);
 errcode_t ocfs2_snprint_extent_flags(char *str, size_t size, uint8_t flags);
 errcode_t ocfs2_snprint_refcount_flags(char *str, size_t size, uint8_t flags);
+errcode_t ocfs2_snprint_cluster_o2cb_flags(char *str, size_t size,
+					   uint8_t flags);
 errcode_t ocfs2_parse_feature(const char *opts,
 			      ocfs2_fs_options *feature_flags,
 			      ocfs2_fs_options *reverse_flags);
@@ -1251,6 +1253,20 @@ static inline int ocfs2_clusterinfo_valid(struct ocfs2_super_block *osb)
 	return 0;
 }
 
+static inline int ocfs2_clusterinfo_v2(struct ocfs2_super_block *osb)
+{
+	if (osb->s_feature_compat & OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2)
+		return 1;
+	return 0;
+}
+
+static inline int ocfs2_cluster_o2cb_global_heartbeat(struct ocfs2_super_block *osb)
+{
+	return (ocfs2_o2cb_stack(osb) && ocfs2_clusterinfo_v2(osb) &&
+		(osb->s_cluster_info.ci_stackflags &
+		 OCFS2_CLUSTER_O2CB_GLOBAL_HEARTBEAT));
+}
+
 static inline int ocfs2_writes_unwritten_extents(struct ocfs2_super_block *osb)
 {
 	/*
diff --git a/libocfs2/feature_string.c b/libocfs2/feature_string.c
index ad44807..da3d328 100644
--- a/libocfs2/feature_string.c
+++ b/libocfs2/feature_string.c
@@ -61,17 +61,20 @@ static struct feature_level_translation ocfs2_feature_levels_table[] = {
 };
 
 static ocfs2_fs_options feature_level_defaults[] = {
-	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
+	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB |
+		OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2,
 	 OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
 	 OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
 	 OCFS2_FEATURE_INCOMPAT_XATTR,
 	 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},  /* OCFS2_FEATURE_LEVEL_DEFAULT */
 
-	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
+	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB |
+		OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2,
 	 0,
 	 0}, /* OCFS2_FEATURE_LEVEL_MAX_COMPAT */
 
-	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
+	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB |
+		OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2,
 	 OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
 	 OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP |
 	 OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
@@ -85,25 +88,29 @@ static ocfs2_fs_options feature_level_defaults[] = {
 };
 
 static ocfs2_fs_options mkfstypes_features_defaults[] = {
-	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
+	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB |
+		OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2,
 	 OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
 	 OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
 	 OCFS2_FEATURE_INCOMPAT_XATTR,
 	 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},  /* OCFS2_MKFSTYPE_DEFAULT */
 
-	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
+	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB |
+		OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2,
 	 OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
 	 OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
 	 OCFS2_FEATURE_INCOMPAT_XATTR,
 	 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},  /* OCFS2_MKFSTYPE_DATAFILES */
 
-	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
+	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB |
+		OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2,
 	 OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
 	 OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
 	 OCFS2_FEATURE_INCOMPAT_XATTR,
 	 OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},  /* OCFS2_MKFSTYPE_MAIL */
 
-	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
+	{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB |
+		OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2,
 	 OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
 	 OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
 	 OCFS2_FEATURE_INCOMPAT_XATTR |
@@ -175,6 +182,11 @@ static struct fs_feature_flags ocfs2_supported_features[] = {
 		{0, OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE, 0},
 	},
 	{
+		"clusterinfo-v2",
+		{OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2, 0, 0},
+		{OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2, 0, 0},
+	},
+	{
 		NULL,
 		{0, 0, 0},
 		{0, 0, 0}
@@ -266,6 +278,10 @@ static struct feature_name ocfs2_feature_names[] = {
 		.fn_flag = {0, OCFS2_FEATURE_INCOMPAT_O2CB_STACK, 0},
 	},
 	{
+		.fn_name = "clusterinfo-v2",
+		.fn_flag = {OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2, 0, 0},
+	},
+	{
 		.fn_name = NULL,
 	},
 };
@@ -330,6 +346,16 @@ static struct flag_name ocfs2_refcount_flag_names[] = {
 	},
 };
 
+static struct flag_name ocfs2_cluster_o2cb_flag_names[] = {
+	{
+		.fl_name = "Globalheartbeat",
+		.fl_flag = OCFS2_CLUSTER_O2CB_GLOBAL_HEARTBEAT,
+	},
+	{
+		.fl_name = NULL,
+	},
+};
+
 static inline void merge_features(ocfs2_fs_options *features,
 				  ocfs2_fs_options new_features)
 {
@@ -494,6 +520,13 @@ errcode_t ocfs2_snprint_refcount_flags(char *str, size_t size, uint8_t flags)
 					str, size, (uint32_t)flags);
 }
 
+errcode_t ocfs2_snprint_cluster_o2cb_flags(char *str, size_t size,
+					   uint8_t flags)
+{
+	return ocfs2_snprint_flag_names(ocfs2_cluster_o2cb_flag_names,
+					str, size, (uint32_t)flags);
+}
+
 /*
  * If we are asked to clear a feature, we also need to clear any other
  * features that depend on it.
diff --git a/tunefs.ocfs2/Makefile b/tunefs.ocfs2/Makefile
index 6219af6..e9d77b1 100644
--- a/tunefs.ocfs2/Makefile
+++ b/tunefs.ocfs2/Makefile
@@ -27,7 +27,8 @@ OCFS2NE_FEATURES =			\
 	feature_unwritten_extents	\
 	feature_xattr			\
 	feature_indexed_dirs		\
-	feature_quota
+	feature_quota			\
+	feature_clusterinfo_v2
 
 OCFS2NE_OPERATIONS =			\
 	op_cloned_volume		\
diff --git a/tunefs.ocfs2/feature_clusterinfo_v2.c b/tunefs.ocfs2/feature_clusterinfo_v2.c
new file mode 100644
index 0000000..1897662
--- /dev/null
+++ b/tunefs.ocfs2/feature_clusterinfo_v2.c
@@ -0,0 +1,125 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * feature_clusterinfo_v2.c
+ *
+ * ocfs2 tune utility to enable and disable the clusterinfo_v2 feature flag.
+ *
+ * Copyright (C) 2010 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#include "ocfs2/ocfs2.h"
+
+#include "libocfs2ne.h"
+
+
+static int enable_clusterinfo_v2(ocfs2_filesys *fs, int flags)
+{
+	errcode_t err = 0;
+	struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super);
+	struct tools_progress *prog;
+
+	if (ocfs2_clusterinfo_v2(super)) {
+		verbosef(VL_APP,
+			 "Clusterinfo v2 feature is already enabled; "
+			 "nothing to enable\n");
+		goto out;
+	}
+
+	if (!tools_interact("Enable the clusterinfo v2 feature on "
+			    "device \"%s\"? ",
+			    fs->fs_devname))
+		goto out;
+
+	prog = tools_progress_start("Enable clusterinfo-v2",
+				    "clusterinfo-v2", 1);
+	if (!prog) {
+		err = TUNEFS_ET_NO_MEMORY;
+		tcom_err(err, "while initializing the progress display");
+		goto out;
+	}
+
+	OCFS2_SET_COMPAT_FEATURE(super, OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2);
+	super->s_cluster_info.ci_stackflags = 0;
+
+	tunefs_block_signals();
+	err = ocfs2_write_super(fs);
+	if (err)
+		tcom_err(err, "while writing out the superblock");
+	tunefs_unblock_signals();
+
+	tools_progress_step(prog, 1);
+	tools_progress_stop(prog);
+
+out:
+	return err;
+}
+
+static int disable_clusterinfo_v2(ocfs2_filesys *fs, int flags)
+{
+	errcode_t err = 0;
+	struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super);
+	struct tools_progress *prog;
+
+	if (!ocfs2_clusterinfo_v2(super)) {
+		verbosef(VL_APP,
+			 "Clusterinfo v2 feature is not enabled; "
+			 "nothing to disable\n");
+		goto out;
+	}
+
+	if (!tools_interact("Disable the clusterinfo v2 feature on "
+			    "device \"%s\"? ",
+			    fs->fs_devname))
+		goto out;
+
+	prog = tools_progress_start("Disable clusterinfo-v2",
+				    "noclusterinfo-v2", 1);
+	if (!prog) {
+		err = TUNEFS_ET_NO_MEMORY;
+		tcom_err(err, "while initializing the progress display");
+		goto out;
+	}
+
+	OCFS2_CLEAR_COMPAT_FEATURE(super, OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2);
+	super->s_cluster_info.ci_stackflags = 0;
+
+	tunefs_block_signals();
+	err = ocfs2_write_super(fs);
+	if (err)
+		tcom_err(err, "while writing out the superblock");
+	tunefs_unblock_signals();
+
+	tools_progress_step(prog, 1);
+	tools_progress_stop(prog);
+
+out:
+	return err;
+}
+
+DEFINE_TUNEFS_FEATURE_COMPAT(clusterinfo_v2,
+			     OCFS2_FEATURE_COMPAT_CLUSTERINFO_V2,
+			     TUNEFS_FLAG_RW,
+			     enable_clusterinfo_v2,
+			     disable_clusterinfo_v2);
+
+#ifdef DEBUG_EXE
+int main(int argc, char *argv[])
+{
+	return tunefs_feature_main(argc, argv, &clusterinfo_v2_feature);
+}
+#endif
diff --git a/tunefs.ocfs2/op_features.c b/tunefs.ocfs2/op_features.c
index 613ea7e..bd41b73 100644
--- a/tunefs.ocfs2/op_features.c
+++ b/tunefs.ocfs2/op_features.c
@@ -45,6 +45,7 @@ extern struct tunefs_feature usrquota_feature;
 extern struct tunefs_feature grpquota_feature;
 extern struct tunefs_feature refcount_feature;
 extern struct tunefs_feature indexed_dirs_feature;
+extern struct tunefs_feature clusterinfo_v2_feature;
 
 /* List of features supported by ocfs2ne */
 static struct tunefs_feature *features[] = {
@@ -60,6 +61,7 @@ static struct tunefs_feature *features[] = {
 	&grpquota_feature,
 	&refcount_feature,
 	&indexed_dirs_feature,
+	&clusterinfo_v2_feature,
 	NULL,
 };
 
-- 
1.7.0.4




More information about the Ocfs2-tools-devel mailing list