diff options
author | Jan Kara | 2019-11-05 17:44:09 +0100 |
---|---|---|
committer | Theodore Ts'o | 2019-11-05 12:13:25 -0500 |
commit | b90bfdf581194a0fa5f6c26fef1e522f15f6212e (patch) | |
tree | 049cad17c0b0b24520d734501ad6a1c4a2b05935 | |
parent | 0db45889453644bb5d3e3c6044f4d81b910d41ef (diff) |
jbd2: Completely fill journal descriptor blocks
With 32-bit block numbers, we don't allocate the array for journal
buffer heads large enough for corresponding descriptor tags to fill the
descriptor block. Thus we end up writing out half-full descriptor blocks
to the journal unnecessarily growing the transaction. Fix the logic to
allocate the array large enough.
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20191105164437.32602-3-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r-- | fs/jbd2/journal.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 1c58859aa592..cc11097f1176 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1098,6 +1098,16 @@ static void jbd2_stats_proc_exit(journal_t *journal) remove_proc_entry(journal->j_devname, proc_jbd2_stats); } +/* Minimum size of descriptor tag */ +static int jbd2_min_tag_size(void) +{ + /* + * Tag with 32-bit block numbers does not use last four bytes of the + * structure + */ + return sizeof(journal_block_tag_t) - 4; +} + /* * Management for journal control blocks: functions to create and * destroy journal_t structures, and to initialise and read existing @@ -1156,7 +1166,8 @@ static journal_t *journal_init_common(struct block_device *bdev, journal->j_fs_dev = fs_dev; journal->j_blk_offset = start; journal->j_maxlen = len; - n = journal->j_blocksize / sizeof(journal_block_tag_t); + /* We need enough buffers to write out full descriptor block. */ + n = journal->j_blocksize / jbd2_min_tag_size(); journal->j_wbufsize = n; journal->j_wbuf = kmalloc_array(n, sizeof(struct buffer_head *), GFP_KERNEL); |