Skip to content

Commit 51ed42a

Browse files
committed
Merge tag 'ext4_for_linus-6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o: "Many cleanups and bug fixes in ext4, especially for the fast commit feature. Also some performance improvements; in particular, improving IOPS and throughput on fast devices running Async Direct I/O by up to 20% by optimizing jbd2_transaction_committed()" * tag 'ext4_for_linus-6.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (40 commits) ext4: make sure the first directory block is not a hole ext4: check dot and dotdot of dx_root before making dir indexed ext4: sanity check for NULL pointer after ext4_force_shutdown jbd2: increase maximum transaction size jbd2: drop pointless shrinker batch initialization jbd2: avoid infinite transaction commit loop jbd2: precompute number of transaction descriptor blocks jbd2: make jbd2_journal_get_max_txn_bufs() internal jbd2: avoid mount failed when commit block is partial submitted ext4: avoid writing unitialized memory to disk in EA inodes ext4: don't track ranges in fast_commit if inode has inlined data ext4: fix possible tid_t sequence overflows ext4: use ext4_update_inode_fsync_trans() helper in inode creation ext4: add missing MODULE_DESCRIPTION() jbd2: add missing MODULE_DESCRIPTION() ext4: use memtostr_pad() for s_volume_name jbd2: speed up jbd2_transaction_committed() ext4: make ext4_da_map_blocks() buffer_head unaware ext4: make ext4_insert_delayed_block() insert multi-blocks ext4: factor out a helper to check the cluster allocation state ...
2 parents dddebde + f9ca515 commit 51ed42a

File tree

20 files changed

+454
-250
lines changed

20 files changed

+454
-250
lines changed

fs/buffer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,6 +2184,8 @@ static void __block_commit_write(struct folio *folio, size_t from, size_t to)
21842184
struct buffer_head *bh, *head;
21852185

21862186
bh = head = folio_buffers(folio);
2187+
if (!bh)
2188+
return;
21872189
blocksize = bh->b_size;
21882190

21892191
block_start = 0;

