History

Merge tag 'ext4_for_linus-7.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull ext4 fixes from Ted Ts'o: - Update the MAINTAINERS file to add reviewers for the ext4 file system - Add a test issue an ext4 warning (not a WARN_ON) if there are still dirty pages attached to an evicted inode. - Fix a number of Syzkaller issues - Fix memory leaks on error paths - Replace some BUG and WARN with EFSCORRUPTED reporting - Fix a potential crash when disabling discard via remount followed by an immediate unmount. (Found by Sashiko) - Fix a corner case which could lead to allocating blocks for an indirect-mapped inode block numbers > 2**32 - Fix a race when reallocating a freed inode that could result in a deadlock - Fix a user-after-free in update_super_work when racing with umount - Fix build issues when trying to build ext4's kunit tests as a module - Fix a bug where ext4_split_extent_zeroout() could fail to pass back an error from ext4_ext_dirty() - Avoid allocating blocks from a corrupted block group in ext4_mb_find_by_goal() - Fix a percpu_counters list corruption BUG triggered by an ext4 extents kunit - Fix a potetial crash caused by the fast commit flush path potentially accessing the jinode structure before it is fully initialized - Fix fsync(2) in no-journal mode to make sure the dirtied inode is write to storage - Fix a bug when in no-journal mode, when ext4 tries to avoid using recently deleted inodes, if lazy itable initialization is enabled, can lead to an unitialized inode getting skipped and triggering an e2fsck complaint - Fix journal credit calculation when setting an xattr when both the encryption and ea_inode feeatures are enabled - Fix corner cases which could result in stale xarray tags after writeback - Fix generic/475 failures caused by ENOSPC errors while creating a symlink when the system crashes resulting to a file system inconsistency when replaying the fast commit journal * tag 'ext4_for_linus-7.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (27 commits) ext4: always drain queued discard work in ext4_mb_release() ext4: handle wraparound when searching for blocks for indirect mapped blocks ext4: skip split extent recovery on corruption ext4: fix iloc.bh leak in ext4_fc_replay_inode() error paths ext4: fix deadlock on inode reallocation ext4: fix use-after-free in update_super_work when racing with umount ext4: fix the might_sleep() warnings in kvfree() ext4: reject mount if bigalloc with s_first_data_block != 0 ext4: fix extents-test.c is not compiled when EXT4_KUNIT_TESTS=M ext4: fix mballoc-test.c is not compiled when EXT4_KUNIT_TESTS=M ext4: introduce EXPORT_SYMBOL_FOR_EXT4_TEST() helper jbd2: gracefully abort on checkpointing state corruptions ext4: avoid infinite loops caused by residual data ext4: validate p_idx bounds in ext4_ext_correct_indexes ext4: test if inode's all dirty pages are submitted to disk ext4: minor fix for ext4_split_extent_zeroout() ext4: avoid allocate block from corrupted group in ext4_mb_find_by_goal() ext4: kunit: extents-test: lix percpu_counters list corruption ext4: publish jinode after initialization ext4: replace BUG_ON with proper error handling in ext4_read_inline_folio ...

Linus Torvalds committed 7 months ago

Commit 241d4ca2 parents b51ad67 9ee29d219 files · +455 −115Browse files

Unified · Split

19 files
  1. MAINTAINERS +6 −1
  2. fs/ext4/Makefile +3 −2
  3. fs/ext4/crypto.c +8 −1
  4. fs/ext4/ext4.h +6 −0
  5. fs/ext4/ext4_extents.h +12 −0
  6. fs/ext4/extents-test.c +7 −5
  7. fs/ext4/extents.c +68 −12
  8. fs/ext4/fast_commit.c +10 −7
  9. fs/ext4/fsync.c +14 −2
  10. fs/ext4/ialloc.c +6 −0
  11. fs/ext4/inline.c +9 −1
  12. fs/ext4/inode.c +60 −15
  13. fs/ext4/mballoc-test.c +41 −40
  14. fs/ext4/mballoc.c +114 −18
  15. fs/ext4/mballoc.h +30 −0
  16. fs/ext4/page-io.c +8 −2
  17. fs/ext4/super.c +31 −6
  18. fs/ext4/sysfs.c +9 −1
  19. fs/jbd2/checkpoint.c +13 −2
