Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

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

+64 -51
+33 -21
fs/ext4/mballoc.c
··· 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 /* ··· 6907 6906 return ret; 6908 6907 } 6909 6908 6909 + static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb, 6910 + ext4_group_t grp) 6911 + { 6912 + if (grp < ext4_get_groups_count(sb)) 6913 + return EXT4_CLUSTERS_PER_GROUP(sb) - 1; 6914 + return (ext4_blocks_count(EXT4_SB(sb)->s_es) - 6915 + ext4_group_first_block_no(sb, grp) - 1) >> 6916 + EXT4_CLUSTER_BITS(sb); 6917 + } 6918 + 6919 + static bool ext4_trim_interrupted(void) 6920 + { 6921 + return fatal_signal_pending(current) || freezing(current); 6922 + } 6923 + 6910 6924 static int ext4_try_to_trim_range(struct super_block *sb, 6911 6925 struct ext4_buddy *e4b, ext4_grpblk_t start, 6912 6926 ext4_grpblk_t max, ext4_grpblk_t minblocks) ··· 6929 6913 __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) 6930 6914 { 6931 6915 ext4_grpblk_t next, count, free_count; 6916 + bool set_trimmed = false; 6932 6917 void *bitmap; 6933 6918 6934 6919 bitmap = e4b->bd_bitmap; 6920 + if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group)) 6921 + set_trimmed = true; 6935 6922 start = max(e4b->bd_info->bb_first_free, start); 6936 6923 count = 0; 6937 6924 free_count = 0; ··· 6949 6930 int ret = ext4_trim_extent(sb, start, next - start, e4b); 6950 6931 6951 6932 if (ret && ret != -EOPNOTSUPP) 6952 - break; 6933 + return count; 6953 6934 count += next - start; 6954 6935 } 6955 6936 free_count += next - start; 6956 6937 start = next + 1; 6957 6938 6958 - if (fatal_signal_pending(current)) { 6959 - count = -ERESTARTSYS; 6960 - break; 6961 - } 6939 + if (ext4_trim_interrupted()) 6940 + return count; 6962 6941 6963 6942 if (need_resched()) { 6964 6943 ext4_unlock_group(sb, e4b->bd_group); ··· 6968 6951 break; 6969 6952 } 6970 6953 6954 + if (set_trimmed) 6955 + EXT4_MB_GRP_SET_TRIMMED(e4b->bd_info); 6956 + 6971 6957 return count; 6972 6958 } 6973 6959 ··· 6981 6961 * @start: first group block to examine 6982 6962 * @max: last group block to examine 6983 6963 * @minblocks: minimum extent block count 6984 - * @set_trimmed: set the trimmed flag if at least one block is trimmed 6985 6964 * 6986 6965 * ext4_trim_all_free walks through group's block bitmap searching for free 6987 6966 * extents. When the free extent is found, mark it as used in group buddy ··· 6990 6971 static ext4_grpblk_t 6991 6972 ext4_trim_all_free(struct super_block *sb, ext4_group_t group, 6992 6973 ext4_grpblk_t start, ext4_grpblk_t max, 6993 - ext4_grpblk_t minblocks, bool set_trimmed) 6974 + ext4_grpblk_t minblocks) 6994 6975 { 6995 6976 struct ext4_buddy e4b; 6996 6977 int ret; ··· 7007 6988 ext4_lock_group(sb, group); 7008 6989 7009 6990 if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) || 7010 - minblocks < EXT4_SB(sb)->s_last_trim_minblks) { 6991 + minblocks < EXT4_SB(sb)->s_last_trim_minblks) 7011 6992 ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks); 7012 - if (ret >= 0 && set_trimmed) 7013 - EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info); 7014 - } else { 6993 + else 7015 6994 ret = 0; 7016 - } 7017 6995 7018 6996 ext4_unlock_group(sb, group); 7019 6997 ext4_mb_unload_buddy(&e4b); ··· 7043 7027 ext4_fsblk_t first_data_blk = 7044 7028 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); 7045 7029 ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es); 7046 - bool whole_group, eof = false; 7047 7030 int ret = 0; 7048 7031 7049 7032 start = range->start >> sb->s_blocksize_bits; ··· 7061 7046 if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) 7062 7047 goto out; 7063 7048 } 7064 - if (end >= max_blks - 1) { 7049 + if (end >= max_blks - 1) 7065 7050 end = max_blks - 1; 7066 - eof = true; 7067 - } 7068 7051 if (end <= first_data_blk) 7069 7052 goto out; 7070 7053 if (start < first_data_blk) ··· 7076 7063 7077 7064 /* end now represents the last cluster to discard in this group */ 7078 7065 end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; 7079 - whole_group = true; 7080 7066 7081 7067 for (group = first_group; group <= last_group; group++) { 7068 + if (ext4_trim_interrupted()) 7069 + break; 7082 7070 grp = ext4_get_group_info(sb, group); 7083 7071 if (!grp) 7084 7072 continue; ··· 7096 7082 * change it for the last group, note that last_cluster is 7097 7083 * already computed earlier by ext4_get_group_no_and_offset() 7098 7084 */ 7099 - if (group == last_group) { 7085 + if (group == last_group) 7100 7086 end = last_cluster; 7101 - whole_group = eof ? true : end == EXT4_CLUSTERS_PER_GROUP(sb) - 1; 7102 - } 7103 7087 if (grp->bb_free >= minlen) { 7104 7088 cnt = ext4_trim_all_free(sb, group, first_cluster, 7105 - end, minlen, whole_group); 7089 + end, minlen); 7106 7090 if (cnt < 0) { 7107 7091 ret = cnt; 7108 7092 break;
+15 -11
fs/ext4/namei.c
··· 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 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; ··· 446 445 struct ext4_dir_entry *dp; 447 446 struct dx_root_info *root; 448 447 int count_offset; 448 + int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); 449 + unsigned int rlen = ext4_rec_len_from_disk(dirent->rec_len, blocksize); 449 450 450 - if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb)) 451 + if (rlen == blocksize) 451 452 count_offset = 8; 452 - else if (le16_to_cpu(dirent->rec_len) == 12) { 453 + else if (rlen == 12) { 453 454 dp = (struct ext4_dir_entry *)(((void *)dirent) + 12); 454 - if (le16_to_cpu(dp->rec_len) != 455 - EXT4_BLOCK_SIZE(inode->i_sb) - 12) 455 + if (ext4_rec_len_from_disk(dp->rec_len, blocksize) != blocksize - 12) 456 456 return NULL; 457 457 root = (struct dx_root_info *)(((void *)dp + 12)); 458 458 if (root->reserved_zero || ··· 1317 1315 unsigned int buflen = bh->b_size; 1318 1316 char *base = bh->b_data; 1319 1317 struct dx_hash_info h = *hinfo; 1318 + int blocksize = EXT4_BLOCK_SIZE(dir->i_sb); 1320 1319 1321 1320 if (ext4_has_metadata_csum(dir->i_sb)) 1322 1321 buflen -= sizeof(struct ext4_dir_entry_tail); ··· 1338 1335 map_tail--; 1339 1336 map_tail->hash = h.hash; 1340 1337 map_tail->offs = ((char *) de - base)>>2; 1341 - map_tail->size = le16_to_cpu(de->rec_len); 1338 + map_tail->size = ext4_rec_len_from_disk(de->rec_len, 1339 + blocksize); 1342 1340 count++; 1343 1341 cond_resched(); 1344 1342 } 1345 - de = ext4_next_entry(de, dir->i_sb->s_blocksize); 1343 + de = ext4_next_entry(de, blocksize); 1346 1344 } 1347 1345 return count; 1348 1346 }
+6 -10
fs/jbd2/commit.c
··· 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 } ··· 320 322 struct buffer_head *bh, __u32 sequence) 321 323 { 322 324 journal_block_tag3_t *tag3 = (journal_block_tag3_t *)tag; 323 - struct page *page = bh->b_page; 324 325 __u8 *addr; 325 326 __u32 csum32; 326 327 __be32 seq; ··· 328 331 return; 329 332 330 333 seq = cpu_to_be32(sequence); 331 - addr = kmap_atomic(page); 334 + addr = kmap_local_folio(bh->b_folio, bh_offset(bh)); 332 335 csum32 = jbd2_chksum(j, j->j_csum_seed, (__u8 *)&seq, sizeof(seq)); 333 - csum32 = jbd2_chksum(j, csum32, addr + offset_in_page(bh->b_data), 334 - bh->b_size); 335 - kunmap_atomic(addr); 336 + csum32 = jbd2_chksum(j, csum32, addr, bh->b_size); 337 + kunmap_local(addr); 336 338 337 339 if (jbd2_has_feature_csum3(j)) 338 340 tag3->t_checksum = cpu_to_be32(csum32);
+2
fs/jbd2/journal.c
··· 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);
+4 -8
fs/jbd2/transaction.c
··· 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
+4 -1
include/linux/buffer_head.h
··· 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) \