fs/ext4/block_validity.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static int add_system_zone(struct ext4_system_blocks *system_blks,
7272
{
7373
struct ext4_system_zone *new_entry, *entry;
7474
struct rb_node **n = &system_blks->root.rb_node, *node;
75-
struct rb_node *parent = NULL, *new_node = NULL;
75+
struct rb_node *parent = NULL, *new_node;
7676

7777
while (*n) {
7878
parent = *n;

fs/ext4/ext4.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1347,7 +1347,7 @@ struct ext4_super_block {
13471347
/*60*/ __le32 s_feature_incompat; /* incompatible feature set */
13481348
__le32 s_feature_ro_compat; /* readonly-compatible feature set */
13491349
/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */
1350-
/*78*/ char s_volume_name[EXT4_LABEL_MAX]; /* volume name */
1350+
/*78*/ char s_volume_name[EXT4_LABEL_MAX] __nonstring; /* volume name */
13511351
/*88*/ char s_last_mounted[64] __nonstring; /* directory where last mounted */
13521352
/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */
13531353
/*

fs/ext4/extents_status.c

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ void ext4_es_find_extent_range(struct inode *inode,
310310
ext4_lblk_t lblk, ext4_lblk_t end,
311311
struct extent_status *es)
312312
{
313+
es->es_lblk = es->es_len = es->es_pblk = 0;
314+
313315
if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
314316
return;
315317

@@ -2052,34 +2054,49 @@ bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk)
20522054
}
20532055

20542056
/*
2055-
* ext4_es_insert_delayed_block - adds a delayed block to the extents status
2056-
* tree, adding a pending reservation where
2057-
* needed
2057+
* ext4_es_insert_delayed_extent - adds some delayed blocks to the extents
2058+
* status tree, adding a pending reservation
2059+
* where needed
20582060
*
20592061
* @inode - file containing the newly added block
2060-
* @lblk - logical block to be added
2061-
* @allocated - indicates whether a physical cluster has been allocated for
2062-
* the logical cluster that contains the block
2062+
* @lblk - start logical block to be added
2063+
* @len - length of blocks to be added
2064+
* @lclu_allocated/end_allocated - indicates whether a physical cluster has
2065+
* been allocated for the logical cluster
2066+
* that contains the start/end block. Note that
2067+
* end_allocated should always be set to false
2068+
* if the start and the end block are in the
2069+
* same cluster
20632070
*/
2064-
void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
2065-
bool allocated)
2071+
void ext4_es_insert_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
2072+
ext4_lblk_t len, bool lclu_allocated,
2073+
bool end_allocated)
20662074
{
2075+
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
20672076
struct extent_status newes;
2077+
ext4_lblk_t end = lblk + len - 1;
20682078
int err1 = 0, err2 = 0, err3 = 0;
20692079
struct extent_status *es1 = NULL;
20702080
struct extent_status *es2 = NULL;
2071-
struct pending_reservation *pr = NULL;
2081+
struct pending_reservation *pr1 = NULL;
2082+
struct pending_reservation *pr2 = NULL;
20722083

20732084
if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
20742085
return;
20752086

2076-
es_debug("add [%u/1) delayed to extent status tree of inode %lu\n",
2077-
lblk, inode->i_ino);
2087+
es_debug("add [%u/%u) delayed to extent status tree of inode %lu\n",
2088+
lblk, len, inode->i_ino);
2089+
if (!len)
2090+
return;
2091+
2092+
WARN_ON_ONCE((EXT4_B2C(sbi, lblk) == EXT4_B2C(sbi, end)) &&
2093+
end_allocated);
20782094

20792095
newes.es_lblk = lblk;
2080-
newes.es_len = 1;
2096+
newes.es_len = len;
20812097
ext4_es_store_pblock_status(&newes, ~0, EXTENT_STATUS_DELAYED);
2082-
trace_ext4_es_insert_delayed_block(inode, &newes, allocated);
2098+
trace_ext4_es_insert_delayed_extent(inode, &newes, lclu_allocated,
2099+
end_allocated);
20832100

20842101
ext4_es_insert_extent_check(inode, &newes);
20852102

@@ -2088,11 +2105,15 @@ void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
20882105
es1 = __es_alloc_extent(true);
20892106
if ((err1 || err2) && !es2)
20902107
es2 = __es_alloc_extent(true);
2091-
if ((err1 || err2 || err3) && allocated && !pr)
2092-
pr = __alloc_pending(true);
2108+
if (err1 || err2 || err3) {
2109+
if (lclu_allocated && !pr1)
2110+
pr1 = __alloc_pending(true);
2111+
if (end_allocated && !pr2)
2112+
pr2 = __alloc_pending(true);
2113+
}
20932114
write_lock(&EXT4_I(inode)->i_es_lock);
20942115

2095-
err1 = __es_remove_extent(inode, lblk, lblk, NULL, es1);
2116+
err1 = __es_remove_extent(inode, lblk, end, NULL, es1);
20962117
if (err1 != 0)
20972118
goto error;
20982119
/* Free preallocated extent if it didn't get used. */
@@ -2112,13 +2133,22 @@ void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
21122133
es2 = NULL;
21132134
}
21142135

2115-
if (allocated) {
2116-
err3 = __insert_pending(inode, lblk, &pr);
2136+
if (lclu_allocated) {
2137+
err3 = __insert_pending(inode, lblk, &pr1);
21172138
if (err3 != 0)
21182139
goto error;
2119-
if (pr) {
2120-
__free_pending(pr);
2121-
pr = NULL;
2140+
if (pr1) {
2141+
__free_pending(pr1);
2142+
pr1 = NULL;
2143+
}
2144+
}
2145+
if (end_allocated) {
2146+
err3 = __insert_pending(inode, end, &pr2);
2147+
if (err3 != 0)
2148+
goto error;
2149+
if (pr2) {
2150+
__free_pending(pr2);
2151+
pr2 = NULL;
21222152
}
21232153
}
21242154
error:

fs/ext4/extents_status.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,9 @@ extern void ext4_exit_pending(void);
249249
extern void ext4_init_pending_tree(struct ext4_pending_tree *tree);
250250
extern void ext4_remove_pending(struct inode *inode, ext4_lblk_t lblk);
251251
extern bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk);
252-
extern void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
253-
bool allocated);
252+
extern void ext4_es_insert_delayed_extent(struct inode *inode, ext4_lblk_t lblk,
253+
ext4_lblk_t len, bool lclu_allocated,
254+
bool end_allocated);
254255
extern unsigned int ext4_es_delayed_clu(struct inode *inode, ext4_lblk_t lblk,
255256
ext4_lblk_t len);
256257
extern void ext4_clear_inode_es(struct inode *inode);

fs/ext4/fast_commit.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ void ext4_fc_mark_ineligible(struct super_block *sb, int reason, handle_t *handl
353353
read_unlock(&sbi->s_journal->j_state_lock);
354354
}
355355
spin_lock(&sbi->s_fc_lock);
356-
if (sbi->s_fc_ineligible_tid < tid)
356+
if (tid_gt(tid, sbi->s_fc_ineligible_tid))
357357
sbi->s_fc_ineligible_tid = tid;
358358
spin_unlock(&sbi->s_fc_lock);
359359
WARN_ON(reason >= EXT4_FC_REASON_MAX);
@@ -649,6 +649,12 @@ void ext4_fc_track_range(handle_t *handle, struct inode *inode, ext4_lblk_t star
649649
if (ext4_test_mount_flag(inode->i_sb, EXT4_MF_FC_INELIGIBLE))
650650
return;
651651

652+
if (ext4_has_inline_data(inode)) {
653+
ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_XATTR,
654+
handle);
655+
return;
656+
}
657+
652658
args.start = start;
653659
args.end = end;
654660

@@ -1207,7 +1213,7 @@ int ext4_fc_commit(journal_t *journal, tid_t commit_tid)
12071213
if (ret == -EALREADY) {
12081214
/* There was an ongoing commit, check if we need to restart */
12091215
if (atomic_read(&sbi->s_fc_subtid) <= subtid &&
1210-
commit_tid > journal->j_commit_sequence)
1216+
tid_gt(commit_tid, journal->j_commit_sequence))
12111217
goto restart_fc;
12121218
ext4_fc_update_stats(sb, EXT4_FC_STATUS_SKIPPED, 0, 0,
12131219
commit_tid);
@@ -1282,7 +1288,7 @@ static void ext4_fc_cleanup(journal_t *journal, int full, tid_t tid)
12821288
list_del_init(&iter->i_fc_list);
12831289
ext4_clear_inode_state(&iter->vfs_inode,
12841290
EXT4_STATE_FC_COMMITTING);
1285-
if (iter->i_sync_tid <= tid)
1291+
if (tid_geq(tid, iter->i_sync_tid))
12861292
ext4_fc_reset_inode(&iter->vfs_inode);
12871293
/* Make sure EXT4_STATE_FC_COMMITTING bit is clear */
12881294
smp_mb();
@@ -1313,7 +1319,7 @@ static void ext4_fc_cleanup(journal_t *journal, int full, tid_t tid)
13131319
list_splice_init(&sbi->s_fc_q[FC_Q_STAGING],
13141320
&sbi->s_fc_q[FC_Q_MAIN]);
13151321

1316-
if (tid >= sbi->s_fc_ineligible_tid) {
1322+
if (tid_geq(tid, sbi->s_fc_ineligible_tid)) {
13171323
sbi->s_fc_ineligible_tid = 0;
13181324
ext4_clear_mount_flag(sb, EXT4_MF_FC_INELIGIBLE);
13191325
}

fs/ext4/ialloc.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,10 +1336,7 @@ struct inode *__ext4_new_inode(struct mnt_idmap *idmap,
13361336
}
13371337
}
13381338

1339-
if (ext4_handle_valid(handle)) {
1340-
ei->i_sync_tid = handle->h_transaction->t_tid;
1341-
ei->i_datasync_tid = handle->h_transaction->t_tid;
1342-
}
1339+
ext4_update_inode_fsync_trans(handle, inode, 1);
13431340

13441341
err = ext4_mark_inode_dirty(handle, inode);
13451342
if (err) {

fs/ext4/inline.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1410,7 +1410,11 @@ int ext4_inlinedir_to_tree(struct file *dir_file,
14101410
hinfo->hash = EXT4_DIRENT_HASH(de);
14111411
hinfo->minor_hash = EXT4_DIRENT_MINOR_HASH(de);
14121412
} else {
1413-
ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
1413+
err = ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
1414+
if (err) {
1415+
ret = err;
1416+
goto out;
1417+
}
14141418
}
14151419
if ((hinfo->hash < start_hash) ||
14161420
((hinfo->hash == start_hash) &&

fs/ext4/inode-test.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,4 +279,5 @@ static struct kunit_suite ext4_inode_test_suite = {
279279

280280
kunit_test_suites(&ext4_inode_test_suite);
281281

282+
MODULE_DESCRIPTION("KUnit test of ext4 inode timestamp decoding");
282283
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)