MAINTAINERS+6−1
@@ -9619,7 +9619,12 @@ F: include/linux/ext2* · 9618 unmodified lines
96199619
96209620 EXT4 FILE SYSTEM
96219621 M: "Theodore Ts'o" <tytso@mit.edu>
9622−M: Andreas Dilger <adilger.kernel@dilger.ca>
9622+R: Andreas Dilger <adilger.kernel@dilger.ca>
9623+R: Baokun Li <libaokun@linux.alibaba.com>
9624+R: Jan Kara <jack@suse.cz>
9625+R: Ojaswin Mujoo <ojaswin@linux.ibm.com>
9626+R: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
9627+R: Zhang Yi <yi.zhang@huawei.com>
96239628 L: linux-ext4@vger.kernel.org
96249629 S: Maintained
96259630 W: http://ext4.wiki.kernel.org
fs/ext4/Makefile+3−2
@@ -14,7 +14,8 @@ ext4-y := balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ · 13 unmodified lines
1414
1515 ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o
1616 ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o
17−ext4-inode-test-objs += inode-test.o
18−obj-$(CONFIG_EXT4_KUNIT_TESTS) += ext4-inode-test.o
17+ext4-test-objs += inode-test.o mballoc-test.o \
18+ extents-test.o
19+obj-$(CONFIG_EXT4_KUNIT_TESTS) += ext4-test.o
1920 ext4-$(CONFIG_FS_VERITY) += verity.o
2021 ext4-$(CONFIG_FS_ENCRYPTION) += crypto.o
fs/ext4/crypto.c+8−1
@@ -163,10 +163,17 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len, · 162 unmodified lines
163163 */
164164
165165 if (handle) {
166+ /*
167+ * Since the inode is new it is ok to pass the
168+ * XATTR_CREATE flag. This is necessary to match the
169+ * remaining journal credits check in the set_handle
170+ * function with the credits allocated for the new
171+ * inode.
172+ */
166173 res = ext4_xattr_set_handle(handle, inode,
167174 EXT4_XATTR_INDEX_ENCRYPTION,
168175 EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
169− ctx, len, 0);
176+ ctx, len, XATTR_CREATE);
170177 if (!res) {
171178 ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
172179 ext4_clear_inode_state(inode,
fs/ext4/ext4.h+6−0
@@ -1570,6 +1570,7 @@ struct ext4_sb_info { · 1569 unmodified lines
15701570 struct proc_dir_entry *s_proc;
15711571 struct kobject s_kobj;
15721572 struct completion s_kobj_unregister;
1573+ struct mutex s_error_notify_mutex; /* protects sysfs_notify vs kobject_del */
15731574 struct super_block *s_sb;
15741575 struct buffer_head *s_mmp_bh;
15751576
@@ -3944,6 +3945,11 @@ static inline bool ext4_inode_can_atomic_write(struct inode *inode) · 2368 unmodified lines
39443945 extern int ext4_block_write_begin(handle_t *handle, struct folio *folio,
39453946 loff_t pos, unsigned len,
39463947 get_block_t *get_block);
3948+
3949+#if IS_ENABLED(CONFIG_EXT4_KUNIT_TESTS)
3950+#define EXPORT_SYMBOL_FOR_EXT4_TEST(sym) \
3951+ EXPORT_SYMBOL_FOR_MODULES(sym, "ext4-test")
3952+#endif
39473953 #endif /* __KERNEL__ */
39483954
39493955 #endif /* _EXT4_H */
fs/ext4/ext4_extents.h+12−0
@@ -264,5 +264,17 @@ static inline void ext4_idx_store_pblock(struct ext4_extent_idx *ix, · 263 unmodified lines
264264 0xffff);
265265 }
266266
267+extern int __ext4_ext_dirty(const char *where, unsigned int line,
268+ handle_t *handle, struct inode *inode,
269+ struct ext4_ext_path *path);
270+extern int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex);
271+#if IS_ENABLED(CONFIG_EXT4_KUNIT_TESTS)
272+extern int ext4_ext_space_root_idx_test(struct inode *inode, int check);
273+extern struct ext4_ext_path *ext4_split_convert_extents_test(
274+ handle_t *handle, struct inode *inode,
275+ struct ext4_map_blocks *map,
276+ struct ext4_ext_path *path,
277+ int flags, unsigned int *allocated);
278+#endif
267279 #endif /* _EXT4_EXTENTS */
268280
fs/ext4/extents-test.c+7−5
@@ -142,8 +142,10 @@ static struct file_system_type ext_fs_type = { · 141 unmodified lines
142142
143143 static void extents_kunit_exit(struct kunit *test)
144144 {
145− struct ext4_sb_info *sbi = k_ctx.k_ei->vfs_inode.i_sb->s_fs_info;
145+ struct super_block *sb = k_ctx.k_ei->vfs_inode.i_sb;
146+ struct ext4_sb_info *sbi = sb->s_fs_info;
146147
148+ ext4_es_unregister_shrinker(sbi);
147149 kfree(sbi);
148150 kfree(k_ctx.k_ei);
149151 kfree(k_ctx.k_data);
@@ -280,8 +282,8 @@ static int extents_kunit_init(struct kunit *test) · 130 unmodified lines
280282 eh->eh_depth = 0;
281283 eh->eh_entries = cpu_to_le16(1);
282284 eh->eh_magic = EXT4_EXT_MAGIC;
283− eh->eh_max =
284− cpu_to_le16(ext4_ext_space_root_idx(&k_ctx.k_ei->vfs_inode, 0));
285+ eh->eh_max = cpu_to_le16(ext4_ext_space_root_idx_test(
286+ &k_ctx.k_ei->vfs_inode, 0));
285287 eh->eh_generation = 0;
286288
287289 /*
@@ -384,8 +386,8 @@ static void test_split_convert(struct kunit *test) · 96 unmodified lines
384386
385387 switch (param->type) {
386388 case TEST_SPLIT_CONVERT:
387− path = ext4_split_convert_extents(NULL, inode, &map, path,
388− param->split_flags, NULL);
389+ path = ext4_split_convert_extents_test(NULL, inode, &map,
390+ path, param->split_flags, NULL);
389391 break;
390392 case TEST_CREATE_BLOCKS:
391393 ext4_map_create_blocks_helper(test, inode, &map, param->split_flags);
fs/ext4/extents.c+68−12
@@ -184,9 +184,9 @@ static int ext4_ext_get_access(handle_t *handle, struct inode *inode, · 183 unmodified lines
184184 * - ENOMEM
185185 * - EIO
186186 */
187−static int __ext4_ext_dirty(const char *where, unsigned int line,
188− handle_t *handle, struct inode *inode,
189− struct ext4_ext_path *path)
187+int __ext4_ext_dirty(const char *where, unsigned int line,
188+ handle_t *handle, struct inode *inode,
189+ struct ext4_ext_path *path)
190190 {
191191 int err;
192192
@@ -1736,6 +1736,13 @@ static int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode, · 1543 unmodified lines
17361736 err = ext4_ext_get_access(handle, inode, path + k);
17371737 if (err)
17381738 return err;
1739+ if (unlikely(path[k].p_idx > EXT_LAST_INDEX(path[k].p_hdr))) {
1740+ EXT4_ERROR_INODE(inode,
1741+ "path[%d].p_idx %p > EXT_LAST_INDEX %p",
1742+ k, path[k].p_idx,
1743+ EXT_LAST_INDEX(path[k].p_hdr));
1744+ return -EFSCORRUPTED;
1745+ }
17391746 path[k].p_idx->ei_block = border;
17401747 err = ext4_ext_dirty(handle, inode, path + k);
17411748 if (err)
@@ -1748,6 +1755,14 @@ static int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode, · 6 unmodified lines
17481755 err = ext4_ext_get_access(handle, inode, path + k);
17491756 if (err)
17501757 goto clean;
1758+ if (unlikely(path[k].p_idx > EXT_LAST_INDEX(path[k].p_hdr))) {
1759+ EXT4_ERROR_INODE(inode,
1760+ "path[%d].p_idx %p > EXT_LAST_INDEX %p",
1761+ k, path[k].p_idx,
1762+ EXT_LAST_INDEX(path[k].p_hdr));
1763+ err = -EFSCORRUPTED;
1764+ goto clean;
1765+ }
17511766 path[k].p_idx->ei_block = border;
17521767 err = ext4_ext_dirty(handle, inode, path + k);
17531768 if (err)
@@ -3144,7 +3159,7 @@ static void ext4_zeroout_es(struct inode *inode, struct ext4_extent *ex) · 1390 unmodified lines
31443159 }
31453160
31463161 /* FIXME!! we need to try to merge to left or right after zero-out */
3147−static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
3162+int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
31483163 {
31493164 ext4_fsblk_t ee_pblock;
31503165 unsigned int ee_len;
@@ -3239,6 +3254,9 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle, · 88 unmodified lines
32393254
32403255 insert_err = PTR_ERR(path);
32413256 err = 0;
3257+ if (insert_err != -ENOSPC && insert_err != -EDQUOT &&
3258+ insert_err != -ENOMEM)
3259+ goto out_path;
32423260
32433261 /*
32443262 * Get a new path to try to zeroout or fix the extent length.
@@ -3255,13 +3273,20 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle, · 10 unmodified lines
32553273 goto out_path;
32563274 }
32573275
3276+ depth = ext_depth(inode);
3277+ ex = path[depth].p_ext;
3278+ if (!ex) {
3279+ EXT4_ERROR_INODE(inode,
3280+ "bad extent address lblock: %lu, depth: %d pblock %llu",
3281+ (unsigned long)ee_block, depth, path[depth].p_block);
3282+ err = -EFSCORRUPTED;
3283+ goto out;
3284+ }
3285+
32583286 err = ext4_ext_get_access(handle, inode, path + depth);
32593287 if (err)
32603288 goto out;
32613289
3262− depth = ext_depth(inode);
3263− ex = path[depth].p_ext;
3264−
32653290 fix_extent_len:
32663291 ex->ee_len = orig_ex.ee_len;
32673292 err = ext4_ext_dirty(handle, inode, path + path->p_depth);
@@ -3363,7 +3388,7 @@ static int ext4_split_extent_zeroout(handle_t *handle, struct inode *inode, · 95 unmodified lines
33633388
33643389 ext4_ext_mark_initialized(ex);
33653390
3366− ext4_ext_dirty(handle, inode, path + depth);
3391+ err = ext4_ext_dirty(handle, inode, path + depth);
33673392 if (err)
33683393 return err;
33693394
@@ -4457,9 +4482,13 @@ got_allocated_blocks: · 1087 unmodified lines
44574482 path = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
44584483 if (IS_ERR(path)) {
44594484 err = PTR_ERR(path);
4460− if (allocated_clusters) {
4485+ /*
4486+ * Gracefully handle out of space conditions. If the filesystem
4487+ * is inconsistent, we'll just leak allocated blocks to avoid
4488+ * causing even more damage.
4489+ */
4490+ if (allocated_clusters && (err == -EDQUOT || err == -ENOSPC)) {
44614491 int fb_flags = 0;
4462−
44634492 /*
44644493 * free data blocks we just allocated.
44654494 * not a good idea to call discard here directly,
@@ -6238,6 +6267,33 @@ out: · 1772 unmodified lines
62386267 return 0;
62396268 }
62406269
6241−#ifdef CONFIG_EXT4_KUNIT_TESTS
6242−#include "extents-test.c"
6270+#if IS_ENABLED(CONFIG_EXT4_KUNIT_TESTS)
6271+int ext4_ext_space_root_idx_test(struct inode *inode, int check)
6272+{
6273+ return ext4_ext_space_root_idx(inode, check);
6274+}
6275+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_ext_space_root_idx_test);
6276+
6277+struct ext4_ext_path *ext4_split_convert_extents_test(handle_t *handle,
6278+ struct inode *inode, struct ext4_map_blocks *map,
6279+ struct ext4_ext_path *path, int flags,
6280+ unsigned int *allocated)
6281+{
6282+ return ext4_split_convert_extents(handle, inode, map, path,
6283+ flags, allocated);
6284+}
6285+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_split_convert_extents_test);
6286+
6287+EXPORT_SYMBOL_FOR_EXT4_TEST(__ext4_ext_dirty);
6288+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_ext_zeroout);
6289+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_es_register_shrinker);
6290+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_es_unregister_shrinker);
6291+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_map_create_blocks);
6292+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_es_init_tree);
6293+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_es_lookup_extent);
6294+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_es_insert_extent);
6295+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_ext_insert_extent);
6296+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_find_extent);
6297+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_issue_zeroout);
6298+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_map_query_blocks);
62436299 #endif
fs/ext4/fast_commit.c+10−7
@@ -975,13 +975,13 @@ static int ext4_fc_flush_data(journal_t *journal) · 974 unmodified lines
975975 int ret = 0;
976976
977977 list_for_each_entry(ei, &sbi->s_fc_q[FC_Q_MAIN], i_fc_list) {
978− ret = jbd2_submit_inode_data(journal, ei->jinode);
978+ ret = jbd2_submit_inode_data(journal, READ_ONCE(ei->jinode));
979979 if (ret)
980980 return ret;
981981 }
982982
983983 list_for_each_entry(ei, &sbi->s_fc_q[FC_Q_MAIN], i_fc_list) {
984− ret = jbd2_wait_inode_data(journal, ei->jinode);
984+ ret = jbd2_wait_inode_data(journal, READ_ONCE(ei->jinode));
985985 if (ret)
986986 return ret;
987987 }
@@ -1613,19 +1613,21 @@ static int ext4_fc_replay_inode(struct super_block *sb, · 625 unmodified lines
16131613 /* Immediately update the inode on disk. */
16141614 ret = ext4_handle_dirty_metadata(NULL, NULL, iloc.bh);
16151615 if (ret)
1616− goto out;
1616+ goto out_brelse;
16171617 ret = sync_dirty_buffer(iloc.bh);
16181618 if (ret)
1619− goto out;
1619+ goto out_brelse;
16201620 ret = ext4_mark_inode_used(sb, ino);
16211621 if (ret)
1622− goto out;
1622+ goto out_brelse;
16231623
16241624 /* Given that we just wrote the inode on disk, this SHOULD succeed. */
16251625 inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
16261626 if (IS_ERR(inode)) {
16271627 ext4_debug("Inode not found.");
1628− return -EFSCORRUPTED;
1628+ inode = NULL;
1629+ ret = -EFSCORRUPTED;
1630+ goto out_brelse;
16291631 }
16301632
16311633 /*
@@ -1642,13 +1644,14 @@ static int ext4_fc_replay_inode(struct super_block *sb, · 10 unmodified lines
16421644 ext4_inode_csum_set(inode, ext4_raw_inode(&iloc), EXT4_I(inode));
16431645 ret = ext4_handle_dirty_metadata(NULL, NULL, iloc.bh);
16441646 sync_dirty_buffer(iloc.bh);
1647+out_brelse:
16451648 brelse(iloc.bh);
16461649 out:
16471650 iput(inode);
16481651 if (!ret)
16491652 blkdev_issue_flush(sb->s_bdev);
16501653
1651− return 0;
1654+ return ret;
16521655 }
16531656
16541657 /*
fs/ext4/fsync.c+14−2
@@ -83,11 +83,23 @@ static int ext4_fsync_nojournal(struct file *file, loff_t start, loff_t end, · 82 unmodified lines
8383 int datasync, bool *needs_barrier)
8484 {
8585 struct inode *inode = file->f_inode;
86+ struct writeback_control wbc = {
87+ .sync_mode = WB_SYNC_ALL,
88+ .nr_to_write = 0,
89+ };
8690 int ret;
8791
8892 ret = generic_buffers_fsync_noflush(file, start, end, datasync);
89− if (!ret)
90− ret = ext4_sync_parent(inode);
93+ if (ret)
94+ return ret;
95+
96+ /* Force writeout of inode table buffer to disk */
97+ ret = ext4_write_inode(inode, &wbc);
98+ if (ret)
99+ return ret;
100+
101+ ret = ext4_sync_parent(inode);
102+
91103 if (test_opt(inode->i_sb, BARRIER))
92104 *needs_barrier = true;
93105
fs/ext4/ialloc.c+6−0
@@ -686,6 +686,12 @@ static int recently_deleted(struct super_block *sb, ext4_group_t group, int ino) · 685 unmodified lines
686686 if (unlikely(!gdp))
687687 return 0;
688688
689+ /* Inode was never used in this filesystem? */
690+ if (ext4_has_group_desc_csum(sb) &&
691+ (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT) ||
692+ ino >= EXT4_INODES_PER_GROUP(sb) - ext4_itable_unused_count(sb, gdp)))
693+ return 0;
694+
689695 bh = sb_find_get_block(sb, ext4_inode_table(sb, gdp) +
690696 (ino / inodes_per_block));
691697 if (!bh || !buffer_uptodate(bh))
fs/ext4/inline.c+9−1
@@ -522,7 +522,15 @@ static int ext4_read_inline_folio(struct inode *inode, struct folio *folio) · 521 unmodified lines
522522 goto out;
523523
524524 len = min_t(size_t, ext4_get_inline_size(inode), i_size_read(inode));
525− BUG_ON(len > PAGE_SIZE);
525+
526+ if (len > PAGE_SIZE) {
527+ ext4_error_inode(inode, __func__, __LINE__, 0,
528+ "inline size %zu exceeds PAGE_SIZE", len);
529+ ret = -EFSCORRUPTED;
530+ brelse(iloc.bh);
531+ goto out;
532+ }
533+
526534 kaddr = kmap_local_folio(folio, 0);
527535 ret = ext4_read_inline_data(inode, kaddr, len, &iloc);
528536 kaddr = folio_zero_tail(folio, len, kaddr + len);
fs/ext4/inode.c+60−15
@@ -128,6 +128,8 @@ void ext4_inode_csum_set(struct inode *inode, struct ext4_inode *raw, · 127 unmodified lines
128128 static inline int ext4_begin_ordered_truncate(struct inode *inode,
129129 loff_t new_size)
130130 {
131+ struct jbd2_inode *jinode = READ_ONCE(EXT4_I(inode)->jinode);
132+
131133 trace_ext4_begin_ordered_truncate(inode, new_size);
132134 /*
133135 * If jinode is zero, then we never opened the file for
@@ -135,10 +137,10 @@ static inline int ext4_begin_ordered_truncate(struct inode *inode, · 1 unmodified line
135137 * jbd2_journal_begin_ordered_truncate() since there's no
136138 * outstanding writes we need to flush.
137139 */
138− if (!EXT4_I(inode)->jinode)
140+ if (!jinode)
139141 return 0;
140142 return jbd2_journal_begin_ordered_truncate(EXT4_JOURNAL(inode),
141− EXT4_I(inode)->jinode,
143+ jinode,
142144 new_size);
143145 }
144146
@@ -184,6 +186,14 @@ void ext4_evict_inode(struct inode *inode) · 39 unmodified lines
184186 if (EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)
185187 ext4_evict_ea_inode(inode);
186188 if (inode->i_nlink) {
189+ /*
190+ * If there's dirty page will lead to data loss, user
191+ * could see stale data.
192+ */
193+ if (unlikely(!ext4_emergency_state(inode->i_sb) &&
194+ mapping_tagged(&inode->i_data, PAGECACHE_TAG_DIRTY)))
195+ ext4_warning_inode(inode, "data will be lost");
196+
187197 truncate_inode_pages_final(&inode->i_data);
188198
189199 goto no_delete;
@@ -4451,8 +4461,13 @@ int ext4_inode_attach_jinode(struct inode *inode) · 4261 unmodified lines
44514461 spin_unlock(&inode->i_lock);
44524462 return -ENOMEM;
44534463 }
4454− ei->jinode = jinode;
4455− jbd2_journal_init_jbd_inode(ei->jinode, inode);
4464+ jbd2_journal_init_jbd_inode(jinode, inode);
4465+ /*
4466+ * Publish ->jinode only after it is fully initialized so that
4467+ * readers never observe a partially initialized jbd2_inode.
4468+ */
4469+ smp_wmb();
4470+ WRITE_ONCE(ei->jinode, jinode);
44564471 jinode = NULL;
44574472 }
44584473 spin_unlock(&inode->i_lock);
@@ -5401,18 +5416,36 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, · 942 unmodified lines
54015416 inode->i_op = &ext4_encrypted_symlink_inode_operations;
54025417 } else if (ext4_inode_is_fast_symlink(inode)) {
54035418 inode->i_op = &ext4_fast_symlink_inode_operations;
5404− if (inode->i_size == 0 ||
5405− inode->i_size >= sizeof(ei->i_data) ||
5406− strnlen((char *)ei->i_data, inode->i_size + 1) !=
5407− inode->i_size) {
5408− ext4_error_inode(inode, function, line, 0,
5409− "invalid fast symlink length %llu",
5410− (unsigned long long)inode->i_size);
5411− ret = -EFSCORRUPTED;
5412− goto bad_inode;
5419+
5420+ /*
5421+ * Orphan cleanup can see inodes with i_size == 0
5422+ * and i_data uninitialized. Skip size checks in
5423+ * that case. This is safe because the first thing
5424+ * ext4_evict_inode() does for fast symlinks is
5425+ * clearing of i_data and i_size.
5426+ */
5427+ if ((EXT4_SB(sb)->s_mount_state & EXT4_ORPHAN_FS)) {
5428+ if (inode->i_nlink != 0) {
5429+ ext4_error_inode(inode, function, line, 0,
5430+ "invalid orphan symlink nlink %d",
5431+ inode->i_nlink);
5432+ ret = -EFSCORRUPTED;
5433+ goto bad_inode;
5434+ }
5435+ } else {
5436+ if (inode->i_size == 0 ||
5437+ inode->i_size >= sizeof(ei->i_data) ||
5438+ strnlen((char *)ei->i_data, inode->i_size + 1) !=
5439+ inode->i_size) {
5440+ ext4_error_inode(inode, function, line, 0,
5441+ "invalid fast symlink length %llu",
5442+ (unsigned long long)inode->i_size);
5443+ ret = -EFSCORRUPTED;
5444+ goto bad_inode;
5445+ }
5446+ inode_set_cached_link(inode, (char *)ei->i_data,
5447+ inode->i_size);
54135448 }
5414− inode_set_cached_link(inode, (char *)ei->i_data,
5415− inode->i_size);
54165449 } else {
54175450 inode->i_op = &ext4_symlink_inode_operations;
54185451 }
@@ -5849,6 +5882,18 @@ int ext4_setattr(struct mnt_idmap *idmap, struct dentry *dentry, · 430 unmodified lines
58495882 if (attr->ia_size == inode->i_size)
58505883 inc_ivers = false;
58515884
5885+ /*
5886+ * If file has inline data but new size exceeds inline capacity,
5887+ * convert to extent-based storage first to prevent inconsistent
5888+ * state (inline flag set but size exceeds inline capacity).
5889+ */
5890+ if (ext4_has_inline_data(inode) &&
5891+ attr->ia_size > EXT4_I(inode)->i_inline_size) {
5892+ error = ext4_convert_inline_data(inode);
5893+ if (error)
5894+ goto err_out;
5895+ }
5896+
58525897 if (shrink) {
58535898 if (ext4_should_order_data(inode)) {
58545899 error = ext4_begin_ordered_truncate(inode,
fs/ext4/mballoc-test.c+41−40
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include <linux/random.h>
99
1010 #include "ext4.h"
11+#include "mballoc.h"
1112
1213 struct mbt_grp_ctx {
1314 struct buffer_head bitmap_bh;
@@ -336,7 +337,7 @@ ext4_mb_mark_context_stub(handle_t *handle, struct super_block *sb, bool state, · 322 unmodified lines
336337 if (state)
337338 mb_set_bits(bitmap_bh->b_data, blkoff, len);
338339 else
339− mb_clear_bits(bitmap_bh->b_data, blkoff, len);
340+ mb_clear_bits_test(bitmap_bh->b_data, blkoff, len);
340341
341342 return 0;
342343 }
@@ -413,14 +414,14 @@ static void test_new_blocks_simple(struct kunit *test) · 70 unmodified lines
413414
414415 /* get block at goal */
415416 ar.goal = ext4_group_first_block_no(sb, goal_group);
416− found = ext4_mb_new_blocks_simple(&ar, &err);
417+ found = ext4_mb_new_blocks_simple_test(&ar, &err);
417418 KUNIT_ASSERT_EQ_MSG(test, ar.goal, found,
418419 "failed to alloc block at goal, expected %llu found %llu",
419420 ar.goal, found);
420421
421422 /* get block after goal in goal group */
422423 ar.goal = ext4_group_first_block_no(sb, goal_group);
423− found = ext4_mb_new_blocks_simple(&ar, &err);
424+ found = ext4_mb_new_blocks_simple_test(&ar, &err);
424425 KUNIT_ASSERT_EQ_MSG(test, ar.goal + EXT4_C2B(sbi, 1), found,
425426 "failed to alloc block after goal in goal group, expected %llu found %llu",
426427 ar.goal + 1, found);
@@ -428,7 +429,7 @@ static void test_new_blocks_simple(struct kunit *test) · 1 unmodified line
428429 /* get block after goal group */
429430 mbt_ctx_mark_used(sb, goal_group, 0, EXT4_CLUSTERS_PER_GROUP(sb));
430431 ar.goal = ext4_group_first_block_no(sb, goal_group);
431− found = ext4_mb_new_blocks_simple(&ar, &err);
432+ found = ext4_mb_new_blocks_simple_test(&ar, &err);
432433 KUNIT_ASSERT_EQ_MSG(test,
433434 ext4_group_first_block_no(sb, goal_group + 1), found,
434435 "failed to alloc block after goal group, expected %llu found %llu",
@@ -438,7 +439,7 @@ static void test_new_blocks_simple(struct kunit *test) · 3 unmodified lines
438439 for (i = goal_group; i < ext4_get_groups_count(sb); i++)
439440 mbt_ctx_mark_used(sb, i, 0, EXT4_CLUSTERS_PER_GROUP(sb));
440441 ar.goal = ext4_group_first_block_no(sb, goal_group);
441− found = ext4_mb_new_blocks_simple(&ar, &err);
442+ found = ext4_mb_new_blocks_simple_test(&ar, &err);
442443 KUNIT_ASSERT_EQ_MSG(test,
443444 ext4_group_first_block_no(sb, 0) + EXT4_C2B(sbi, 1), found,
444445 "failed to alloc block before goal group, expected %llu found %llu",
@@ -448,7 +449,7 @@ static void test_new_blocks_simple(struct kunit *test) · 3 unmodified lines
448449 for (i = 0; i < ext4_get_groups_count(sb); i++)
449450 mbt_ctx_mark_used(sb, i, 0, EXT4_CLUSTERS_PER_GROUP(sb));
450451 ar.goal = ext4_group_first_block_no(sb, goal_group);
451− found = ext4_mb_new_blocks_simple(&ar, &err);
452+ found = ext4_mb_new_blocks_simple_test(&ar, &err);
452453 KUNIT_ASSERT_NE_MSG(test, err, 0,
453454 "unexpectedly get block when no block is available");
454455 }
@@ -492,16 +493,16 @@ validate_free_blocks_simple(struct kunit *test, struct super_block *sb, · 37 unmodified lines
492493 continue;
493494
494495 bitmap = mbt_ctx_bitmap(sb, i);
495− bit = mb_find_next_zero_bit(bitmap, max, 0);
496+ bit = mb_find_next_zero_bit_test(bitmap, max, 0);
496497 KUNIT_ASSERT_EQ_MSG(test, bit, max,
497498 "free block on unexpected group %d", i);
498499 }
499500
500501 bitmap = mbt_ctx_bitmap(sb, goal_group);
501− bit = mb_find_next_zero_bit(bitmap, max, 0);
502+ bit = mb_find_next_zero_bit_test(bitmap, max, 0);
502503 KUNIT_ASSERT_EQ(test, bit, start);
503504
504− bit = mb_find_next_bit(bitmap, max, bit + 1);
505+ bit = mb_find_next_bit_test(bitmap, max, bit + 1);
505506 KUNIT_ASSERT_EQ(test, bit, start + len);
506507 }
507508
@@ -524,7 +525,7 @@ test_free_blocks_simple_range(struct kunit *test, ext4_group_t goal_group, · 16 unmodified lines
524525
525526 block = ext4_group_first_block_no(sb, goal_group) +
526527 EXT4_C2B(sbi, start);
527− ext4_free_blocks_simple(inode, block, len);
528+ ext4_free_blocks_simple_test(inode, block, len);
528529 validate_free_blocks_simple(test, sb, goal_group, start, len);
529530 mbt_ctx_mark_used(sb, goal_group, 0, EXT4_CLUSTERS_PER_GROUP(sb));
530531 }
@@ -566,15 +567,15 @@ test_mark_diskspace_used_range(struct kunit *test, · 35 unmodified lines
566567
567568 bitmap = mbt_ctx_bitmap(sb, TEST_GOAL_GROUP);
568569 memset(bitmap, 0, sb->s_blocksize);
569− ret = ext4_mb_mark_diskspace_used(ac, NULL);
570+ ret = ext4_mb_mark_diskspace_used_test(ac, NULL);
570571 KUNIT_ASSERT_EQ(test, ret, 0);
571572
572573 max = EXT4_CLUSTERS_PER_GROUP(sb);
573− i = mb_find_next_bit(bitmap, max, 0);
574+ i = mb_find_next_bit_test(bitmap, max, 0);
574575 KUNIT_ASSERT_EQ(test, i, start);
575− i = mb_find_next_zero_bit(bitmap, max, i + 1);
576+ i = mb_find_next_zero_bit_test(bitmap, max, i + 1);
576577 KUNIT_ASSERT_EQ(test, i, start + len);
577− i = mb_find_next_bit(bitmap, max, i + 1);
578+ i = mb_find_next_bit_test(bitmap, max, i + 1);
578579 KUNIT_ASSERT_EQ(test, max, i);
579580 }
580581
@@ -617,54 +618,54 @@ static void mbt_generate_buddy(struct super_block *sb, void *buddy, · 36 unmodified lines
617618 max = EXT4_CLUSTERS_PER_GROUP(sb);
618619 bb_h = buddy + sbi->s_mb_offsets[1];
619620
620− off = mb_find_next_zero_bit(bb, max, 0);
621+ off = mb_find_next_zero_bit_test(bb, max, 0);
621622 grp->bb_first_free = off;
622623 while (off < max) {
623624 grp->bb_counters[0]++;
624625 grp->bb_free++;
625626
626− if (!(off & 1) && !mb_test_bit(off + 1, bb)) {
627+ if (!(off & 1) && !mb_test_bit_test(off + 1, bb)) {
627628 grp->bb_free++;
628629 grp->bb_counters[0]--;
629− mb_clear_bit(off >> 1, bb_h);
630+ mb_clear_bit_test(off >> 1, bb_h);
630631 grp->bb_counters[1]++;
631632 grp->bb_largest_free_order = 1;
632633 off++;
633634 }
634635
635− off = mb_find_next_zero_bit(bb, max, off + 1);
636+ off = mb_find_next_zero_bit_test(bb, max, off + 1);
636637 }
637638
638639 for (order = 1; order < MB_NUM_ORDERS(sb) - 1; order++) {
639640 bb = buddy + sbi->s_mb_offsets[order];
640641 bb_h = buddy + sbi->s_mb_offsets[order + 1];
641642 max = max >> 1;
642− off = mb_find_next_zero_bit(bb, max, 0);
643+ off = mb_find_next_zero_bit_test(bb, max, 0);
643644
644645 while (off < max) {
645− if (!(off & 1) && !mb_test_bit(off + 1, bb)) {
646+ if (!(off & 1) && !mb_test_bit_test(off + 1, bb)) {
646647 mb_set_bits(bb, off, 2);
647648 grp->bb_counters[order] -= 2;
648− mb_clear_bit(off >> 1, bb_h);
649+ mb_clear_bit_test(off >> 1, bb_h);
649650 grp->bb_counters[order + 1]++;
650651 grp->bb_largest_free_order = order + 1;
651652 off++;
652653 }
653654
654− off = mb_find_next_zero_bit(bb, max, off + 1);
655+ off = mb_find_next_zero_bit_test(bb, max, off + 1);
655656 }
656657 }
657658
658659 max = EXT4_CLUSTERS_PER_GROUP(sb);
659− off = mb_find_next_zero_bit(bitmap, max, 0);
660+ off = mb_find_next_zero_bit_test(bitmap, max, 0);
660661 while (off < max) {
661662 grp->bb_fragments++;
662663
663− off = mb_find_next_bit(bitmap, max, off + 1);
664+ off = mb_find_next_bit_test(bitmap, max, off + 1);
664665 if (off + 1 >= max)
665666 break;
666667
667− off = mb_find_next_zero_bit(bitmap, max, off + 1);
668+ off = mb_find_next_zero_bit_test(bitmap, max, off + 1);
668669 }
669670 }
670671
@@ -706,7 +707,7 @@ do_test_generate_buddy(struct kunit *test, struct super_block *sb, void *bitmap, · 35 unmodified lines
706707 /* needed by validation in ext4_mb_generate_buddy */
707708 ext4_grp->bb_free = mbt_grp->bb_free;
708709 memset(ext4_buddy, 0xff, sb->s_blocksize);
709− ext4_mb_generate_buddy(sb, ext4_buddy, bitmap, TEST_GOAL_GROUP,
710+ ext4_mb_generate_buddy_test(sb, ext4_buddy, bitmap, TEST_GOAL_GROUP,
710711 ext4_grp);
711712
712713 KUNIT_ASSERT_EQ(test, memcmp(mbt_buddy, ext4_buddy, sb->s_blocksize),
@@ -760,7 +761,7 @@ test_mb_mark_used_range(struct kunit *test, struct ext4_buddy *e4b, · 47 unmodified lines
760761 ex.fe_group = TEST_GOAL_GROUP;
761762
762763 ext4_lock_group(sb, TEST_GOAL_GROUP);
763− mb_mark_used(e4b, &ex);
764+ mb_mark_used_test(e4b, &ex);
764765 ext4_unlock_group(sb, TEST_GOAL_GROUP);
765766
766767 mb_set_bits(bitmap, start, len);
@@ -769,7 +770,7 @@ test_mb_mark_used_range(struct kunit *test, struct ext4_buddy *e4b, · 2 unmodified lines
769770 memset(buddy, 0xff, sb->s_blocksize);
770771 for (i = 0; i < MB_NUM_ORDERS(sb); i++)
771772 grp->bb_counters[i] = 0;
772− ext4_mb_generate_buddy(sb, buddy, bitmap, 0, grp);
773+ ext4_mb_generate_buddy_test(sb, buddy, bitmap, 0, grp);
773774
774775 KUNIT_ASSERT_EQ(test, memcmp(buddy, e4b->bd_buddy, sb->s_blocksize),
775776 0);
@@ -798,7 +799,7 @@ static void test_mb_mark_used(struct kunit *test) · 22 unmodified lines
798799 bb_counters[MB_NUM_ORDERS(sb)]), GFP_KERNEL);
799800 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, grp);
800801
801− ret = ext4_mb_load_buddy(sb, TEST_GOAL_GROUP, &e4b);
802+ ret = ext4_mb_load_buddy_test(sb, TEST_GOAL_GROUP, &e4b);
802803 KUNIT_ASSERT_EQ(test, ret, 0);
803804
804805 grp->bb_free = EXT4_CLUSTERS_PER_GROUP(sb);
@@ -809,7 +810,7 @@ static void test_mb_mark_used(struct kunit *test) · 4 unmodified lines
809810 test_mb_mark_used_range(test, &e4b, ranges[i].start,
810811 ranges[i].len, bitmap, buddy, grp);
811812
812− ext4_mb_unload_buddy(&e4b);
813+ ext4_mb_unload_buddy_test(&e4b);
813814 }
814815
815816 static void
@@ -825,16 +826,16 @@ test_mb_free_blocks_range(struct kunit *test, struct ext4_buddy *e4b, · 9 unmodified lines
825826 return;
826827
827828 ext4_lock_group(sb, e4b->bd_group);
828− mb_free_blocks(NULL, e4b, start, len);
829+ mb_free_blocks_test(NULL, e4b, start, len);
829830 ext4_unlock_group(sb, e4b->bd_group);
830831
831− mb_clear_bits(bitmap, start, len);
832+ mb_clear_bits_test(bitmap, start, len);
832833 /* bypass bb_free validatoin in ext4_mb_generate_buddy */
833834 grp->bb_free += len;
834835 memset(buddy, 0xff, sb->s_blocksize);
835836 for (i = 0; i < MB_NUM_ORDERS(sb); i++)
836837 grp->bb_counters[i] = 0;
837− ext4_mb_generate_buddy(sb, buddy, bitmap, 0, grp);
838+ ext4_mb_generate_buddy_test(sb, buddy, bitmap, 0, grp);
838839
839840 KUNIT_ASSERT_EQ(test, memcmp(buddy, e4b->bd_buddy, sb->s_blocksize),
840841 0);
@@ -865,7 +866,7 @@ static void test_mb_free_blocks(struct kunit *test) · 24 unmodified lines
865866 bb_counters[MB_NUM_ORDERS(sb)]), GFP_KERNEL);
866867 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, grp);
867868
868− ret = ext4_mb_load_buddy(sb, TEST_GOAL_GROUP, &e4b);
869+ ret = ext4_mb_load_buddy_test(sb, TEST_GOAL_GROUP, &e4b);
869870 KUNIT_ASSERT_EQ(test, ret, 0);
870871
871872 ex.fe_start = 0;
@@ -873,7 +874,7 @@ static void test_mb_free_blocks(struct kunit *test) · 1 unmodified line
873874 ex.fe_group = TEST_GOAL_GROUP;
874875
875876 ext4_lock_group(sb, TEST_GOAL_GROUP);
876− mb_mark_used(&e4b, &ex);
877+ mb_mark_used_test(&e4b, &ex);
877878 ext4_unlock_group(sb, TEST_GOAL_GROUP);
878879
879880 grp->bb_free = 0;
@@ -886,7 +887,7 @@ static void test_mb_free_blocks(struct kunit *test) · 6 unmodified lines
886887 test_mb_free_blocks_range(test, &e4b, ranges[i].start,
887888 ranges[i].len, bitmap, buddy, grp);
888889
889− ext4_mb_unload_buddy(&e4b);
890+ ext4_mb_unload_buddy_test(&e4b);
890891 }
891892
892893 #define COUNT_FOR_ESTIMATE 100000
@@ -904,7 +905,7 @@ static void test_mb_mark_used_cost(struct kunit *test) · 11 unmodified lines
904905 if (sb->s_blocksize > PAGE_SIZE)
905906 kunit_skip(test, "blocksize exceeds pagesize");
906907
907− ret = ext4_mb_load_buddy(sb, TEST_GOAL_GROUP, &e4b);
908+ ret = ext4_mb_load_buddy_test(sb, TEST_GOAL_GROUP, &e4b);
908909 KUNIT_ASSERT_EQ(test, ret, 0);
909910
910911 ex.fe_group = TEST_GOAL_GROUP;
@@ -918,7 +919,7 @@ static void test_mb_mark_used_cost(struct kunit *test) · 7 unmodified lines
918919 ex.fe_start = ranges[i].start;
919920 ex.fe_len = ranges[i].len;
920921 ext4_lock_group(sb, TEST_GOAL_GROUP);
921− mb_mark_used(&e4b, &ex);
922+ mb_mark_used_test(&e4b, &ex);
922923 ext4_unlock_group(sb, TEST_GOAL_GROUP);
923924 }
924925 end = jiffies;
@@ -929,14 +930,14 @@ static void test_mb_mark_used_cost(struct kunit *test) · 4 unmodified lines
929930 continue;
930931
931932 ext4_lock_group(sb, TEST_GOAL_GROUP);
932− mb_free_blocks(NULL, &e4b, ranges[i].start,
933+ mb_free_blocks_test(NULL, &e4b, ranges[i].start,
933934 ranges[i].len);
934935 ext4_unlock_group(sb, TEST_GOAL_GROUP);
935936 }
936937 }
937938
938939 kunit_info(test, "costed jiffies %lu\n", all);
939− ext4_mb_unload_buddy(&e4b);
940+ ext4_mb_unload_buddy_test(&e4b);
940941 }
941942
942943 static const struct mbt_ext4_block_layout mbt_test_layouts[] = {
fs/ext4/mballoc.c+114−18
@@ -1199,6 +1199,8 @@ static int ext4_mb_scan_groups(struct ext4_allocation_context *ac) · 1198 unmodified lines
11991199
12001200 /* searching for the right group start from the goal value specified */
12011201 start = ac->ac_g_ex.fe_group;
1202+ if (start >= ngroups)
1203+ start = 0;
12021204 ac->ac_prefetch_grp = start;
12031205 ac->ac_prefetch_nr = 0;
12041206
@@ -2443,8 +2445,12 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, · 1238 unmodified lines
24432445 return 0;
24442446
24452447 err = ext4_mb_load_buddy(ac->ac_sb, group, e4b);
2446− if (err)
2448+ if (err) {
2449+ if (EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info) &&
2450+ !(ac->ac_flags & EXT4_MB_HINT_GOAL_ONLY))
2451+ return 0;
24472452 return err;
2453+ }
24482454
24492455 ext4_lock_group(ac->ac_sb, group);
24502456 if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info)))
@@ -3580,9 +3586,7 @@ err_freebuddy: · 1129 unmodified lines
35803586 rcu_read_unlock();
35813587 iput(sbi->s_buddy_cache);
35823588 err_freesgi:
3583− rcu_read_lock();
3584− kvfree(rcu_dereference(sbi->s_group_info));
3585− rcu_read_unlock();
3589+ kvfree(rcu_access_pointer(sbi->s_group_info));
35863590 return -ENOMEM;
35873591 }
35883592
@@ -3889,15 +3893,14 @@ void ext4_mb_release(struct super_block *sb) · 300 unmodified lines
38893893 struct kmem_cache *cachep = get_groupinfo_cache(sb->s_blocksize_bits);
38903894 int count;
38913895
3892− if (test_opt(sb, DISCARD)) {
3893− /*
3894− * wait the discard work to drain all of ext4_free_data
3895− */
3896− flush_work(&sbi->s_discard_work);
3897− WARN_ON_ONCE(!list_empty(&sbi->s_discard_list));
3898− }
3896+ /*
3897+ * wait the discard work to drain all of ext4_free_data
3898+ */
3899+ flush_work(&sbi->s_discard_work);
3900+ WARN_ON_ONCE(!list_empty(&sbi->s_discard_list));
38993901
3900− if (sbi->s_group_info) {
3902+ group_info = rcu_access_pointer(sbi->s_group_info);
3903+ if (group_info) {
39013904 for (i = 0; i < ngroups; i++) {
39023905 cond_resched();
39033906 grinfo = ext4_get_group_info(sb, i);
@@ -3915,12 +3918,9 @@ void ext4_mb_release(struct super_block *sb) · 11 unmodified lines
39153918 num_meta_group_infos = (ngroups +
39163919 EXT4_DESC_PER_BLOCK(sb) - 1) >>
39173920 EXT4_DESC_PER_BLOCK_BITS(sb);
3918− rcu_read_lock();
3919− group_info = rcu_dereference(sbi->s_group_info);
39203921 for (i = 0; i < num_meta_group_infos; i++)
39213922 kfree(group_info[i]);
39223923 kvfree(group_info);
3923− rcu_read_unlock();
39243924 }
39253925 ext4_mb_avg_fragment_size_destroy(sbi);
39263926 ext4_mb_largest_free_orders_destroy(sbi);
@@ -4084,7 +4084,7 @@ void ext4_exit_mballoc(void) · 157 unmodified lines
40844084
40854085 #define EXT4_MB_BITMAP_MARKED_CHECK 0x0001
40864086 #define EXT4_MB_SYNC_UPDATE 0x0002
4087−static int
4087+int
40884088 ext4_mb_mark_context(handle_t *handle, struct super_block *sb, bool state,
40894089 ext4_group_t group, ext4_grpblk_t blkoff,
40904090 ext4_grpblk_t len, int flags, ext4_grpblk_t *ret_changed)
@@ -7188,6 +7188,102 @@ out_unload: · 3097 unmodified lines
71887188 return error;
71897189 }
71907190
7191−#ifdef CONFIG_EXT4_KUNIT_TESTS
7192−#include "mballoc-test.c"
7191+#if IS_ENABLED(CONFIG_EXT4_KUNIT_TESTS)
7192+void mb_clear_bits_test(void *bm, int cur, int len)
7193+{
7194+ mb_clear_bits(bm, cur, len);
7195+}
7196+EXPORT_SYMBOL_FOR_EXT4_TEST(mb_clear_bits_test);
7197+
7198+ext4_fsblk_t
7199+ext4_mb_new_blocks_simple_test(struct ext4_allocation_request *ar,
7200+ int *errp)
7201+{
7202+ return ext4_mb_new_blocks_simple(ar, errp);
7203+}
7204+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_mb_new_blocks_simple_test);
7205+
7206+int mb_find_next_zero_bit_test(void *addr, int max, int start)
7207+{
7208+ return mb_find_next_zero_bit(addr, max, start);
7209+}
7210+EXPORT_SYMBOL_FOR_EXT4_TEST(mb_find_next_zero_bit_test);
7211+
7212+int mb_find_next_bit_test(void *addr, int max, int start)
7213+{
7214+ return mb_find_next_bit(addr, max, start);
7215+}
7216+EXPORT_SYMBOL_FOR_EXT4_TEST(mb_find_next_bit_test);
7217+
7218+void mb_clear_bit_test(int bit, void *addr)
7219+{
7220+ mb_clear_bit(bit, addr);
7221+}
7222+EXPORT_SYMBOL_FOR_EXT4_TEST(mb_clear_bit_test);
7223+
7224+int mb_test_bit_test(int bit, void *addr)
7225+{
7226+ return mb_test_bit(bit, addr);
7227+}
7228+EXPORT_SYMBOL_FOR_EXT4_TEST(mb_test_bit_test);
7229+
7230+int ext4_mb_mark_diskspace_used_test(struct ext4_allocation_context *ac,
7231+ handle_t *handle)
7232+{
7233+ return ext4_mb_mark_diskspace_used(ac, handle);
7234+}
7235+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_mb_mark_diskspace_used_test);
7236+
7237+int mb_mark_used_test(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
7238+{
7239+ return mb_mark_used(e4b, ex);
7240+}
7241+EXPORT_SYMBOL_FOR_EXT4_TEST(mb_mark_used_test);
7242+
7243+void ext4_mb_generate_buddy_test(struct super_block *sb, void *buddy,
7244+ void *bitmap, ext4_group_t group,
7245+ struct ext4_group_info *grp)
7246+{
7247+ ext4_mb_generate_buddy(sb, buddy, bitmap, group, grp);
7248+}
7249+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_mb_generate_buddy_test);
7250+
7251+int ext4_mb_load_buddy_test(struct super_block *sb, ext4_group_t group,
7252+ struct ext4_buddy *e4b)
7253+{
7254+ return ext4_mb_load_buddy(sb, group, e4b);
7255+}
7256+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_mb_load_buddy_test);
7257+
7258+void ext4_mb_unload_buddy_test(struct ext4_buddy *e4b)
7259+{
7260+ ext4_mb_unload_buddy(e4b);
7261+}
7262+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_mb_unload_buddy_test);
7263+
7264+void mb_free_blocks_test(struct inode *inode, struct ext4_buddy *e4b,
7265+ int first, int count)
7266+{
7267+ mb_free_blocks(inode, e4b, first, count);
7268+}
7269+EXPORT_SYMBOL_FOR_EXT4_TEST(mb_free_blocks_test);
7270+
7271+void ext4_free_blocks_simple_test(struct inode *inode, ext4_fsblk_t block,
7272+ unsigned long count)
7273+{
7274+ return ext4_free_blocks_simple(inode, block, count);
7275+}
7276+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_free_blocks_simple_test);
7277+
7278+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_wait_block_bitmap);
7279+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_mb_init);
7280+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_get_group_desc);
7281+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_count_free_clusters);
7282+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_get_group_info);
7283+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_free_group_clusters_set);
7284+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_mb_release);
7285+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_read_block_bitmap_nowait);
7286+EXPORT_SYMBOL_FOR_EXT4_TEST(mb_set_bits);
7287+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_fc_init_inode);
7288+EXPORT_SYMBOL_FOR_EXT4_TEST(ext4_mb_mark_context);
71937289 #endif
fs/ext4/mballoc.h+30−0
@@ -270,4 +270,34 @@ ext4_mballoc_query_range( · 269 unmodified lines
270270 ext4_mballoc_query_range_fn formatter,
271271 void *priv);
272272
273+extern int ext4_mb_mark_context(handle_t *handle,
274+ struct super_block *sb, bool state,
275+ ext4_group_t group, ext4_grpblk_t blkoff,
276+ ext4_grpblk_t len, int flags,
277+ ext4_grpblk_t *ret_changed);
278+#if IS_ENABLED(CONFIG_EXT4_KUNIT_TESTS)
279+extern void mb_clear_bits_test(void *bm, int cur, int len);
280+extern ext4_fsblk_t
281+ext4_mb_new_blocks_simple_test(struct ext4_allocation_request *ar,
282+ int *errp);
283+extern int mb_find_next_zero_bit_test(void *addr, int max, int start);
284+extern int mb_find_next_bit_test(void *addr, int max, int start);
285+extern void mb_clear_bit_test(int bit, void *addr);
286+extern int mb_test_bit_test(int bit, void *addr);
287+extern int
288+ext4_mb_mark_diskspace_used_test(struct ext4_allocation_context *ac,
289+ handle_t *handle);
290+extern int mb_mark_used_test(struct ext4_buddy *e4b,
291+ struct ext4_free_extent *ex);
292+extern void ext4_mb_generate_buddy_test(struct super_block *sb,
293+ void *buddy, void *bitmap, ext4_group_t group,
294+ struct ext4_group_info *grp);
295+extern int ext4_mb_load_buddy_test(struct super_block *sb,
296+ ext4_group_t group, struct ext4_buddy *e4b);
297+extern void ext4_mb_unload_buddy_test(struct ext4_buddy *e4b);
298+extern void mb_free_blocks_test(struct inode *inode,
299+ struct ext4_buddy *e4b, int first, int count);
300+extern void ext4_free_blocks_simple_test(struct inode *inode,
301+ ext4_fsblk_t block, unsigned long count);
302+#endif
273303 #endif
fs/ext4/page-io.c+8−2
@@ -524,9 +524,15 @@ int ext4_bio_write_folio(struct ext4_io_submit *io, struct folio *folio, · 523 unmodified lines
524524 nr_to_submit++;
525525 } while ((bh = bh->b_this_page) != head);
526526
527− /* Nothing to submit? Just unlock the folio... */
528− if (!nr_to_submit)
527+ if (!nr_to_submit) {
528+ /*
529+ * We have nothing to submit. Just cycle the folio through
530+ * writeback state to properly update xarray tags.
531+ */
532+ __folio_start_writeback(folio, keep_towrite);
533+ folio_end_writeback(folio);
529534 return 0;
535+ }
530536
531537 bh = head = folio_buffers(folio);
532538
fs/ext4/super.c+31−6
@@ -1254,12 +1254,10 @@ static void ext4_group_desc_free(struct ext4_sb_info *sbi) · 1253 unmodified lines
12541254 struct buffer_head **group_desc;
12551255 int i;
12561256
1257− rcu_read_lock();
1258− group_desc = rcu_dereference(sbi->s_group_desc);
1257+ group_desc = rcu_access_pointer(sbi->s_group_desc);
12591258 for (i = 0; i < sbi->s_gdb_count; i++)
12601259 brelse(group_desc[i]);
12611260 kvfree(group_desc);
1262− rcu_read_unlock();
12631261 }
12641262
12651263 static void ext4_flex_groups_free(struct ext4_sb_info *sbi)
@@ -1267,14 +1265,12 @@ static void ext4_flex_groups_free(struct ext4_sb_info *sbi) · 1 unmodified line
12671265 struct flex_groups **flex_groups;
12681266 int i;
12691267
1270− rcu_read_lock();
1271− flex_groups = rcu_dereference(sbi->s_flex_groups);
1268+ flex_groups = rcu_access_pointer(sbi->s_flex_groups);
12721269 if (flex_groups) {
12731270 for (i = 0; i < sbi->s_flex_groups_allocated; i++)
12741271 kvfree(flex_groups[i]);
12751272 kvfree(flex_groups);
12761273 }
1277− rcu_read_unlock();
12781274 }
12791275
12801276 static void ext4_put_super(struct super_block *sb)
@@ -1527,6 +1523,27 @@ void ext4_clear_inode(struct inode *inode) · 246 unmodified lines
15271523 invalidate_inode_buffers(inode);
15281524 clear_inode(inode);
15291525 ext4_discard_preallocations(inode);
1526+ /*
1527+ * We must remove the inode from the hash before ext4_free_inode()
1528+ * clears the bit in inode bitmap as otherwise another process reusing
1529+ * the inode will block in insert_inode_hash() waiting for inode
1530+ * eviction to complete while holding transaction handle open, but
1531+ * ext4_evict_inode() still running for that inode could block waiting
1532+ * for transaction commit if the inode is marked as IS_SYNC => deadlock.
1533+ *
1534+ * Removing the inode from the hash here is safe. There are two cases
1535+ * to consider:
1536+ * 1) The inode still has references to it (i_nlink > 0). In that case
1537+ * we are keeping the inode and once we remove the inode from the hash,
1538+ * iget() can create the new inode structure for the same inode number
1539+ * and we are fine with that as all IO on behalf of the inode is
1540+ * finished.
1541+ * 2) We are deleting the inode (i_nlink == 0). In that case inode
1542+ * number cannot be reused until ext4_free_inode() clears the bit in
1543+ * the inode bitmap, at which point all IO is done and reuse is fine
1544+ * again.
1545+ */
1546+ remove_inode_hash(inode);
15301547 ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS);
15311548 dquot_drop(inode);
15321549 if (EXT4_I(inode)->jinode) {
@@ -3633,6 +3650,13 @@ int ext4_feature_set_ok(struct super_block *sb, int readonly) · 2100 unmodified lines
36333650 "extents feature\n");
36343651 return 0;
36353652 }
3653+ if (ext4_has_feature_bigalloc(sb) &&
3654+ le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) {
3655+ ext4_msg(sb, KERN_WARNING,
3656+ "bad geometry: bigalloc file system with non-zero "
3657+ "first_data_block\n");
3658+ return 0;
3659+ }
36363660
36373661 #if !IS_ENABLED(CONFIG_QUOTA) || !IS_ENABLED(CONFIG_QFMT_V2)
36383662 if (!readonly && (ext4_has_feature_quota(sb) ||
@@ -5403,6 +5427,7 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb) · 1764 unmodified lines
54035427
54045428 timer_setup(&sbi->s_err_report, print_daily_error_info, 0);
54055429 spin_lock_init(&sbi->s_error_lock);
5430+ mutex_init(&sbi->s_error_notify_mutex);
54065431 INIT_WORK(&sbi->s_sb_upd_work, update_super_work);
54075432
54085433 err = ext4_group_desc_init(sb, es, logical_sb_block, &first_not_zeroed);
fs/ext4/sysfs.c+9−1
@@ -597,7 +597,10 @@ static const struct kobj_type ext4_feat_ktype = { · 596 unmodified lines
597597
598598 void ext4_notify_error_sysfs(struct ext4_sb_info *sbi)
599599 {
600− sysfs_notify(&sbi->s_kobj, NULL, "errors_count");
600+ mutex_lock(&sbi->s_error_notify_mutex);
601+ if (sbi->s_kobj.state_in_sysfs)
602+ sysfs_notify(&sbi->s_kobj, NULL, "errors_count");
603+ mutex_unlock(&sbi->s_error_notify_mutex);
601604 }
602605
603606 static struct kobject *ext4_root;
@@ -610,8 +613,10 @@ int ext4_register_sysfs(struct super_block *sb) · 6 unmodified lines
610613 int err;
611614
612615 init_completion(&sbi->s_kobj_unregister);
616+ mutex_lock(&sbi->s_error_notify_mutex);
613617 err = kobject_init_and_add(&sbi->s_kobj, &ext4_sb_ktype, ext4_root,
614618 "%s", sb->s_id);
619+ mutex_unlock(&sbi->s_error_notify_mutex);
615620 if (err) {
616621 kobject_put(&sbi->s_kobj);
617622 wait_for_completion(&sbi->s_kobj_unregister);
@@ -644,7 +649,10 @@ void ext4_unregister_sysfs(struct super_block *sb) · 26 unmodified lines
644649
645650 if (sbi->s_proc)
646651 remove_proc_subtree(sb->s_id, ext4_proc_root);
652+
653+ mutex_lock(&sbi->s_error_notify_mutex);
647654 kobject_del(&sbi->s_kobj);
655+ mutex_unlock(&sbi->s_error_notify_mutex);
648656 }
649657
650658 int __init ext4_init_sysfs(void)
fs/jbd2/checkpoint.c+13−2
@@ -267,7 +267,15 @@ restart: · 266 unmodified lines
267267 */
268268 BUFFER_TRACE(bh, "queue");
269269 get_bh(bh);
270− J_ASSERT_BH(bh, !buffer_jwrite(bh));
270+ if (WARN_ON_ONCE(buffer_jwrite(bh))) {
271+ put_bh(bh); /* drop the ref we just took */
272+ spin_unlock(&journal->j_list_lock);
273+ /* Clean up any previously batched buffers */
274+ if (batch_count)
275+ __flush_batch(journal, &batch_count);
276+ jbd2_journal_abort(journal, -EFSCORRUPTED);
277+ return -EFSCORRUPTED;
278+ }
271279 journal->j_chkpt_bhs[batch_count++] = bh;
272280 transaction->t_chp_stats.cs_written++;
273281 transaction->t_checkpoint_list = jh->b_cpnext;
@@ -325,7 +333,10 @@ int jbd2_cleanup_journal_tail(journal_t *journal) · 51 unmodified lines
325333
326334 if (!jbd2_journal_get_log_tail(journal, &first_tid, &blocknr))
327335 return 1;
328− J_ASSERT(blocknr != 0);
336+ if (WARN_ON_ONCE(blocknr == 0)) {
337+ jbd2_journal_abort(journal, -EFSCORRUPTED);
338+ return -EFSCORRUPTED;
339+ }
329340
330341 /*
331342 * We need to make sure that any blocks that were recently written out

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t