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