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

Pull btrfs fixes from David Sterba:

- fix potential NULL pointer dereference when replaying tree log after
an error

- release path before initializing extent tree to avoid potential
deadlock when allocating new inode

- on filesystems with block size > page size
- fix potential read out of bounds during encoded read of an inline
extent
- only enforce free space tree if v1 cache is required

- print correct tree id in error message

* tag 'for-6.19-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: show correct warning if can't read data reloc tree
btrfs: fix NULL pointer dereference in do_abort_log_replay()
btrfs: force free space tree for bs > ps cases
btrfs: only enforce free space tree if v1 cache is required for bs < ps cases
btrfs: release path before initializing extent tree in btrfs_read_locked_inode()
btrfs: avoid access-beyond-folio for bs > ps encoded writes

Changed files
+39 -17
fs
+1
fs/btrfs/disk-io.c
··· 2255 2255 BTRFS_DATA_RELOC_TREE_OBJECTID, true); 2256 2256 if (IS_ERR(root)) { 2257 2257 if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) { 2258 + location.objectid = BTRFS_DATA_RELOC_TREE_OBJECTID; 2258 2259 ret = PTR_ERR(root); 2259 2260 goto out; 2260 2261 }
+32 -9
fs/btrfs/inode.c
··· 481 481 ASSERT(size <= sectorsize); 482 482 483 483 /* 484 - * The compressed size also needs to be no larger than a sector. 485 - * That's also why we only need one page as the parameter. 484 + * The compressed size also needs to be no larger than a page. 485 + * That's also why we only need one folio as the parameter. 486 486 */ 487 - if (compressed_folio) 487 + if (compressed_folio) { 488 488 ASSERT(compressed_size <= sectorsize); 489 - else 489 + ASSERT(compressed_size <= PAGE_SIZE); 490 + } else { 490 491 ASSERT(compressed_size == 0); 492 + } 491 493 492 494 if (compressed_size && compressed_folio) 493 495 cur_size = compressed_size; ··· 574 572 575 573 /* Inline extents must start at offset 0. */ 576 574 if (offset != 0) 575 + return false; 576 + 577 + /* 578 + * Even for bs > ps cases, cow_file_range_inline() can only accept a 579 + * single folio. 580 + * 581 + * This can be problematic and cause access beyond page boundary if a 582 + * page sized folio is passed into that function. 583 + * And encoded write is doing exactly that. 584 + * So here limits the inlined extent size to PAGE_SIZE. 585 + */ 586 + if (size > PAGE_SIZE || compressed_size > PAGE_SIZE) 577 587 return false; 578 588 579 589 /* Inline extents are limited to sectorsize. */ ··· 4048 4034 btrfs_set_inode_mapping_order(inode); 4049 4035 4050 4036 cache_index: 4051 - ret = btrfs_init_file_extent_tree(inode); 4052 - if (ret) 4053 - goto out; 4054 - btrfs_inode_set_file_extent_range(inode, 0, 4055 - round_up(i_size_read(vfs_inode), fs_info->sectorsize)); 4056 4037 /* 4057 4038 * If we were modified in the current generation and evicted from memory 4058 4039 * and then re-read we need to do a full sync since we don't have any ··· 4133 4124 "error loading props for ino %llu (root %llu): %d", 4134 4125 btrfs_ino(inode), btrfs_root_id(root), ret); 4135 4126 } 4127 + 4128 + /* 4129 + * We don't need the path anymore, so release it to avoid holding a read 4130 + * lock on a leaf while calling btrfs_init_file_extent_tree(), which can 4131 + * allocate memory that triggers reclaim (GFP_KERNEL) and cause a locking 4132 + * dependency. 4133 + */ 4134 + btrfs_release_path(path); 4135 + 4136 + ret = btrfs_init_file_extent_tree(inode); 4137 + if (ret) 4138 + goto out; 4139 + btrfs_inode_set_file_extent_range(inode, 0, 4140 + round_up(i_size_read(vfs_inode), fs_info->sectorsize)); 4136 4141 4137 4142 if (!maybe_acls) 4138 4143 cache_no_acl(vfs_inode);
+5 -7
fs/btrfs/super.c
··· 736 736 */ 737 737 void btrfs_set_free_space_cache_settings(struct btrfs_fs_info *fs_info) 738 738 { 739 - if (fs_info->sectorsize < PAGE_SIZE) { 739 + if (fs_info->sectorsize != PAGE_SIZE && btrfs_test_opt(fs_info, SPACE_CACHE)) { 740 + btrfs_info(fs_info, 741 + "forcing free space tree for sector size %u with page size %lu", 742 + fs_info->sectorsize, PAGE_SIZE); 740 743 btrfs_clear_opt(fs_info->mount_opt, SPACE_CACHE); 741 - if (!btrfs_test_opt(fs_info, FREE_SPACE_TREE)) { 742 - btrfs_info(fs_info, 743 - "forcing free space tree for sector size %u with page size %lu", 744 - fs_info->sectorsize, PAGE_SIZE); 745 - btrfs_set_opt(fs_info->mount_opt, FREE_SPACE_TREE); 746 - } 744 + btrfs_set_opt(fs_info->mount_opt, FREE_SPACE_TREE); 747 745 } 748 746 749 747 /*
+1 -1
fs/btrfs/tree-log.c
··· 190 190 191 191 btrfs_abort_transaction(wc->trans, error); 192 192 193 - if (wc->subvol_path->nodes[0]) { 193 + if (wc->subvol_path && wc->subvol_path->nodes[0]) { 194 194 btrfs_crit(fs_info, 195 195 "subvolume (root %llu) leaf currently being processed:", 196 196 btrfs_root_id(wc->root));