[Ocfs2-tools-devel] [PATCH 3/3] mkfs.ocfs2: Add 64bit journal support.

Joel Becker joel.becker at oracle.com
Fri Sep 5 23:36:42 PDT 2008


The [no]block32 and [no]block64 journal options are added to mkfs -J.
noblock32 and block64 will create 64bit-capable journals.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 include/ocfs2/ocfs2.h |    4 ++
 libocfs2/mkjournal.c  |   55 +++++++++++++++++++++++++++++++
 mkfs.ocfs2/mkfs.c     |   87 ++++++++++++++++++++++++++++++++++++++++++++++--
 mkfs.ocfs2/mkfs.h     |    1 +
 4 files changed, 143 insertions(+), 4 deletions(-)

diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index bdeadb9..8a7e865 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -289,6 +289,10 @@ errcode_t ocfs2_write_journal_superblock(ocfs2_filesys *fs, uint64_t blkno,
 					 char *jsb_buf);
 errcode_t ocfs2_make_journal(ocfs2_filesys *fs, uint64_t blkno,
 			     uint32_t clusters);
+errcode_t ocfs2_journal_clear_features(journal_superblock_t *jsb,
+				       ocfs2_fs_options *features);
+errcode_t ocfs2_journal_set_features(journal_superblock_t *jsb,
+				     ocfs2_fs_options *features);
 extern size_t ocfs2_journal_tag_bytes(journal_superblock_t *jsb);
 extern uint64_t ocfs2_journal_tag_block(journal_block_tag_t *tag,
 					size_t tag_bytes);
diff --git a/libocfs2/mkjournal.c b/libocfs2/mkjournal.c
index c0a7c29..bdaf1ed 100644
--- a/libocfs2/mkjournal.c
+++ b/libocfs2/mkjournal.c
@@ -50,6 +50,61 @@ uint64_t ocfs2_journal_tag_block(journal_block_tag_t *tag, size_t tag_bytes)
 	return blockno;
 }
 
+/* Returns true if we support these journal features */
+static int ocfs2_journal_check_available_features(journal_superblock_t *jsb,
+						  ocfs2_fs_options *features)
+{
+	if (!features->opt_compat && !features->opt_ro_compat &&
+	    !features->opt_incompat)
+		return 1;
+
+	if (jsb->s_header.h_blocktype != JBD2_SUPERBLOCK_V2)
+		return 0;
+
+	if ((features->opt_compat & JBD2_KNOWN_COMPAT_FEATURES) !=
+	    features->opt_compat)
+		return 0;
+
+	if ((features->opt_ro_compat & JBD2_KNOWN_ROCOMPAT_FEATURES) !=
+	    features->opt_ro_compat)
+		return 0;
+
+	if ((features->opt_incompat & JBD2_KNOWN_INCOMPAT_FEATURES) !=
+	    features->opt_incompat)
+		return 0;
+
+	return 1;
+}
+
+errcode_t ocfs2_journal_set_features(journal_superblock_t *jsb,
+				     ocfs2_fs_options *features)
+{
+
+	if (!ocfs2_journal_check_available_features(jsb, features))
+		return OCFS2_ET_UNSUPP_FEATURE;
+
+
+	jsb->s_feature_compat |= features->opt_compat;
+	jsb->s_feature_ro_compat |= features->opt_ro_compat;
+	jsb->s_feature_incompat |= features->opt_incompat;
+
+	return 0;
+}
+
+errcode_t ocfs2_journal_clear_features(journal_superblock_t *jsb,
+				       ocfs2_fs_options *features)
+{
+
+	if (!ocfs2_journal_check_available_features(jsb, features))
+		return OCFS2_ET_UNSUPP_FEATURE;
+
+	jsb->s_feature_compat &= ~(features->opt_compat);
+	jsb->s_feature_ro_compat &= ~(features->opt_ro_compat);
+	jsb->s_feature_incompat &= ~(features->opt_incompat);
+
+	return 0;
+}
+
 void ocfs2_swap_journal_superblock(journal_superblock_t *jsb)
 {
 	if (cpu_is_big_endian)
diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
index 06d4f6f..dfc9323 100644
--- a/mkfs.ocfs2/mkfs.c
+++ b/mkfs.ocfs2/mkfs.c
@@ -28,7 +28,8 @@
 static State *get_state(int argc, char **argv);
 static int get_number(char *arg, uint64_t *res);
 static void parse_journal_opts(char *progname, const char *opts,
-			       uint64_t *journal_size_in_bytes);
+			       uint64_t *journal_size_in_bytes,
+			       int *journal64);
 static void usage(const char *progname);
 static void version(const char *progname);
 static void fill_defaults(State *s);
@@ -545,6 +546,7 @@ get_state(int argc, char **argv)
 	int ret;
 	uint64_t val;
 	uint64_t journal_size_in_bytes = 0;
