mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00:00
for-6.19-rc4-tag
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmlhIx0ACgkQxWXV+ddt
WDszVRAAik5HCuE0AwSmn/9VlN4ZFIZDKNUF1RnctsJuKkqEVTXLvpf7exM+C+WR
HKTNlRxCcKikAgtk4vlh7XI3bydaeYZpxyQmfVqn1prBXvL1NUPzdKjCOkhQL9yi
9uJAGPjekrVGc/l805DlQxZ19Jzc/HxWV6/uUBO2djKNVXOljxFK9IIL6rHHzwHe
pMR6n0zkdDUUxz0+x6BaJfvz1Vn8HyNd64MgVsOYsguaOmyHpn3/gxQ17jMcIvKu
Zh3Y+3vmZBdHP4t9USi0whc5tKiM2xOAzYm10ZQLhXDFWXNWnIoLmX+QrDhPZiyJ
r99ILwFBpoxHyuACNhZJK6YaNaukp97pmgfhO8k226FpAkTsBymdSYp5il8utAIE
/mBulniqkDKA2XTyv+KtRHPCeStUK427t/ZDTzmlBxYxtdcLSvrKtiXempYQ41vt
SQZGOt4psEhR7ZuFvFI7TgtbPoEq7z2O2WukX1ujx/9gjjZTLppst7EnKfdsRT8B
KygNl8W4wWo3yhP8RSlt8XBfF+KxCO75HnpBm78yoJqxOgle6h+Vx2WzsVi06o6R
06SzEHkzNMWW6Tj68xvGcm0DTmScvY5uiElf9MgyZBY69I7/q4U8SnnlTnwiru6g
wNaDLT0y2FWrH+RhKqUmWbWQGDyKdAdA5rZdI9eXoJRNxegOMkA=
=Euzv
-----END PGP SIGNATURE-----
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
This commit is contained in:
commit
372800cb95
@ -2255,6 +2255,7 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info)
|
|||||||
BTRFS_DATA_RELOC_TREE_OBJECTID, true);
|
BTRFS_DATA_RELOC_TREE_OBJECTID, true);
|
||||||
if (IS_ERR(root)) {
|
if (IS_ERR(root)) {
|
||||||
if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) {
|
if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) {
|
||||||
|
location.objectid = BTRFS_DATA_RELOC_TREE_OBJECTID;
|
||||||
ret = PTR_ERR(root);
|
ret = PTR_ERR(root);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -481,13 +481,15 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
|
|||||||
ASSERT(size <= sectorsize);
|
ASSERT(size <= sectorsize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The compressed size also needs to be no larger than a sector.
|
* The compressed size also needs to be no larger than a page.
|
||||||
* That's also why we only need one page as the parameter.
|
* That's also why we only need one folio as the parameter.
|
||||||
*/
|
*/
|
||||||
if (compressed_folio)
|
if (compressed_folio) {
|
||||||
ASSERT(compressed_size <= sectorsize);
|
ASSERT(compressed_size <= sectorsize);
|
||||||
else
|
ASSERT(compressed_size <= PAGE_SIZE);
|
||||||
|
} else {
|
||||||
ASSERT(compressed_size == 0);
|
ASSERT(compressed_size == 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (compressed_size && compressed_folio)
|
if (compressed_size && compressed_folio)
|
||||||
cur_size = compressed_size;
|
cur_size = compressed_size;
|
||||||
@ -574,6 +576,18 @@ static bool can_cow_file_range_inline(struct btrfs_inode *inode,
|
|||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Even for bs > ps cases, cow_file_range_inline() can only accept a
|
||||||
|
* single folio.
|
||||||
|
*
|
||||||
|
* This can be problematic and cause access beyond page boundary if a
|
||||||
|
* page sized folio is passed into that function.
|
||||||
|
* And encoded write is doing exactly that.
|
||||||
|
* So here limits the inlined extent size to PAGE_SIZE.
|
||||||
|
*/
|
||||||
|
if (size > PAGE_SIZE || compressed_size > PAGE_SIZE)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* Inline extents are limited to sectorsize. */
|
/* Inline extents are limited to sectorsize. */
|
||||||
if (size > fs_info->sectorsize)
|
if (size > fs_info->sectorsize)
|
||||||
return false;
|
return false;
|
||||||
@ -4034,11 +4048,6 @@ static int btrfs_read_locked_inode(struct btrfs_inode *inode, struct btrfs_path
|
|||||||
btrfs_set_inode_mapping_order(inode);
|
btrfs_set_inode_mapping_order(inode);
|
||||||
|
|
||||||
cache_index:
|
cache_index:
|
||||||
ret = btrfs_init_file_extent_tree(inode);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
btrfs_inode_set_file_extent_range(inode, 0,
|
|
||||||
round_up(i_size_read(vfs_inode), fs_info->sectorsize));
|
|
||||||
/*
|
/*
|
||||||
* If we were modified in the current generation and evicted from memory
|
* If we were modified in the current generation and evicted from memory
|
||||||
* and then re-read we need to do a full sync since we don't have any
|
* and then re-read we need to do a full sync since we don't have any
|
||||||
@ -4125,6 +4134,20 @@ cache_acl:
|
|||||||
btrfs_ino(inode), btrfs_root_id(root), ret);
|
btrfs_ino(inode), btrfs_root_id(root), ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't need the path anymore, so release it to avoid holding a read
|
||||||
|
* lock on a leaf while calling btrfs_init_file_extent_tree(), which can
|
||||||
|
* allocate memory that triggers reclaim (GFP_KERNEL) and cause a locking
|
||||||
|
* dependency.
|
||||||
|
*/
|
||||||
|
btrfs_release_path(path);
|
||||||
|
|
||||||
|
ret = btrfs_init_file_extent_tree(inode);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
btrfs_inode_set_file_extent_range(inode, 0,
|
||||||
|
round_up(i_size_read(vfs_inode), fs_info->sectorsize));
|
||||||
|
|
||||||
if (!maybe_acls)
|
if (!maybe_acls)
|
||||||
cache_no_acl(vfs_inode);
|
cache_no_acl(vfs_inode);
|
||||||
|
|
||||||
|
|||||||
@ -736,14 +736,12 @@ bool btrfs_check_options(const struct btrfs_fs_info *info,
|
|||||||
*/
|
*/
|
||||||
void btrfs_set_free_space_cache_settings(struct btrfs_fs_info *fs_info)
|
void btrfs_set_free_space_cache_settings(struct btrfs_fs_info *fs_info)
|
||||||
{
|
{
|
||||||
if (fs_info->sectorsize < PAGE_SIZE) {
|
if (fs_info->sectorsize != PAGE_SIZE && btrfs_test_opt(fs_info, SPACE_CACHE)) {
|
||||||
|
btrfs_info(fs_info,
|
||||||
|
"forcing free space tree for sector size %u with page size %lu",
|
||||||
|
fs_info->sectorsize, PAGE_SIZE);
|
||||||
btrfs_clear_opt(fs_info->mount_opt, SPACE_CACHE);
|
btrfs_clear_opt(fs_info->mount_opt, SPACE_CACHE);
|
||||||
if (!btrfs_test_opt(fs_info, FREE_SPACE_TREE)) {
|
btrfs_set_opt(fs_info->mount_opt, FREE_SPACE_TREE);
|
||||||
btrfs_info(fs_info,
|
|
||||||
"forcing free space tree for sector size %u with page size %lu",
|
|
||||||
fs_info->sectorsize, PAGE_SIZE);
|
|
||||||
btrfs_set_opt(fs_info->mount_opt, FREE_SPACE_TREE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -190,7 +190,7 @@ static void do_abort_log_replay(struct walk_control *wc, const char *function,
|
|||||||
|
|
||||||
btrfs_abort_transaction(wc->trans, error);
|
btrfs_abort_transaction(wc->trans, error);
|
||||||
|
|
||||||
if (wc->subvol_path->nodes[0]) {
|
if (wc->subvol_path && wc->subvol_path->nodes[0]) {
|
||||||
btrfs_crit(fs_info,
|
btrfs_crit(fs_info,
|
||||||
"subvolume (root %llu) leaf currently being processed:",
|
"subvolume (root %llu) leaf currently being processed:",
|
||||||
btrfs_root_id(wc->root));
|
btrfs_root_id(wc->root));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user