mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 16:10:02 +02:00
for-7.3-rc2-tag
-----BEGIN PGP SIGNATURE----- iQJPBAABCgA5FiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmqkjz8bFIAAAAAABAAO bWFudTIsMi41KzEuMTIsMiwyAAoJEMVl1fnXbVg72aYP/iJfylH6S+RbQMRFvon2 TixmsPcGaFgUUAyAG4uLmfVX7KS4Z7uJD8zoZKqP0DMBbCOUwEjWriY2Fy9dKAJm I8UNJpPfQzXV7Oalpdy5UaNVVtdk/mE1Rhv4+G4EdqNLf9GuxTd+kuO1Tn1EK/Ql gQKL1WZgYmHBHDv9R1uip/ibEMsTzow2RDQGDI/AKILlnWjoMthd22NXdX0bC7Tb sKZfEmDKbIpiVkoMaJdoXsXnDifsAb31W0KqiqOvG3PGS5bY/TJgV9l5x9heExvR pQ4CCSY/wH+dWKetl3YvHiWBiSXdKlsufnYwsO00PxJAr+Q7pNsBrXH5fys9bORC G7qCWiEmTJElNnTBTv0yUaJq+FQ6/FSzTPZXQgGhUctamiM2hgnEVv4vc8YiEGcN dk7rBSKMfA08BXqGhEwLZkVwleM09uUa89kK9gG/pdh0aY5twHB4CQ2EQFwitJgE QhtTrKLa8yjP7HpzR82VEioTkj7KZlI+jYDksaIACANjbxk7tZ73F81lPi7vNhRj YyYOXZOQaD081d+h09NM89C/XTXrKMND6Ft8iRSzSec/U75YWeDRFHJ2O986n0dj DAxzArrAR18lQwCmFODJbRMi6ELcnSjSbiIusNjUpwXsVSOuZR/ulriTRktPvptq UtDnhWOvBjHwoeqUlgB4OAEG =DZIQ -----END PGP SIGNATURE----- Merge tag 'for-7.3-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: - tree-checker updates, validate values in b-tree item keys, other item length checks - don't do unnecessary transaction commit fallback when logging parent directories - in zoned mode, initialize space info of a block group early enough so it does not lead to NULL pointer dereference * tag 'for-7.3-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: tree-checker: validate name length for extref items btrfs: tree-checker: validate parent field for inode extref items btrfs: tree-checker: validate key offset for inode ref keys btrfs: fix unnecessary transaction commit fallback from btrfs_log_all_parents() btrfs: set space_info before adding new free space in btrfs_make_block_group()
This commit is contained in:
commit
95deca8dd9
|
|
@ -3074,6 +3074,18 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran
|
|||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure the corresponding space_info object is created and
|
||||
* assigned to our block group. We want our bg to be added to the rbtree
|
||||
* with its ->space_info set.
|
||||
*
|
||||
* On a zoned filesystem btrfs_add_new_free_space() ends up in
|
||||
* __btrfs_add_free_space_zoned(), which dereferences
|
||||
* block_group->space_info, so it has to be set beforehand.
|
||||
*/
|
||||
cache->space_info = space_info;
|
||||
ASSERT(cache->space_info);
|
||||
|
||||
ret = btrfs_add_new_free_space(cache, chunk_offset, chunk_offset + size, NULL);
|
||||
btrfs_free_excluded_extents(cache);
|
||||
if (ret) {
|
||||
|
|
@ -3081,14 +3093,6 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran
|
|||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure the corresponding space_info object is created and
|
||||
* assigned to our block group. We want our bg to be added to the rbtree
|
||||
* with its ->space_info set.
|
||||
*/
|
||||
cache->space_info = space_info;
|
||||
ASSERT(cache->space_info);
|
||||
|
||||
ret = btrfs_add_block_group_cache(cache);
|
||||
if (ret) {
|
||||
btrfs_remove_free_space_cache(cache);
|
||||
|
|
|
|||
|
|
@ -1909,6 +1909,16 @@ static int check_inode_ref(struct extent_buffer *leaf,
|
|||
return -EUCLEAN;
|
||||
}
|
||||
|
||||
if (unlikely(btrfs_is_fstree(btrfs_header_owner(leaf)) &&
|
||||
(key->offset < BTRFS_FIRST_FREE_OBJECTID ||
|
||||
key->offset > BTRFS_LAST_FREE_OBJECTID))) {
|
||||
inode_ref_err(leaf, slot,
|
||||
"invalid offset for ref key, have %llu expect [%llu, %lld]",
|
||||
key->offset, BTRFS_FIRST_FREE_OBJECTID,
|
||||
BTRFS_LAST_FREE_OBJECTID);
|
||||
return -EUCLEAN;
|
||||
}
|
||||
|
||||
ptr = btrfs_item_ptr_offset(leaf, slot);
|
||||
end = ptr + btrfs_item_size(leaf, slot);
|
||||
while (ptr < end) {
|
||||
|
|
@ -1952,12 +1962,14 @@ static int check_inode_extref(struct extent_buffer *leaf,
|
|||
{
|
||||
unsigned long ptr = btrfs_item_ptr_offset(leaf, slot);
|
||||
unsigned long end = ptr + btrfs_item_size(leaf, slot);
|
||||
const bool is_fstree = btrfs_is_fstree(btrfs_header_owner(leaf));
|
||||
|
||||
if (unlikely(!check_prev_ino(leaf, key, slot, prev_key)))
|
||||
return -EUCLEAN;
|
||||
|
||||
while (ptr < end) {
|
||||
struct btrfs_inode_extref *extref = (struct btrfs_inode_extref *)ptr;
|
||||
u64 parent;
|
||||
u16 namelen;
|
||||
|
||||
if (unlikely(ptr + sizeof(*extref) > end)) {
|
||||
|
|
@ -1967,7 +1979,24 @@ static int check_inode_extref(struct extent_buffer *leaf,
|
|||
return -EUCLEAN;
|
||||
}
|
||||
|
||||
parent = btrfs_inode_extref_parent(leaf, extref);
|
||||
if (unlikely(is_fstree && (parent < BTRFS_FIRST_FREE_OBJECTID ||
|
||||
parent > BTRFS_LAST_FREE_OBJECTID))) {
|
||||
inode_ref_err(leaf, slot,
|
||||
"invalid parent for extref key, have %llu expect [%llu, %lld]",
|
||||
parent, BTRFS_FIRST_FREE_OBJECTID,
|
||||
BTRFS_LAST_FREE_OBJECTID);
|
||||
return -EUCLEAN;
|
||||
}
|
||||
|
||||
namelen = btrfs_inode_extref_name_len(leaf, extref);
|
||||
if (unlikely(namelen == 0 || namelen > BTRFS_NAME_LEN)) {
|
||||
inode_ref_err(leaf, slot,
|
||||
"invalid inode extref name length, has %u expect [1, %u]",
|
||||
namelen, BTRFS_NAME_LEN);
|
||||
return -EUCLEAN;
|
||||
}
|
||||
|
||||
if (unlikely(ptr + sizeof(*extref) + namelen > end)) {
|
||||
inode_ref_err(leaf, slot,
|
||||
"inode extref overflow, ptr %lu end %lu namelen %u",
|
||||
|
|
|
|||
|
|
@ -7286,6 +7286,22 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
|
|||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
/*
|
||||
* There can't be an inode ref key with offset 0 because inode numbers
|
||||
* start at BTRFS_FIRST_FREE_OBJECTID.
|
||||
*/
|
||||
if (WARN_ON_ONCE(ret == 0)) {
|
||||
btrfs_err(trans->fs_info,
|
||||
"found inode ref key with offset 0 for root %llu inode %llu",
|
||||
btrfs_root_id(root), ino);
|
||||
ret = BTRFS_LOG_FORCE_COMMIT;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Set to 0 so that in case we don't do any work below, we won't return
|
||||
* 1 and trigger an unnecessary transaction commit.
|
||||
*/
|
||||
ret = 0;
|
||||
|
||||
while (true) {
|
||||
struct extent_buffer *leaf = path->nodes[0];
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user