+	int journal64 = 0;
 	enum ocfs2_fs_types fs_type = FS_DEFAULT;
 	int mount = -1;
 	int no_backup_super = -1;
@@ -667,7 +669,8 @@ get_state(int argc, char **argv)
 
 		case 'J':
 			parse_journal_opts(progname, optarg,
-					   &journal_size_in_bytes);
+					   &journal_size_in_bytes,
+					   &journal64);
 			break;
 
 		case 'H':
@@ -811,6 +814,7 @@ get_state(int argc, char **argv)
 	s->format_time   = time(NULL);
 
 	s->journal_size_in_bytes = journal_size_in_bytes;
+	s->journal64 = journal64;
 
 	s->hb_dev = hb_dev;
 
@@ -909,23 +913,31 @@ get_number(char *arg, uint64_t *res)
 /* derived from e2fsprogs */
 static void
 parse_journal_opts(char *progname, const char *opts,
-		   uint64_t *journal_size_in_bytes)
+		   uint64_t *journal_size_in_bytes, int *journal64)
 {
 	char *options, *token, *next, *p, *arg;
 	int ret, journal_usage = 0;
 	uint64_t val;
+	int invert;
 
 	options = strdup(opts);
 
 	for (token = options; token && *token; token = next) {
 		p = strchr(token, ',');
 		next = NULL;
+		invert = 0;
 
 		if (p) {
 			*p = '\0';
 			next = p + 1;
 		}
 
+		arg = strstr(token, "no");
+		if (arg == token) {
+			invert = 1;
+			token += strlen("no");
+		}
+
 		arg = strchr(token, '=');
 
 		if (arg) {
@@ -934,7 +946,7 @@ parse_journal_opts(char *progname, const char *opts,
 		}
 
 		if (strcmp(token, "size") == 0) {
-			if (!arg) {
+			if (!arg || invert) {
 				journal_usage++;
 				continue;
 			}
@@ -951,6 +963,18 @@ parse_journal_opts(char *progname, const char *opts,
 			}
 
 			*journal_size_in_bytes = val;
+		} else if (strcmp(token, "block32") == 0) {
+			if (arg) {
+				journal_usage++;
+				continue;
+			}
+			*journal64 = invert;
+		} else if (strcmp(token, "block64") == 0) {
+			if (arg) {
+				journal_usage++;
+				continue;
+			}
+			*journal64 = !invert;
 		} else
 			journal_usage++;
 	}
@@ -2369,6 +2393,50 @@ bail:
 	exit(1);
 }
 
+static errcode_t set_journal64(ocfs2_filesys *fs, uint64_t blkno)
+{
+	char *buf;
+	errcode_t ret;
+	uint64_t offset;
+	journal_superblock_t *jsb;
+	ocfs2_cached_inode *ci;
+	ocfs2_fs_options features = {
+		.opt_incompat = JBD2_FEATURE_INCOMPAT_64BIT,
+	};
+
+	ret = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (ret)
+		return ret;
+
+	ret = ocfs2_read_cached_inode(fs, blkno, &ci);
+	if (ret)
+		goto out_buf;
+
+	/* re-use offset here for 1st journal block. */
+	ret = ocfs2_extent_map_get_blocks(ci, 0, 1, &offset, NULL, NULL);
+	if (ret)
+		goto out_inode;
+
+	ret = ocfs2_read_journal_superblock(fs, offset, buf);
+	if (ret)
+		goto out_inode;
+
+	jsb = (journal_superblock_t *)buf;
+	ret = ocfs2_journal_set_features(jsb, &features);
+	if (ret)
+		goto out_inode;
+
+	ret = ocfs2_write_journal_superblock(fs, offset, buf);
+
+out_inode:
+	ocfs2_free_cached_inode(fs, ci);
+
+out_buf:
+	ocfs2_free(&buf);
+
+	return ret;
+}
+
 static void format_journals(State *s)
 {
 	errcode_t ret;
@@ -2406,6 +2474,17 @@ static void format_journals(State *s)
 				(int)strlen(jrnl_file), jrnl_file);
 			goto error;
 		}
+
+		if (s->journal64) {
+			ret = set_journal64(fs, blkno);
+			if (ret) {
+				com_err(s->progname, ret,
+					"while setting block64 on "
+					"journal \"%.*s\"",
+					(int)strlen(jrnl_file), jrnl_file);
+				goto error;
+			}
+		}
 	}
 
 	ocfs2_close(fs);
diff --git a/mkfs.ocfs2/mkfs.h b/mkfs.ocfs2/mkfs.h
index b98b705..bd8ac45 100644
--- a/mkfs.ocfs2/mkfs.h
+++ b/mkfs.ocfs2/mkfs.h
@@ -212,6 +212,7 @@ struct _State {
 	unsigned int initial_slots;
 
 	uint64_t journal_size_in_bytes;
+	int journal64;
 
 	char *vol_label;
 	char *device_name;
-- 
1.5.6.3




More information about the Ocfs2-tools-devel mailing list