[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20201120191606.2224881-5-harshadshirwadkar@gmail.com>
Date: Fri, 20 Nov 2020 11:15:55 -0800
From: Harshad Shirwadkar <harshadshirwadkar@...il.com>
To: linux-ext4@...r.kernel.org
Cc: tytso@....edu, Harshad Shirwadkar <harshadshirwadkar@...il.com>
Subject: [PATCH 04/15] mke2fs, dumpe2fs: make fast commit blocks configurable
This patch makes number of fast commit blocks configurable. Also, the
number of fast commit blocks can now be seen in dumpe2fs output.
$ ./misc/mke2fs -O fast_commit -t ext4 image
mke2fs 1.46-WIP (20-Mar-2020)
Discarding device blocks: done
Creating filesystem with 5120 1k blocks and 1280 inodes
Allocating group tables: done
Writing inode tables: done
Creating journal (1040 blocks): done
Writing superblocks and filesystem accounting information: done
$ ./misc/dumpe2fs image
dumpe2fs 1.46-WIP (20-Mar-2020)
...
Journal features: (none)
Total journal size: 1040k
Total journal blocks: 1040
Max transaction length: 1024
Fast commit length: 16
Journal sequence: 0x00000001
Journal start: 0
$ ./misc/mke2fs -O fast_commit -t ext4 image -J fast_commit_size=256,size=1
mke2fs 1.46-WIP (20-Mar-2020)
Creating filesystem with 5120 1k blocks and 1280 inodes
Allocating group tables: done
Writing inode tables: done
Creating journal (1280 blocks): done
Writing superblocks and filesystem accounting information: done
$ ./misc/dumpe2fs image
dumpe2fs 1.46-WIP (20-Mar-2020)
...
Journal features: (none)
Total journal size: 1280k
Total journal blocks: 1280
Max transaction length: 1024
Fast commit length: 256
Journal sequence: 0x00000001
Journal start: 0
Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@...il.com>
---
e2fsck/unix.c | 8 ++--
lib/e2p/e2p.h | 1 +
lib/e2p/ljs.c | 16 +++++--
lib/ext2fs/ext2fs.h | 21 ++++++---
lib/ext2fs/mkjournal.c | 99 +++++++++++++++++++++++++++++-------------
misc/dumpe2fs.c | 10 ++++-
misc/mke2fs.c | 24 +++++++---
misc/tune2fs.c | 8 ++--
misc/util.c | 63 ++++++++++++++++++++-------
misc/util.h | 4 +-
10 files changed, 185 insertions(+), 69 deletions(-)
diff --git a/e2fsck/unix.c b/e2fsck/unix.c
index 1cb51672..3162896a 100644
--- a/e2fsck/unix.c
+++ b/e2fsck/unix.c
@@ -1388,7 +1388,7 @@ int main (int argc, char *argv[])
blk64_t orig_superblock = ~(blk64_t)0;
struct problem_context pctx;
int flags, run_result, was_changed;
- int journal_size;
+ int journal_size, journal_fc_size;
int sysval, sys_page_size = 4096;
int old_bitmaps;
__u32 features[3];
@@ -1912,7 +1912,7 @@ print_unsupp_features:
(ctx->flags & E2F_FLAG_JOURNAL_INODE)) {
if (fix_problem(ctx, PR_6_RECREATE_JOURNAL, &pctx)) {
if (journal_size < 1024)
- journal_size = ext2fs_default_journal_size(ext2fs_blocks_count(fs->super));
+ ext2fs_default_journal_size(&journal_size, &journal_fc_size, fs);
if (journal_size < 0) {
ext2fs_clear_feature_journal(fs->super);
fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
@@ -1923,8 +1923,8 @@ print_unsupp_features:
log_out(ctx, _("Creating journal (%d blocks): "),
journal_size);
fflush(stdout);
- retval = ext2fs_add_journal_inode(fs,
- journal_size, 0);
+ retval = ext2fs_add_journal_inode(fs, journal_size,
+ journal_fc_size, 0);
if (retval) {
log_out(ctx, "%s: while trying to create "
"journal\n", error_message(retval));
diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h
index 90efb624..65702a7e 100644
--- a/lib/e2p/e2p.h
+++ b/lib/e2p/e2p.h
@@ -47,6 +47,7 @@ void print_fs_state (FILE * f, unsigned short state);
int setflags (int fd, unsigned long flags);
int setversion (int fd, unsigned long version);
+#define E2P_LIST_JOURNAL_FLAG_FC 0x1
void e2p_list_journal_super(FILE *f, char *journal_sb_buf,
int exp_block_size, int flags);
diff --git a/lib/e2p/ljs.c b/lib/e2p/ljs.c
index 4ffe9b61..9f866c7e 100644
--- a/lib/e2p/ljs.c
+++ b/lib/e2p/ljs.c
@@ -54,7 +54,12 @@ void e2p_list_journal_super(FILE *f, char *journal_sb_buf,
unsigned int size;
int j, printed = 0;
unsigned int i, nr_users;
+ int num_fc_blks = 0;
+ int journal_blks = 0;
+ if (flags & E2P_LIST_JOURNAL_FLAG_FC)
+ num_fc_blks = jbd2_journal_get_num_fc_blks((journal_superblock_t *)journal_sb_buf);
+ journal_blks = ntohl(jsb->s_maxlen) - num_fc_blks;
fprintf(f, "%s", "Journal features: ");
for (i=0, mask_ptr=&jsb->s_feature_compat; i <3; i++,mask_ptr++) {
mask = e2p_be32(*mask_ptr);
@@ -68,7 +73,7 @@ void e2p_list_journal_super(FILE *f, char *journal_sb_buf,
if (printed == 0)
fprintf(f, " (none)");
fputc('\n', f);
- fputs("Journal size: ", f);
+ fputs("Total journal size: ", f);
size = (ntohl(jsb->s_blocksize) / 1024) * ntohl(jsb->s_maxlen);
if (size < 8192)
fprintf(f, "%uk\n", size);
@@ -78,8 +83,13 @@ void e2p_list_journal_super(FILE *f, char *journal_sb_buf,
if (exp_block_size != (int) ntohl(jsb->s_blocksize))
fprintf(f, "Journal block size: %u\n",
(unsigned int)ntohl(jsb->s_blocksize));
- fprintf(f, "Journal length: %u\n",
- (unsigned int)ntohl(jsb->s_maxlen));
+ fprintf(f, "Total journal blocks: %u\n",
+ (unsigned int)(journal_blks + num_fc_blks));
+ fprintf(f, "Max transaction length: %u\n",
+ (unsigned int)journal_blks);
+ fprintf(f, "Fast commit length: %u\n",
+ (unsigned int)num_fc_blks);
+
if (ntohl(jsb->s_first) != 1)
fprintf(f, "Journal first block: %u\n",
(unsigned int)ntohl(jsb->s_first));
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index a8a6e091..01132245 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -220,6 +220,12 @@ typedef struct ext2_file *ext2_file_t;
#define EXT2_MKJOURNAL_LAZYINIT 0x0000002 /* don't zero journal inode before use*/
#define EXT2_MKJOURNAL_NO_MNT_CHECK 0x0000004 /* don't check mount status */
+/*
+ * Normal journal area size to fast commit area size ratio. This is used to
+ * set default size of fast commit area.
+ */
+#define EXT2_JOURNAL_TO_FC_BLKS_RATIO 64
+
struct blk_alloc_ctx;
struct opaque_ext2_group_desc;
@@ -1625,15 +1631,18 @@ extern errcode_t ext2fs_zero_blocks(ext2_filsys fs, blk_t blk, int num,
extern errcode_t ext2fs_zero_blocks2(ext2_filsys fs, blk64_t blk, int num,
blk64_t *ret_blk, int *ret_count);
extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
- __u32 num_blocks, int flags,
- char **ret_jsb);
+ __u32 num_blocks, __u32 num_fc_blks,
+ int flags, char **ret_jsb);
+extern errcode_t ext2fs_split_journal_size(ext2_filsys fs, blk_t *journal_blks,
+ blk_t *fc_blks, blk_t total_blks);
extern errcode_t ext2fs_add_journal_device(ext2_filsys fs,
ext2_filsys journal_dev);
extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks,
- int flags);
+ blk_t num_fc_blocks, int flags);
extern errcode_t ext2fs_add_journal_inode2(ext2_filsys fs, blk_t num_blocks,
- blk64_t goal, int flags);
-extern int ext2fs_default_journal_size(__u64 num_blocks);
+ blk_t num_fc_blocks,
+ blk64_t goal, int flags);
+extern errcode_t ext2fs_default_journal_size(int *journal_size, int *fc_size, ext2_filsys fs);
extern int ext2fs_journal_sb_start(int blocksize);
/* openfs.c */
@@ -2122,6 +2131,8 @@ static inline unsigned int ext2_dir_htree_level(ext2_filsys fs)
return EXT4_HTREE_LEVEL_COMPAT;
}
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/ext2fs/mkjournal.c b/lib/ext2fs/mkjournal.c
index f47f71e6..74d0c7fc 100644
--- a/lib/ext2fs/mkjournal.c
+++ b/lib/ext2fs/mkjournal.c
@@ -12,6 +12,7 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
+#include <assert.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -39,13 +40,32 @@
#include "kernel-jbd.h"
+errcode_t ext2fs_split_journal_size(ext2_filsys fs, blk_t *journal_blks,
+ blk_t *fc_blks, blk_t total_blks)
+{
+ if (total_blks < JBD2_MIN_JOURNAL_BLOCKS)
+ return EXT2_ET_JOURNAL_TOO_SMALL;
+
+ if (!ext2fs_has_feature_fast_commit(fs->super)) {
+ *journal_blks = total_blks;
+ *fc_blks = 0;
+ return 0;
+ }
+ *journal_blks = ext2fs_blocks_count(fs->super) *
+ EXT2_JOURNAL_TO_FC_BLKS_RATIO /
+ (EXT2_JOURNAL_TO_FC_BLKS_RATIO + 1);
+ *journal_blks = max(JBD2_MIN_JOURNAL_BLOCKS, *journal_blks);
+ *fc_blks = total_blks - *journal_blks;
+ return 0;
+}
+
/*
* This function automatically sets up the journal superblock and
* returns it as an allocated block.
*/
errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
- __u32 num_blocks, int flags,
- char **ret_jsb)
+ __u32 num_blocks, __u32 num_fc_blks,
+ int flags, char **ret_jsb)
{
errcode_t retval;
journal_superblock_t *jsb;
@@ -64,10 +84,11 @@ errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
else
jsb->s_header.h_blocktype = htonl(JBD2_SUPERBLOCK_V2);
jsb->s_blocksize = htonl(fs->blocksize);
- jsb->s_maxlen = htonl(num_blocks);
+ jsb->s_maxlen = htonl(num_blocks + num_fc_blks);
jsb->s_nr_users = htonl(1);
jsb->s_first = htonl(1);
jsb->s_sequence = htonl(1);
+ jsb->s_num_fc_blks = htonl(num_fc_blks);
memcpy(jsb->s_uuid, fs->super->s_uuid, sizeof(fs->super->s_uuid));
/*
* If we're creating an external journal device, we need to
@@ -88,14 +109,16 @@ errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
* filesystems.
*/
static errcode_t write_journal_file(ext2_filsys fs, char *filename,
- blk_t num_blocks, int flags)
+ blk_t num_blocks, blk_t num_fc_blocks,
+ int flags)
{
errcode_t retval;
char *buf = 0;
int fd, ret_size;
blk_t i;
- if ((retval = ext2fs_create_journal_superblock(fs, num_blocks, flags,
+ if ((retval = ext2fs_create_journal_superblock(fs, num_blocks,
+ num_fc_blocks, flags,
&buf)))
return retval;
@@ -119,7 +142,7 @@ static errcode_t write_journal_file(ext2_filsys fs, char *filename,
if (flags & EXT2_MKJOURNAL_LAZYINIT)
goto success;
- for (i = 1; i < num_blocks; i++) {
+ for (i = 1; i < num_blocks + num_fc_blocks; i++) {
ret_size = write(fd, buf, fs->blocksize);
if (ret_size < 0) {
retval = errno;
@@ -262,7 +285,8 @@ static blk64_t get_midpoint_journal_block(ext2_filsys fs)
* This function creates a journal using direct I/O routines.
*/
static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
- blk_t num_blocks, blk64_t goal, int flags)
+ blk_t num_blocks, blk_t num_fc_blocks,
+ blk64_t goal, int flags)
{
char *buf;
errcode_t retval;
@@ -271,7 +295,8 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
int falloc_flags = EXT2_FALLOCATE_FORCE_INIT;
blk64_t zblk;
- if ((retval = ext2fs_create_journal_superblock(fs, num_blocks, flags,
+ if ((retval = ext2fs_create_journal_superblock(fs, num_blocks,
+ num_fc_blocks, flags,
&buf)))
return retval;
@@ -295,7 +320,8 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
if (!(flags & EXT2_MKJOURNAL_LAZYINIT))
falloc_flags |= EXT2_FALLOCATE_ZERO_BLOCKS;
- inode_size = (unsigned long long)fs->blocksize * num_blocks;
+ inode_size = (unsigned long long)fs->blocksize *
+ (num_blocks + num_fc_blocks);
inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
inode.i_links_count = 1;
inode.i_mode = LINUX_S_IFREG | 0600;
@@ -304,7 +330,7 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
goto out2;
retval = ext2fs_fallocate(fs, falloc_flags, journal_ino,
- &inode, goal, 0, num_blocks);
+ &inode, goal, 0, num_blocks + num_fc_blocks);
if (retval)
goto out2;
@@ -337,25 +363,34 @@ out2:
*
* n.b. comments assume 4k blocks
*/
-int ext2fs_default_journal_size(__u64 num_blocks)
+errcode_t ext2fs_default_journal_size(int *journal_size, int *fc_size, ext2_filsys fs)
{
+ __u64 num_blocks = ext2fs_blocks_count(fs->super);
+
if (num_blocks < 2048)
- return -1;
+ return EXT2_ET_TOOSMALL;
if (num_blocks < 32768) /* 128 MB */
- return (1024); /* 4 MB */
- if (num_blocks < 256*1024) /* 1 GB */
- return (4096); /* 16 MB */
- if (num_blocks < 512*1024) /* 2 GB */
- return (8192); /* 32 MB */
- if (num_blocks < 4096*1024) /* 16 GB */
- return (16384); /* 64 MB */
- if (num_blocks < 8192*1024) /* 32 GB */
- return (32768); /* 128 MB */
- if (num_blocks < 16384*1024) /* 64 GB */
- return (65536); /* 256 MB */
- if (num_blocks < 32768*1024) /* 128 GB */
- return (131072); /* 512 MB */
- return 262144; /* 1 GB */
+ *journal_size = 1024; /* 4 MB */
+ else if (num_blocks < 256*1024) /* 1 GB */
+ *journal_size = 4096; /* 16 MB */
+ else if (num_blocks < 512*1024) /* 2 GB */
+ *journal_size = 8192; /* 32 MB */
+ else if (num_blocks < 4096*1024) /* 16 GB */
+ *journal_size = 16384; /* 64 MB */
+ else if (num_blocks < 8192*1024) /* 32 GB */
+ *journal_size = 32768; /* 128 MB */
+ else if (num_blocks < 16384*1024) /* 64 GB */
+ *journal_size = 65536; /* 256 MB */
+ else if (num_blocks < 32768*1024) /* 128 GB */
+ *journal_size = 131072; /* 512 MB */
+ else
+ *journal_size = 262144; /* 1 GB */
+
+ *fc_size = ext2fs_has_feature_fast_commit(fs->super) ?
+ *journal_size / EXT2_JOURNAL_TO_FC_BLKS_RATIO : 0;
+ assert(*journal_size + *fc_size < num_blocks);
+
+ return 0;
}
int ext2fs_journal_sb_start(int blocksize)
@@ -435,6 +470,7 @@ errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev)
* functions if it is not.
*/
errcode_t ext2fs_add_journal_inode2(ext2_filsys fs, blk_t num_blocks,
+ blk_t num_fc_blocks,
blk64_t goal, int flags)
{
errcode_t retval;
@@ -486,7 +522,8 @@ errcode_t ext2fs_add_journal_inode2(ext2_filsys fs, blk_t num_blocks,
* filesystems is extremely rare these days... Ignore it. */
flags &= ~EXT2_MKJOURNAL_LAZYINIT;
- if ((retval = write_journal_file(fs, jfile, num_blocks, flags)))
+ if ((retval = write_journal_file(fs, jfile,
+ num_blocks, num_fc_blocks, flags)))
goto errout;
/* Get inode number of the journal file */
@@ -528,7 +565,8 @@ errcode_t ext2fs_add_journal_inode2(ext2_filsys fs, blk_t num_blocks,
}
journal_ino = EXT2_JOURNAL_INO;
if ((retval = write_journal_inode(fs, journal_ino,
- num_blocks, goal, flags)))
+ num_blocks, num_fc_blocks,
+ goal, flags)))
return retval;
}
@@ -546,9 +584,10 @@ errout:
return retval;
}
-errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks, int flags)
+errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks,
+ blk_t num_fc_blocks, int flags)
{
- return ext2fs_add_journal_inode2(fs, num_blocks, ~0ULL, flags);
+ return ext2fs_add_journal_inode2(fs, num_blocks, num_fc_blocks, ~0ULL, flags);
}
diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c
index d295ba4d..e24dc4e6 100644
--- a/misc/dumpe2fs.c
+++ b/misc/dumpe2fs.c
@@ -364,6 +364,7 @@ static void print_inline_journal_information(ext2_filsys fs)
errcode_t retval;
ext2_ino_t ino = fs->super->s_journal_inum;
char buf[1024];
+ int flags;
if (fs->flags & EXT2_FLAG_IMAGE_FILE)
return;
@@ -392,7 +393,9 @@ static void print_inline_journal_information(ext2_filsys fs)
_("Journal superblock magic number invalid!\n"));
exit(1);
}
- e2p_list_journal_super(stdout, buf, fs->blocksize, 0);
+ flags = ext2fs_has_feature_fast_commit(fs->super) ?
+ E2P_LIST_JOURNAL_FLAG_FC : 0;
+ e2p_list_journal_super(stdout, buf, fs->blocksize, flags);
}
static void print_journal_information(ext2_filsys fs)
@@ -400,6 +403,7 @@ static void print_journal_information(ext2_filsys fs)
errcode_t retval;
char buf[1024];
journal_superblock_t *jsb;
+ int flags;
/* Get the journal superblock */
if ((retval = io_channel_read_blk64(fs->io,
@@ -417,7 +421,9 @@ static void print_journal_information(ext2_filsys fs)
_("Couldn't find journal superblock magic numbers"));
exit(1);
}
- e2p_list_journal_super(stdout, buf, fs->blocksize, 0);
+ flags = ext2fs_has_feature_fast_commit(fs->super) ?
+ E2P_LIST_JOURNAL_FLAG_FC : 0;
+ e2p_list_journal_super(stdout, buf, fs->blocksize, flags);
}
static int check_mmp(ext2_filsys fs)
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 8c8f5ea4..2d9a5449 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -93,6 +93,7 @@ static uid_t root_uid;
static gid_t root_gid;
int journal_size;
int journal_flags;
+int journal_fc_size;
static int lazy_itable_init;
static int packed_meta_blocks;
int no_copy_xattrs;
@@ -604,9 +605,18 @@ static void create_journal_dev(ext2_filsys fs)
char *buf;
blk64_t blk, err_blk;
int c, count, err_count;
+ int num_journal_blks = 0, num_fc_blks = 0;
+
+ retval = ext2fs_split_journal_size(fs, &num_journal_blks, &num_fc_blks,
+ ext2fs_blocks_count(fs->super));
+ if (retval) {
+ com_err("create_journal_dev", retval, "%s",
+ _("while splitting the journal size"));
+ exit(1);
+ }
retval = ext2fs_create_journal_superblock(fs,
- ext2fs_blocks_count(fs->super), 0, &buf);
+ num_journal_blks, num_fc_blks, 0, &buf);
if (retval) {
com_err("create_journal_dev", retval, "%s",
_("while initializing journal superblock"));
@@ -1753,6 +1763,8 @@ profile_error:
case 'j':
if (!journal_size)
journal_size = -1;
+ if (!journal_fc_size)
+ journal_fc_size = -1;
break;
case 'J':
parse_journal_opts(optarg);
@@ -2937,7 +2949,7 @@ int main (int argc, char *argv[])
badblocks_list bb_list = 0;
badblocks_iterate bb_iter;
blk_t blk;
- unsigned int journal_blocks = 0;
+ blk_t journal_blocks = 0, journal_fc_blocks = 0;
unsigned int i, checkinterval;
int max_mnt_count;
int val, hash_alg;
@@ -3047,7 +3059,8 @@ int main (int argc, char *argv[])
/* Calculate journal blocks */
if (!journal_device && ((journal_size) ||
ext2fs_has_feature_journal(&fs_param)))
- journal_blocks = figure_journal_size(journal_size, fs);
+ figure_journal_size(&journal_blocks, &journal_fc_blocks,
+ journal_size, journal_fc_size, fs);
sprintf(opt_string, "tdb_data_size=%d", fs->blocksize <= 4096 ?
32768 : fs->blocksize * 8);
@@ -3382,7 +3395,7 @@ int main (int argc, char *argv[])
free(journal_device);
} else if ((journal_size) ||
ext2fs_has_feature_journal(&fs_param)) {
- overhead += EXT2FS_NUM_B2C(fs, journal_blocks);
+ overhead += EXT2FS_NUM_B2C(fs, journal_blocks + journal_fc_blocks);
if (super_only) {
printf("%s", _("Skipping journal creation in super-only mode\n"));
fs->super->s_journal_inum = EXT2_JOURNAL_INO;
@@ -3395,10 +3408,11 @@ int main (int argc, char *argv[])
}
if (!quiet) {
printf(_("Creating journal (%u blocks): "),
- journal_blocks);
+ journal_blocks + journal_fc_blocks);
fflush(stdout);
}
retval = ext2fs_add_journal_inode2(fs, journal_blocks,
+ journal_fc_blocks,
journal_location,
journal_flags);
if (retval) {
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
index 670ed9e0..daee154d 100644
--- a/misc/tune2fs.c
+++ b/misc/tune2fs.c
@@ -102,7 +102,7 @@ static int feature_64bit;
static int fsck_requested;
static char *undo_file;
-int journal_size, journal_flags;
+int journal_size, journal_fc_size, journal_flags;
char *journal_device;
static blk64_t journal_location = ~0LL;
@@ -1543,7 +1543,7 @@ mmp_error:
*/
static int add_journal(ext2_filsys fs)
{
- unsigned long journal_blocks;
+ blk_t journal_blocks, journal_fc_blocks;
errcode_t retval;
ext2_filsys jfs;
io_manager io_ptr;
@@ -1589,13 +1589,15 @@ static int add_journal(ext2_filsys fs)
} else if (journal_size) {
fputs(_("Creating journal inode: "), stdout);
fflush(stdout);
- journal_blocks = figure_journal_size(journal_size, fs);
+ figure_journal_size(&journal_blocks, &journal_fc_blocks,
+ journal_size, journal_fc_size, fs);
if (journal_location_string)
journal_location =
parse_num_blocks2(journal_location_string,
fs->super->s_log_block_size);
retval = ext2fs_add_journal_inode2(fs, journal_blocks,
+ journal_fc_blocks,
journal_location,
journal_flags);
if (retval) {
diff --git a/misc/util.c b/misc/util.c
index dcd2f0a7..85f10a70 100644
--- a/misc/util.c
+++ b/misc/util.c
@@ -200,6 +200,14 @@ void parse_journal_opts(const char *opts)
journal_size = strtoul(arg, &p, 0);
if (*p)
journal_usage++;
+ } else if (strcmp(token, "fast_commit_size") == 0) {
+ if (!arg) {
+ journal_usage++;
+ continue;
+ }
+ journal_fc_size = strtoul(arg, &p, 0);
+ if (*p)
+ journal_usage++;
} else if (!strcmp(token, "location")) {
if (!arg) {
journal_usage++;
@@ -229,42 +237,65 @@ void parse_journal_opts(const char *opts)
free(buf);
}
+static inline int jsize_to_blks(ext2_filsys fs, int size)
+{
+ return (size * 1024) / (fs->blocksize / 1024);
+}
+
+/* Fast commit size is in KBs */
+static inline int fcsize_to_blks(ext2_filsys fs, int size)
+{
+ return (size * 1024) / (fs->blocksize);
+}
+
/*
* Determine the number of journal blocks to use, either via
* user-specified # of megabytes, or via some intelligently selected
* defaults.
*
- * Find a reasonable journal file size (in blocks) given the number of blocks
- * in the filesystem. For very small filesystems, it is not reasonable to
- * have a journal that fills more than half of the filesystem.
+ * Find a reasonable journal file size (in blocks) given the number of blocks in
+ * the filesystem. For very small filesystems, it is not reasonable to have a
+ * journal that fills more than half of the filesystem.
*/
-unsigned int figure_journal_size(int size, ext2_filsys fs)
+void figure_journal_size(blk_t *j_blocks, blk_t *fc_blocks,
+ int requested_j_size, int requested_fc_size, ext2_filsys fs)
{
- int j_blocks;
+ int def_j_blocks, def_fc_blocks, total_blocks;
+ int ret;
- j_blocks = ext2fs_default_journal_size(ext2fs_blocks_count(fs->super));
- if (j_blocks < 0) {
+ ret = ext2fs_default_journal_size(&def_j_blocks, &def_fc_blocks, fs);
+ if (ret) {
fputs(_("\nFilesystem too small for a journal\n"), stderr);
- return 0;
+ return;
}
- if (size > 0) {
- j_blocks = size * 1024 / (fs->blocksize / 1024);
- if (j_blocks < 1024 || j_blocks > 10240000) {
- fprintf(stderr, _("\nThe requested journal "
+ *j_blocks = def_j_blocks;
+ *fc_blocks = def_fc_blocks;
+
+ if (requested_j_size > 0 ||
+ (ext2fs_has_feature_fast_commit(fs->super) && requested_fc_size > 0)) {
+ *j_blocks = requested_j_size > 0 ?
+ jsize_to_blks(fs, requested_j_size) : def_j_blocks;
+
+ *fc_blocks = 0;
+ if (ext2fs_has_feature_fast_commit(fs->super))
+ *fc_blocks = requested_fc_size > 0 ?
+ fcsize_to_blks(fs, requested_fc_size) : def_fc_blocks;
+ total_blocks = *j_blocks + *fc_blocks;
+ if (total_blocks < 1024 || total_blocks > 10240000) {
+ fprintf(stderr, _("\nThe total requested journal "
"size is %d blocks; it must be\n"
"between 1024 and 10240000 blocks. "
"Aborting.\n"),
- j_blocks);
+ total_blocks);
exit(1);
}
- if ((unsigned) j_blocks > ext2fs_free_blocks_count(fs->super) / 2) {
- fputs(_("\nJournal size too big for filesystem.\n"),
+ if ((unsigned int) total_blocks > ext2fs_free_blocks_count(fs->super) / 2) {
+ fputs(_("\nTotal journal size too big for filesystem.\n"),
stderr);
exit(1);
}
}
- return j_blocks;
}
void print_check_message(int mnt, unsigned int check)
diff --git a/misc/util.h b/misc/util.h
index 49b4b9c1..cee812b4 100644
--- a/misc/util.h
+++ b/misc/util.h
@@ -11,6 +11,7 @@
*/
extern int journal_size;
+extern int journal_fc_size;
extern int journal_flags;
extern char *journal_device;
extern char *journal_location_string;
@@ -22,6 +23,7 @@ extern char *get_progname(char *argv_zero);
extern void proceed_question(int delay);
extern void parse_journal_opts(const char *opts);
extern void check_mount(const char *device, int force, const char *type);
-extern unsigned int figure_journal_size(int size, ext2_filsys fs);
+extern void figure_journal_size(blk_t *j_blocks, blk_t *fc_blocks,
+ int requested_j_size, int requested_fc_size, ext2_filsys fs);
extern void print_check_message(int, unsigned int);
extern void dump_mmp_msg(struct mmp_struct *mmp, const char *msg);
--
2.29.2.454.gaff20da3a2-goog
Powered by blists - more mailing lists