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

Joel Becker joel.becker at oracle.com
Tue Sep 9 17:57:16 PDT 2008


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

With block64 enabled journals, the filesystem can be created larger than
2^32 blocks.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 mkfs.ocfs2/mkfs.c          |   49 ++++++++++++++++++++++++++++++++++++-------
 mkfs.ocfs2/mkfs.h          |    1 +
 mkfs.ocfs2/mkfs.ocfs2.8.in |   18 ++++++++++++++++
 3 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
index 2cded13..ad1da36 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++;
 	}
@@ -1824,13 +1848,21 @@ check_32bit_blocks(State *s)
 {
 	uint64_t max = UINT32_MAX;
        
+	if (s->journal64)
+		return;
+
 	if (s->volume_size_in_blocks <= max)
 		return;
 
 	fprintf(stderr, "ERROR: jbd can only store block numbers in 32 bits. "
-		"%s can hold %"PRIu64" blocks which overflows this limit. "
-		"Consider increasing the block size or decreasing the device "
-		"size.\n", s->device_name, s->volume_size_in_blocks);
+		"%s can hold %"PRIu64" blocks which overflows this limit. If "
+		"you have a new enough Ocfs2 with JBD2 support, you can try "
+		"formatting with the \"-Jblock64\" option to turn on support "
+		"for this size block device.\n"
+		"Otherwise, consider increasing the block size or "
+		"decreasing the device size.\n",
+		s->device_name, s->volume_size_in_blocks);
+
 	exit(1);
 }
 
@@ -2378,7 +2410,8 @@ static void format_journals(State *s)
 	ocfs2_filesys *fs = NULL;
 	char jrnl_file[40];
 	ocfs2_fs_options features = {
-		.opt_incompat = 0,
+		.opt_incompat =
+			s->journal64 ? JBD2_FEATURE_INCOMPAT_64BIT : 0,
 	};
 
 	ret = ocfs2_open(s->device_name, OCFS2_FLAG_RW, 0, 0, &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;
diff --git a/mkfs.ocfs2/mkfs.ocfs2.8.in b/mkfs.ocfs2/mkfs.ocfs2.8.in
index 6b553f8..de43946 100644
--- a/mkfs.ocfs2/mkfs.ocfs2.8.in
+++ b/mkfs.ocfs2/mkfs.ocfs2.8.in
@@ -47,6 +47,24 @@ options are comma separated, and may take an argument using the equals
 Create a journal of size \fIjournal\-size\fR. Minimum size is 4M.
 If omitted, a value is heuristically determined by the file system size.
 .RE
+.RS 1.2i
+.TP
+\fBblock32\fR
+Use a standard 32bit journal.  The journal will be able to access up to
+2^32-1 blocks.  This is the default.  It has been the journal format for
+\fIOCFS2\fR volumes since the beginning.  The journal is compatible with
+all versions of \fIOCFS2\fR.  Prepending \fBno\fR is equivalent to the
+\fBblock64\fR journal option.
+.RE
+.RS 1.2i
+.TP
+\fBblock64\fR
+Use a 64bit journal.  The journal will be able to access up to 2^64-1
+blocks.  This allows large filesystems that can extend to the
+theoretical limits of \fIOCFS2\fR.  It requires a new-enough filesystem
+driver based on JBD2.  Prepending \fBno\fR is equivalent to the
+\fBblock32\fR journal option.
+.RE
 
 .TP
 \fB\-L, \-\-label\fR \fIvolume\-label\fR
-- 
1.5.6.3




More information about the Ocfs2-tools-devel mailing list