Pull ext4 fixes from Ted Ts'o: "Regression and bug fixes for ext4" * tag 'ext4_for_linus-6.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: fix rec_len verify error ext4: do not let fstrim block system suspend ext4: move setting of trimmed bit into ext4_try_to_trim_range() jbd2: Fix memory leak in journal_init_common() jbd2: Remove page size assumptions buffer: Make bh_offset() work for compound pages
Unified · Split
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/slab.h> |
| 17 | 17 | #include <linux/nospec.h> |
| 18 | 18 | #include <linux/backing-dev.h> |
| 19 | +#include <linux/freezer.h> | |
| 19 | 20 | #include <trace/events/ext4.h> |
| 20 | 21 | |
| 21 | 22 | /* |
| @@ -6906,6 +6907,21 @@ __acquires(bitlock) · 6884 unmodified lines | ||
| 6906 | 6907 | return ret; |
| 6907 | 6908 | } |
| 6908 | 6909 | |
| 6910 | +static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb, | |
| 6911 | + ext4_group_t grp) | |
| 6912 | +{ | |
| 6913 | + if (grp < ext4_get_groups_count(sb)) | |
| 6914 | + return EXT4_CLUSTERS_PER_GROUP(sb) - 1; | |
| 6915 | + return (ext4_blocks_count(EXT4_SB(sb)->s_es) - | |
| 6916 | + ext4_group_first_block_no(sb, grp) - 1) >> | |
| 6917 | + EXT4_CLUSTER_BITS(sb); | |
| 6918 | +} | |
| 6919 | + | |
| 6920 | +static bool ext4_trim_interrupted(void) | |
| 6921 | +{ | |
| 6922 | + return fatal_signal_pending(current) || freezing(current); | |
| 6923 | +} | |
| 6924 | + | |
| 6909 | 6925 | static int ext4_try_to_trim_range(struct super_block *sb, |
| 6910 | 6926 | struct ext4_buddy *e4b, ext4_grpblk_t start, |
| 6911 | 6927 | ext4_grpblk_t max, ext4_grpblk_t minblocks) |
| @@ -6913,9 +6929,12 @@ __acquires(ext4_group_lock_ptr(sb, e4b->bd_group)) · 1 unmodified line | ||
| 6913 | 6929 | __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) |
| 6914 | 6930 | { |
| 6915 | 6931 | ext4_grpblk_t next, count, free_count; |
| 6932 | + bool set_trimmed = false; | |
| 6916 | 6933 | void *bitmap; |
| 6917 | 6934 | |
| 6918 | 6935 | bitmap = e4b->bd_bitmap; |
| 6936 | + if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group)) | |
| 6937 | + set_trimmed = true; | |
| 6919 | 6938 | start = max(e4b->bd_info->bb_first_free, start); |
| 6920 | 6939 | count = 0; |
| 6921 | 6940 | free_count = 0; |
| @@ -6930,16 +6949,14 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) · 8 unmodified lines | ||
| 6930 | 6949 | int ret = ext4_trim_extent(sb, start, next - start, e4b); |
| 6931 | 6950 | |
| 6932 | 6951 | if (ret && ret != -EOPNOTSUPP) |
| 6933 | − break; | |
| 6952 | + return count; | |
| 6934 | 6953 | count += next - start; |
| 6935 | 6954 | } |
| 6936 | 6955 | free_count += next - start; |
| 6937 | 6956 | start = next + 1; |
| 6938 | 6957 | |
| 6939 | − if (fatal_signal_pending(current)) { | |
| 6940 | − count = -ERESTARTSYS; | |
| 6941 | − break; | |
| 6942 | − } | |
| 6958 | + if (ext4_trim_interrupted()) | |
| 6959 | + return count; | |
| 6943 | 6960 | |
| 6944 | 6961 | if (need_resched()) { |
| 6945 | 6962 | ext4_unlock_group(sb, e4b->bd_group); |
| @@ -6951,6 +6968,9 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) · 5 unmodified lines | ||
| 6951 | 6968 | break; |
| 6952 | 6969 | } |
| 6953 | 6970 | |
| 6971 | + if (set_trimmed) | |
| 6972 | + EXT4_MB_GRP_SET_TRIMMED(e4b->bd_info); | |
| 6973 | + | |
| 6954 | 6974 | return count; |
| 6955 | 6975 | } |
| 6956 | 6976 | |
| @@ -6961,7 +6981,6 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) · 4 unmodified lines | ||
| 6961 | 6981 | * @start: first group block to examine |
| 6962 | 6982 | * @max: last group block to examine |
| 6963 | 6983 | * @minblocks: minimum extent block count |
| 6964 | − * @set_trimmed: set the trimmed flag if at least one block is trimmed | |
| 6965 | 6984 | * |
| 6966 | 6985 | * ext4_trim_all_free walks through group's block bitmap searching for free |
| 6967 | 6986 | * extents. When the free extent is found, mark it as used in group buddy |
| @@ -6971,7 +6990,7 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) · 3 unmodified lines | ||
| 6971 | 6990 | static ext4_grpblk_t |
| 6972 | 6991 | ext4_trim_all_free(struct super_block *sb, ext4_group_t group, |
| 6973 | 6992 | ext4_grpblk_t start, ext4_grpblk_t max, |
| 6974 | − ext4_grpblk_t minblocks, bool set_trimmed) | |
| 6993 | + ext4_grpblk_t minblocks) | |
| 6975 | 6994 | { |
| 6976 | 6995 | struct ext4_buddy e4b; |
| 6977 | 6996 | int ret; |
| @@ -6988,13 +7007,10 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, · 10 unmodified lines | ||
| 6988 | 7007 | ext4_lock_group(sb, group); |
| 6989 | 7008 | |
| 6990 | 7009 | if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) || |
| 6991 | − minblocks < EXT4_SB(sb)->s_last_trim_minblks) { | |
| 7010 | + minblocks < EXT4_SB(sb)->s_last_trim_minblks) | |
| 6992 | 7011 | ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks); |
| 6993 | − if (ret >= 0 && set_trimmed) | |
| 6994 | − EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info); | |
| 6995 | − } else { | |
| 7012 | + else | |
| 6996 | 7013 | ret = 0; |
| 6997 | − } | |
| 6998 | 7014 | |
| 6999 | 7015 | ext4_unlock_group(sb, group); |
| 7000 | 7016 | ext4_mb_unload_buddy(&e4b); |
| @@ -7027,7 +7043,6 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) · 26 unmodified lines | ||
| 7027 | 7043 | ext4_fsblk_t first_data_blk = |
| 7028 | 7044 | le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); |
| 7029 | 7045 | ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es); |
| 7030 | − bool whole_group, eof = false; | |
| 7031 | 7046 | int ret = 0; |
| 7032 | 7047 | |
| 7033 | 7048 | start = range->start >> sb->s_blocksize_bits; |
| @@ -7046,10 +7061,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) · 12 unmodified lines | ||
| 7046 | 7061 | if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) |
| 7047 | 7062 | goto out; |
| 7048 | 7063 | } |
| 7049 | − if (end >= max_blks - 1) { | |
| 7064 | + if (end >= max_blks - 1) | |
| 7050 | 7065 | end = max_blks - 1; |
| 7051 | − eof = true; | |
| 7052 | − } | |
| 7053 | 7066 | if (end <= first_data_blk) |
| 7054 | 7067 | goto out; |
| 7055 | 7068 | if (start < first_data_blk) |
| @@ -7063,9 +7076,10 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) · 7 unmodified lines | ||
| 7063 | 7076 | |
| 7064 | 7077 | /* end now represents the last cluster to discard in this group */ |
| 7065 | 7078 | end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; |
| 7066 | − whole_group = true; | |
| 7067 | 7079 | |
| 7068 | 7080 | for (group = first_group; group <= last_group; group++) { |
| 7081 | + if (ext4_trim_interrupted()) | |
| 7082 | + break; | |
| 7069 | 7083 | grp = ext4_get_group_info(sb, group); |
| 7070 | 7084 | if (!grp) |
| 7071 | 7085 | continue; |
| @@ -7082,13 +7096,11 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) · 10 unmodified lines | ||
| 7082 | 7096 | * change it for the last group, note that last_cluster is |
| 7083 | 7097 | * already computed earlier by ext4_get_group_no_and_offset() |
| 7084 | 7098 | */ |
| 7085 | − if (group == last_group) { | |
| 7099 | + if (group == last_group) | |
| 7086 | 7100 | end = last_cluster; |
| 7087 | − whole_group = eof ? true : end == EXT4_CLUSTERS_PER_GROUP(sb) - 1; | |
| 7088 | − } | |
| 7089 | 7101 | if (grp->bb_free >= minlen) { |
| 7090 | 7102 | cnt = ext4_trim_all_free(sb, group, first_cluster, |
| 7091 | − end, minlen, whole_group); | |
| 7103 | + end, minlen); | |
| 7092 | 7104 | if (cnt < 0) { |
| 7093 | 7105 | ret = cnt; |
| 7094 | 7106 | break; |
| @@ -343,17 +343,17 @@ static struct ext4_dir_entry_tail *get_dirent_tail(struct inode *inode, · 342 unmodified lines | ||
| 343 | 343 | struct buffer_head *bh) |
| 344 | 344 | { |
| 345 | 345 | struct ext4_dir_entry_tail *t; |
| 346 | + int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); | |
| 346 | 347 | |
| 347 | 348 | #ifdef PARANOID |
| 348 | 349 | struct ext4_dir_entry *d, *top; |
| 349 | 350 | |
| 350 | 351 | d = (struct ext4_dir_entry *)bh->b_data; |
| 351 | 352 | top = (struct ext4_dir_entry *)(bh->b_data + |
| 352 | − (EXT4_BLOCK_SIZE(inode->i_sb) - | |
| 353 | − sizeof(struct ext4_dir_entry_tail))); | |
| 354 | − while (d < top && d->rec_len) | |
| 353 | + (blocksize - sizeof(struct ext4_dir_entry_tail))); | |
| 354 | + while (d < top && ext4_rec_len_from_disk(d->rec_len, blocksize)) | |
| 355 | 355 | d = (struct ext4_dir_entry *)(((void *)d) + |
| 356 | − le16_to_cpu(d->rec_len)); | |
| 356 | + ext4_rec_len_from_disk(d->rec_len, blocksize)); | |
| 357 | 357 | |
| 358 | 358 | if (d != top) |
| 359 | 359 | return NULL; |
| @@ -364,7 +364,8 @@ static struct ext4_dir_entry_tail *get_dirent_tail(struct inode *inode, · 4 unmodified lines | ||
| 364 | 364 | #endif |
| 365 | 365 | |
| 366 | 366 | if (t->det_reserved_zero1 || |
| 367 | − le16_to_cpu(t->det_rec_len) != sizeof(struct ext4_dir_entry_tail) || | |
| 367 | + (ext4_rec_len_from_disk(t->det_rec_len, blocksize) != | |
| 368 | + sizeof(struct ext4_dir_entry_tail)) || | |
| 368 | 369 | t->det_reserved_zero2 || |
| 369 | 370 | t->det_reserved_ft != EXT4_FT_DIR_CSUM) |
| 370 | 371 | return NULL; |
| @@ -445,13 +446,14 @@ static struct dx_countlimit *get_dx_countlimit(struct inode *inode, · 74 unmodified lines | ||
| 445 | 446 | struct ext4_dir_entry *dp; |
| 446 | 447 | struct dx_root_info *root; |
| 447 | 448 | int count_offset; |
| 449 | + int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); | |
| 450 | + unsigned int rlen = ext4_rec_len_from_disk(dirent->rec_len, blocksize); | |
| 448 | 451 | |
| 449 | − if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb)) | |
| 452 | + if (rlen == blocksize) | |
| 450 | 453 | count_offset = 8; |
| 451 | − else if (le16_to_cpu(dirent->rec_len) == 12) { | |
| 454 | + else if (rlen == 12) { | |
| 452 | 455 | dp = (struct ext4_dir_entry *)(((void *)dirent) + 12); |
| 453 | − if (le16_to_cpu(dp->rec_len) != | |
| 454 | − EXT4_BLOCK_SIZE(inode->i_sb) - 12) | |
| 456 | + if (ext4_rec_len_from_disk(dp->rec_len, blocksize) != blocksize - 12) | |
| 455 | 457 | return NULL; |
| 456 | 458 | root = (struct dx_root_info *)(((void *)dp + 12)); |
| 457 | 459 | if (root->reserved_zero || |
| @@ -1315,6 +1317,7 @@ static int dx_make_map(struct inode *dir, struct buffer_head *bh, · 857 unmodified lines | ||
| 1315 | 1317 | unsigned int buflen = bh->b_size; |
| 1316 | 1318 | char *base = bh->b_data; |
| 1317 | 1319 | struct dx_hash_info h = *hinfo; |
| 1320 | + int blocksize = EXT4_BLOCK_SIZE(dir->i_sb); | |
| 1318 | 1321 | |
| 1319 | 1322 | if (ext4_has_metadata_csum(dir->i_sb)) |
| 1320 | 1323 | buflen -= sizeof(struct ext4_dir_entry_tail); |
| @@ -1335,11 +1338,12 @@ static int dx_make_map(struct inode *dir, struct buffer_head *bh, · 14 unmodified lines | ||
| 1335 | 1338 | map_tail--; |
| 1336 | 1339 | map_tail->hash = h.hash; |
| 1337 | 1340 | map_tail->offs = ((char *) de - base)>>2; |
| 1338 | − map_tail->size = le16_to_cpu(de->rec_len); | |
| 1341 | + map_tail->size = ext4_rec_len_from_disk(de->rec_len, | |
| 1342 | + blocksize); | |
| 1339 | 1343 | count++; |
| 1340 | 1344 | cond_resched(); |
| 1341 | 1345 | } |
| 1342 | − de = ext4_next_entry(de, dir->i_sb->s_blocksize); | |
| 1346 | + de = ext4_next_entry(de, blocksize); | |
| 1343 | 1347 | } |
| 1344 | 1348 | return count; |
| 1345 | 1349 | } |
| @@ -298,14 +298,12 @@ static int journal_finish_inode_data_buffers(journal_t *journal, · 297 unmodified lines | ||
| 298 | 298 | |
| 299 | 299 | static __u32 jbd2_checksum_data(__u32 crc32_sum, struct buffer_head *bh) |
| 300 | 300 | { |
| 301 | − struct page *page = bh->b_page; | |
| 302 | 301 | char *addr; |
| 303 | 302 | __u32 checksum; |
| 304 | 303 | |
| 305 | − addr = kmap_atomic(page); | |
| 306 | − checksum = crc32_be(crc32_sum, | |
| 307 | − (void *)(addr + offset_in_page(bh->b_data)), bh->b_size); | |
| 308 | − kunmap_atomic(addr); | |
| 304 | + addr = kmap_local_folio(bh->b_folio, bh_offset(bh)); | |
| 305 | + checksum = crc32_be(crc32_sum, addr, bh->b_size); | |
| 306 | + kunmap_local(addr); | |
| 309 | 307 | |
| 310 | 308 | return checksum; |
| 311 | 309 | } |
| @@ -322,7 +320,6 @@ static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag, · 10 unmodified lines | ||
| 322 | 320 | struct buffer_head *bh, __u32 sequence) |
| 323 | 321 | { |
| 324 | 322 | journal_block_tag3_t *tag3 = (journal_block_tag3_t *)tag; |
| 325 | − struct page *page = bh->b_page; | |
| 326 | 323 | __u8 *addr; |
| 327 | 324 | __u32 csum32; |
| 328 | 325 | __be32 seq; |
| @@ -331,11 +328,10 @@ static void jbd2_block_tag_csum_set(journal_t *j, journal_block_tag_t *tag, · 2 unmodified lines | ||
| 331 | 328 | return; |
| 332 | 329 | |
| 333 | 330 | seq = cpu_to_be32(sequence); |
| 334 | − addr = kmap_atomic(page); | |
| 331 | + addr = kmap_local_folio(bh->b_folio, bh_offset(bh)); | |
| 335 | 332 | csum32 = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&seq, sizeof(seq)); |
| 336 | − csum32 = jbd2_chksum(j, csum32, addr + offset_in_page(bh->b_data), | |
| 337 | − bh->b_size); | |
| 338 | − kunmap_atomic(addr); | |
| 333 | + csum32 = jbd2_chksum(j, csum32, addr, bh->b_size); | |
| 334 | + kunmap_local(addr); | |
| 339 | 335 | |
| 340 | 336 | if (jbd2_has_feature_csum3(j)) |
| 341 | 337 | tag3->t_checksum = cpu_to_be32(csum32); |
| @@ -1601,6 +1601,8 @@ static journal_t *journal_init_common(struct block_device *bdev, · 1600 unmodified lines | ||
| 1601 | 1601 | |
| 1602 | 1602 | err_cleanup: |
| 1603 | 1603 | percpu_counter_destroy(&journal->j_checkpoint_jh_count); |
| 1604 | + if (journal->j_chksum_driver) | |
| 1605 | + crypto_free_shash(journal->j_chksum_driver); | |
| 1604 | 1606 | kfree(journal->j_wbuf); |
| 1605 | 1607 | jbd2_journal_destroy_revoke(journal); |
| 1606 | 1608 | journal_fail_superblock(journal); |
| @@ -935,19 +935,15 @@ static void warn_dirty_buffer(struct buffer_head *bh) · 934 unmodified lines | ||
| 935 | 935 | /* Call t_frozen trigger and copy buffer data into jh->b_frozen_data. */ |
| 936 | 936 | static void jbd2_freeze_jh_data(struct journal_head *jh) |
| 937 | 937 | { |
| 938 | − struct page *page; | |
| 939 | − int offset; | |
| 940 | 938 | char *source; |
| 941 | 939 | struct buffer_head *bh = jh2bh(jh); |
| 942 | 940 | |
| 943 | 941 | J_EXPECT_JH(jh, buffer_uptodate(bh), "Possible IO failure.\n"); |
| 944 | − page = bh->b_page; | |
| 945 | − offset = offset_in_page(bh->b_data); | |
| 946 | − source = kmap_atomic(page); | |
| 942 | + source = kmap_local_folio(bh->b_folio, bh_offset(bh)); | |
| 947 | 943 | /* Fire data frozen trigger just before we copy the data */ |
| 948 | − jbd2_buffer_frozen_trigger(jh, source + offset, jh->b_triggers); | |
| 949 | − memcpy(jh->b_frozen_data, source + offset, bh->b_size); | |
| 950 | − kunmap_atomic(source); | |
| 944 | + jbd2_buffer_frozen_trigger(jh, source, jh->b_triggers); | |
| 945 | + memcpy(jh->b_frozen_data, source, bh->b_size); | |
| 946 | + kunmap_local(source); | |
| 951 | 947 | |
| 952 | 948 | /* |
| 953 | 949 | * Now that the frozen data is saved off, we need to store any matching |
| @@ -171,7 +171,10 @@ static __always_inline int buffer_uptodate(const struct buffer_head *bh) · 170 unmodified lines | ||
| 171 | 171 | return test_bit_acquire(BH_Uptodate, &bh->b_state); |
| 172 | 172 | } |
| 173 | 173 | |
| 174 | −#define bh_offset(bh) ((unsigned long)(bh)->b_data & ~PAGE_MASK) | |
| 174 | +static inline unsigned long bh_offset(const struct buffer_head *bh) | |
| 175 | +{ | |
| 176 | + return (unsigned long)(bh)->b_data & (page_size(bh->b_page) - 1); | |
| 177 | +} | |
| 175 | 178 | |
| 176 | 179 | /* If we *know* page->private refers to buffer_heads */ |
| 177 | 180 | #define page_buffers(page) \ |