Skip to content

Commit 6866d7b

Browse files
harshadjstytso
authored andcommitted
ext4 / jbd2: add fast commit initialization
This patch adds fast commit area trackers in the journal_t structure. These are initialized via the jbd2_fc_init() routine that this patch adds. This patch also adds ext4/fast_commit.c and ext4/fast_commit.h files for fast commit code that will be added in subsequent patches in this series. Reported-by: kernel test robot <[email protected]> Signed-off-by: Harshad Shirwadkar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 995a3ed commit 6866d7b

File tree

7 files changed

+122
-6
lines changed

7 files changed

+122
-6
lines changed

fs/ext4/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ext4-y := balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \
1010
indirect.o inline.o inode.o ioctl.o mballoc.o migrate.o \
1111
mmp.o move_extent.o namei.o page-io.o readpage.o resize.o \
1212
super.o symlink.o sysfs.o xattr.o xattr_hurd.o xattr_trusted.o \
13-
xattr_user.o
13+
xattr_user.o fast_commit.o
1414

1515
ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o
1616
ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o

fs/ext4/ext4.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,7 @@ do { \
963963
#endif /* defined(__KERNEL__) || defined(__linux__) */
964964

965965
#include "extents_status.h"
966+
#include "fast_commit.h"
966967

967968
/*
968969
* Lock subclasses for i_data_sem in the ext4_inode_info structure.
@@ -2678,6 +2679,9 @@ extern int ext4_init_inode_table(struct super_block *sb,
26782679
ext4_group_t group, int barrier);
26792680
extern void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate);
26802681

2682+
/* fast_commit.c */
2683+
2684+
void ext4_fc_init(struct super_block *sb, journal_t *journal);
26812685
/* mballoc.c */
26822686
extern const struct seq_operations ext4_mb_seq_groups_ops;
26832687
extern long ext4_mb_stats;

fs/ext4/fast_commit.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
/*
4+
* fs/ext4/fast_commit.c
5+
*
6+
* Written by Harshad Shirwadkar <[email protected]>
7+
*
8+
* Ext4 fast commits routines.
9+
*/
10+
#include "ext4_jbd2.h"
11+
12+
void ext4_fc_init(struct super_block *sb, journal_t *journal)
13+
{
14+
if (!test_opt2(sb, JOURNAL_FAST_COMMIT))
15+
return;
16+
if (jbd2_fc_init(journal, EXT4_NUM_FC_BLKS)) {
17+
pr_warn("Error while enabling fast commits, turning off.");
18+
ext4_clear_feature_fast_commit(sb);
19+
}
20+
}

fs/ext4/fast_commit.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
3+
#ifndef __FAST_COMMIT_H__
4+
#define __FAST_COMMIT_H__
5+
6+
/* Number of blocks in journal area to allocate for fast commits */
7+
#define EXT4_NUM_FC_BLKS 256
8+
9+
#endif /* __FAST_COMMIT_H__ */

fs/ext4/super.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5170,6 +5170,7 @@ static void ext4_init_journal_params(struct super_block *sb, journal_t *journal)
51705170
journal->j_commit_interval = sbi->s_commit_interval;
51715171
journal->j_min_batch_time = sbi->s_min_batch_time;
51725172
journal->j_max_batch_time = sbi->s_max_batch_time;
5173+
ext4_fc_init(sb, journal);
51735174

51745175
write_lock(&journal->j_state_lock);
51755176
if (test_opt(sb, BARRIER))

fs/jbd2/journal.c

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,14 @@ static journal_t *journal_init_common(struct block_device *bdev,
11811181
if (!journal->j_wbuf)
11821182
goto err_cleanup;
11831183

1184+
if (journal->j_fc_wbufsize > 0) {
1185+
journal->j_fc_wbuf = kmalloc_array(journal->j_fc_wbufsize,
1186+
sizeof(struct buffer_head *),
1187+
GFP_KERNEL);
1188+
if (!journal->j_fc_wbuf)
1189+
goto err_cleanup;
1190+
}
1191+
11841192
bh = getblk_unmovable(journal->j_dev, start, journal->j_blocksize);
11851193
if (!bh) {
11861194
pr_err("%s: Cannot get buffer for journal superblock\n",
@@ -1194,11 +1202,23 @@ static journal_t *journal_init_common(struct block_device *bdev,
11941202

11951203
err_cleanup:
11961204
kfree(journal->j_wbuf);
1205+
kfree(journal->j_fc_wbuf);
11971206
jbd2_journal_destroy_revoke(journal);
11981207
kfree(journal);
11991208
return NULL;
12001209
}
12011210

1211+
int jbd2_fc_init(journal_t *journal, int num_fc_blks)
1212+
{
1213+
journal->j_fc_wbufsize = num_fc_blks;
1214+
journal->j_fc_wbuf = kmalloc_array(journal->j_fc_wbufsize,
1215+
sizeof(struct buffer_head *), GFP_KERNEL);
1216+
if (!journal->j_fc_wbuf)
1217+
return -ENOMEM;
1218+
return 0;
1219+
}
1220+
EXPORT_SYMBOL(jbd2_fc_init);
1221+
12021222
/* jbd2_journal_init_dev and jbd2_journal_init_inode:
12031223
*
12041224
* Create a journal structure assigned some fixed set of disk blocks to
@@ -1316,11 +1336,20 @@ static int journal_reset(journal_t *journal)
13161336
}
13171337

13181338
journal->j_first = first;
1319-
journal->j_last = last;
13201339

1321-
journal->j_head = first;
1322-
journal->j_tail = first;
1323-
journal->j_free = last - first;
1340+
if (jbd2_has_feature_fast_commit(journal) &&
1341+
journal->j_fc_wbufsize > 0) {
1342+
journal->j_fc_last = last;
1343+
journal->j_last = last - journal->j_fc_wbufsize;
1344+
journal->j_fc_first = journal->j_last + 1;
1345+
journal->j_fc_off = 0;
1346+
} else {
1347+
journal->j_last = last;
1348+
}
1349+
1350+
journal->j_head = journal->j_first;
1351+
journal->j_tail = journal->j_first;
1352+
journal->j_free = journal->j_last - journal->j_first;
13241353

13251354
journal->j_tail_sequence = journal->j_transaction_sequence;
13261355
journal->j_commit_sequence = journal->j_transaction_sequence - 1;
@@ -1665,9 +1694,18 @@ static int load_superblock(journal_t *journal)
16651694
journal->j_tail_sequence = be32_to_cpu(sb->s_sequence);
16661695
journal->j_tail = be32_to_cpu(sb->s_start);
16671696
journal->j_first = be32_to_cpu(sb->s_first);
1668-
journal->j_last = be32_to_cpu(sb->s_maxlen);
16691697
journal->j_errno = be32_to_cpu(sb->s_errno);
16701698

1699+
if (jbd2_has_feature_fast_commit(journal) &&
1700+
journal->j_fc_wbufsize > 0) {
1701+
journal->j_fc_last = be32_to_cpu(sb->s_maxlen);
1702+
journal->j_last = journal->j_fc_last - journal->j_fc_wbufsize;
1703+
journal->j_fc_first = journal->j_last + 1;
1704+
journal->j_fc_off = 0;
1705+
} else {
1706+
journal->j_last = be32_to_cpu(sb->s_maxlen);
1707+
}
1708+
16711709
return 0;
16721710
}
16731711

@@ -1728,6 +1766,9 @@ int jbd2_journal_load(journal_t *journal)
17281766
*/
17291767
journal->j_flags &= ~JBD2_ABORT;
17301768

1769+
if (journal->j_fc_wbufsize > 0)
1770+
jbd2_journal_set_features(journal, 0, 0,
1771+
JBD2_FEATURE_INCOMPAT_FAST_COMMIT);
17311772
/* OK, we've finished with the dynamic journal bits:
17321773
* reinitialise the dynamic contents of the superblock in memory
17331774
* and reset them on disk. */
@@ -1811,6 +1852,8 @@ int jbd2_journal_destroy(journal_t *journal)
18111852
jbd2_journal_destroy_revoke(journal);
18121853
if (journal->j_chksum_driver)
18131854
crypto_free_shash(journal->j_chksum_driver);
1855+
if (journal->j_fc_wbufsize > 0)
1856+
kfree(journal->j_fc_wbuf);
18141857
kfree(journal->j_wbuf);
18151858
kfree(journal);
18161859

include/linux/jbd2.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,30 @@ struct journal_s
918918
*/
919919
unsigned long j_last;
920920

921+
/**
922+
* @j_fc_first:
923+
*
924+
* The block number of the first fast commit block in the journal
925+
* [j_state_lock].
926+
*/
927+
unsigned long j_fc_first;
928+
929+
/**
930+
* @j_fc_off:
931+
*
932+
* Number of fast commit blocks currently allocated.
933+
* [j_state_lock].
934+
*/
935+
unsigned long j_fc_off;
936+
937+
/**
938+
* @j_fc_last:
939+
*
940+
* The block number one beyond the last fast commit block in the journal
941+
* [j_state_lock].
942+
*/
943+
unsigned long j_fc_last;
944+
921945
/**
922946
* @j_dev: Device where we store the journal.
923947
*/
@@ -1068,13 +1092,26 @@ struct journal_s
10681092
*/
10691093
struct buffer_head **j_wbuf;
10701094

1095+
/**
1096+
* @j_fc_wbuf: Array of fast commit bhs for
1097+
* jbd2_journal_commit_transaction.
1098+
*/
1099+
struct buffer_head **j_fc_wbuf;
1100+
10711101
/**
10721102
* @j_wbufsize:
10731103
*
10741104
* Size of @j_wbuf array.
10751105
*/
10761106
int j_wbufsize;
10771107

1108+
/**
1109+
* @j_fc_wbufsize:
1110+
*
1111+
* Size of @j_fc_wbuf array.
1112+
*/
1113+
int j_fc_wbufsize;
1114+
10781115
/**
10791116
* @j_last_sync_writer:
10801117
*
@@ -1535,6 +1572,8 @@ void __jbd2_log_wait_for_space(journal_t *journal);
15351572
extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *);
15361573
extern int jbd2_cleanup_journal_tail(journal_t *);
15371574

1575+
/* Fast commit related APIs */
1576+
int jbd2_fc_init(journal_t *journal, int num_fc_blks);
15381577
/*
15391578
* is_journal_abort
15401579
*

0 commit comments

Comments
 (0)