[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