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

Merge tag 'for-6.14-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:

- fix stale page cache after race between readahead and direct IO write

- fix hole expansion when writing at an offset beyond EOF, the range
will not be zeroed

- use proper way to calculate offsets in folio ranges

* tag 'for-6.14-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: fix hole expansion when writing at an offset beyond EOF
btrfs: fix stale page cache after race between readahead and direct IO write
btrfs: fix two misuses of folio_shift()

+21 -12
+20 -9
fs/btrfs/extent_io.c
··· 523 523 u64 end; 524 524 u32 len; 525 525 526 - /* For now only order 0 folios are supported for data. */ 527 - ASSERT(folio_order(folio) == 0); 528 526 btrfs_debug(fs_info, 529 527 "%s: bi_sector=%llu, err=%d, mirror=%u", 530 528 __func__, bio->bi_iter.bi_sector, bio->bi_status, ··· 550 552 551 553 if (likely(uptodate)) { 552 554 loff_t i_size = i_size_read(inode); 553 - pgoff_t end_index = i_size >> folio_shift(folio); 554 555 555 556 /* 556 557 * Zero out the remaining part if this range straddles ··· 558 561 * Here we should only zero the range inside the folio, 559 562 * not touch anything else. 560 563 * 561 - * NOTE: i_size is exclusive while end is inclusive. 564 + * NOTE: i_size is exclusive while end is inclusive and 565 + * folio_contains() takes PAGE_SIZE units. 562 566 */ 563 - if (folio_index(folio) == end_index && i_size <= end) { 567 + if (folio_contains(folio, i_size >> PAGE_SHIFT) && 568 + i_size <= end) { 564 569 u32 zero_start = max(offset_in_folio(folio, i_size), 565 570 offset_in_folio(folio, start)); 566 571 u32 zero_len = offset_in_folio(folio, end) + 1 - ··· 898 899 u64 len, struct extent_map **em_cached) 899 900 { 900 901 struct extent_map *em; 901 - struct extent_state *cached_state = NULL; 902 902 903 903 ASSERT(em_cached); 904 904 ··· 913 915 *em_cached = NULL; 914 916 } 915 917 916 - btrfs_lock_and_flush_ordered_range(inode, start, start + len - 1, &cached_state); 917 918 em = btrfs_get_extent(inode, folio, start, len); 918 919 if (!IS_ERR(em)) { 919 920 BUG_ON(*em_cached); 920 921 refcount_inc(&em->refs); 921 922 *em_cached = em; 922 923 } 923 - unlock_extent(&inode->io_tree, start, start + len - 1, &cached_state); 924 924 925 925 return em; 926 926 } ··· 952 956 return ret; 953 957 } 954 958 955 - if (folio->index == last_byte >> folio_shift(folio)) { 959 + if (folio_contains(folio, last_byte >> PAGE_SHIFT)) { 956 960 size_t zero_offset = offset_in_folio(folio, last_byte); 957 961 958 962 if (zero_offset) { ··· 1075 1079 1076 1080 int btrfs_read_folio(struct file *file, struct folio *folio) 1077 1081 { 1082 + struct btrfs_inode *inode = folio_to_inode(folio); 1083 + const u64 start = folio_pos(folio); 1084 + const u64 end = start + folio_size(folio) - 1; 1085 + struct extent_state *cached_state = NULL; 1078 1086 struct btrfs_bio_ctrl bio_ctrl = { .opf = REQ_OP_READ }; 1079 1087 struct extent_map *em_cached = NULL; 1080 1088 int ret; 1081 1089 1090 + btrfs_lock_and_flush_ordered_range(inode, start, end, &cached_state); 1082 1091 ret = btrfs_do_readpage(folio, &em_cached, &bio_ctrl, NULL); 1092 + unlock_extent(&inode->io_tree, start, end, &cached_state); 1093 + 1083 1094 free_extent_map(em_cached); 1084 1095 1085 1096 /* ··· 2383 2380 { 2384 2381 struct btrfs_bio_ctrl bio_ctrl = { .opf = REQ_OP_READ | REQ_RAHEAD }; 2385 2382 struct folio *folio; 2383 + struct btrfs_inode *inode = BTRFS_I(rac->mapping->host); 2384 + const u64 start = readahead_pos(rac); 2385 + const u64 end = start + readahead_length(rac) - 1; 2386 + struct extent_state *cached_state = NULL; 2386 2387 struct extent_map *em_cached = NULL; 2387 2388 u64 prev_em_start = (u64)-1; 2388 2389 2390 + btrfs_lock_and_flush_ordered_range(inode, start, end, &cached_state); 2391 + 2389 2392 while ((folio = readahead_folio(rac)) != NULL) 2390 2393 btrfs_do_readpage(folio, &em_cached, &bio_ctrl, &prev_em_start); 2394 + 2395 + unlock_extent(&inode->io_tree, start, end, &cached_state); 2391 2396 2392 2397 if (em_cached) 2393 2398 free_extent_map(em_cached);
+1 -3
fs/btrfs/file.c
··· 1039 1039 loff_t pos = iocb->ki_pos; 1040 1040 int ret; 1041 1041 loff_t oldsize; 1042 - loff_t start_pos; 1043 1042 1044 1043 /* 1045 1044 * Quickly bail out on NOWAIT writes if we don't have the nodatacow or ··· 1065 1066 inode_inc_iversion(inode); 1066 1067 } 1067 1068 1068 - start_pos = round_down(pos, fs_info->sectorsize); 1069 1069 oldsize = i_size_read(inode); 1070 - if (start_pos > oldsize) { 1070 + if (pos > oldsize) { 1071 1071 /* Expand hole size to cover write data, preventing empty gap */ 1072 1072 loff_t end_pos = round_up(pos + count, fs_info->sectorsize); 1073 1073