From f1304eb52afd613cfcc4d2ce4521dc4a2d54f446 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 20 May 2023 14:13:04 -0400 Subject: [PATCH] Fixes for 5.10 Signed-off-by: Sasha Levin --- ...cache-inconsistency-after-error-load.patch | 62 ++++++ ..._find_highest_objectid-btrfs_find_fr.patch | 179 ++++++++++++++++++ ...lls-to-btrfs_find_free_ino-with-btrf.patch | 84 ++++++++ queue-5.10/series | 3 + 4 files changed, 328 insertions(+) create mode 100644 queue-5.10/btrfs-fix-space-cache-inconsistency-after-error-load.patch create mode 100644 queue-5.10/btrfs-move-btrfs_find_highest_objectid-btrfs_find_fr.patch create mode 100644 queue-5.10/btrfs-replace-calls-to-btrfs_find_free_ino-with-btrf.patch diff --git a/queue-5.10/btrfs-fix-space-cache-inconsistency-after-error-load.patch b/queue-5.10/btrfs-fix-space-cache-inconsistency-after-error-load.patch new file mode 100644 index 00000000000..1727d2a4686 --- /dev/null +++ b/queue-5.10/btrfs-fix-space-cache-inconsistency-after-error-load.patch @@ -0,0 +1,62 @@ +From 5f8ecdce42b6dc54b3ebf0774842a3a2000e9c7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 May 2023 12:04:18 +0100 +Subject: btrfs: fix space cache inconsistency after error loading it from disk + +From: Filipe Manana + +[ Upstream commit 0004ff15ea26015a0a3a6182dca3b9d1df32e2b7 ] + +When loading a free space cache from disk, at __load_free_space_cache(), +if we fail to insert a bitmap entry, we still increment the number of +total bitmaps in the btrfs_free_space_ctl structure, which is incorrect +since we failed to add the bitmap entry. On error we then empty the +cache by calling __btrfs_remove_free_space_cache(), which will result +in getting the total bitmaps counter set to 1. + +A failure to load a free space cache is not critical, so if a failure +happens we just rebuild the cache by scanning the extent tree, which +happens at block-group.c:caching_thread(). Yet the failure will result +in having the total bitmaps of the btrfs_free_space_ctl always bigger +by 1 then the number of bitmap entries we have. So fix this by having +the total bitmaps counter be incremented only if we successfully added +the bitmap entry. + +Fixes: a67509c30079 ("Btrfs: add a io_ctl struct and helpers for dealing with the space cache") +Reviewed-by: Anand Jain +CC: stable@vger.kernel.org # 4.4+ +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/free-space-cache.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c +index ba280707d5ec2..4989c60b1df9c 100644 +--- a/fs/btrfs/free-space-cache.c ++++ b/fs/btrfs/free-space-cache.c +@@ -794,15 +794,16 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, + } + spin_lock(&ctl->tree_lock); + ret = link_free_space(ctl, e); +- ctl->total_bitmaps++; +- ctl->op->recalc_thresholds(ctl); +- spin_unlock(&ctl->tree_lock); + if (ret) { ++ spin_unlock(&ctl->tree_lock); + btrfs_err(fs_info, + "Duplicate entries in free space cache, dumping"); + kmem_cache_free(btrfs_free_space_cachep, e); + goto free_cache; + } ++ ctl->total_bitmaps++; ++ ctl->op->recalc_thresholds(ctl); ++ spin_unlock(&ctl->tree_lock); + list_add_tail(&e->list, &bitmaps); + } + +-- +2.39.2 + diff --git a/queue-5.10/btrfs-move-btrfs_find_highest_objectid-btrfs_find_fr.patch b/queue-5.10/btrfs-move-btrfs_find_highest_objectid-btrfs_find_fr.patch new file mode 100644 index 00000000000..0099b0ed22c --- /dev/null +++ b/queue-5.10/btrfs-move-btrfs_find_highest_objectid-btrfs_find_fr.patch @@ -0,0 +1,179 @@ +From fbe5b786d31288273ee7d210f5aa5a2d96018121 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Nov 2020 15:10:37 +0200 +Subject: btrfs: move btrfs_find_highest_objectid/btrfs_find_free_objectid to + disk-io.c + +From: Nikolay Borisov + +[ Upstream commit ec7d6dfd73b2de1c6bc36f832542061b0ca0e0ff ] + +Those functions are going to be used even after inode cache is removed +so moved them to a more appropriate place. + +Signed-off-by: Nikolay Borisov +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: 0004ff15ea26 ("btrfs: fix space cache inconsistency after error loading it from disk") +Signed-off-by: Sasha Levin +--- + fs/btrfs/disk-io.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ + fs/btrfs/disk-io.h | 2 ++ + fs/btrfs/inode-map.c | 55 -------------------------------------------- + fs/btrfs/inode-map.h | 3 --- + 4 files changed, 57 insertions(+), 58 deletions(-) + +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 2a7778a88f03b..095c9e4f92248 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -4780,3 +4780,58 @@ static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info) + + return 0; + } ++ ++int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid) ++{ ++ struct btrfs_path *path; ++ int ret; ++ struct extent_buffer *l; ++ struct btrfs_key search_key; ++ struct btrfs_key found_key; ++ int slot; ++ ++ path = btrfs_alloc_path(); ++ if (!path) ++ return -ENOMEM; ++ ++ search_key.objectid = BTRFS_LAST_FREE_OBJECTID; ++ search_key.type = -1; ++ search_key.offset = (u64)-1; ++ ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); ++ if (ret < 0) ++ goto error; ++ BUG_ON(ret == 0); /* Corruption */ ++ if (path->slots[0] > 0) { ++ slot = path->slots[0] - 1; ++ l = path->nodes[0]; ++ btrfs_item_key_to_cpu(l, &found_key, slot); ++ *objectid = max_t(u64, found_key.objectid, ++ BTRFS_FIRST_FREE_OBJECTID - 1); ++ } else { ++ *objectid = BTRFS_FIRST_FREE_OBJECTID - 1; ++ } ++ ret = 0; ++error: ++ btrfs_free_path(path); ++ return ret; ++} ++ ++int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid) ++{ ++ int ret; ++ mutex_lock(&root->objectid_mutex); ++ ++ if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) { ++ btrfs_warn(root->fs_info, ++ "the objectid of root %llu reaches its highest value", ++ root->root_key.objectid); ++ ret = -ENOSPC; ++ goto out; ++ } ++ ++ *objectid = ++root->highest_objectid; ++ ret = 0; ++out: ++ mutex_unlock(&root->objectid_mutex); ++ return ret; ++} +diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h +index 182540bdcea0f..e3b96944ce10c 100644 +--- a/fs/btrfs/disk-io.h ++++ b/fs/btrfs/disk-io.h +@@ -131,6 +131,8 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, + int btree_lock_page_hook(struct page *page, void *data, + void (*flush_fn)(void *)); + int btrfs_get_num_tolerated_disk_barrier_failures(u64 flags); ++int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid); ++int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid); + int __init btrfs_end_io_wq_init(void); + void __cold btrfs_end_io_wq_exit(void); + +diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c +index 76d2e43817eae..c74340d22624e 100644 +--- a/fs/btrfs/inode-map.c ++++ b/fs/btrfs/inode-map.c +@@ -525,58 +525,3 @@ int btrfs_save_ino_cache(struct btrfs_root *root, + extent_changeset_free(data_reserved); + return ret; + } +- +-int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid) +-{ +- struct btrfs_path *path; +- int ret; +- struct extent_buffer *l; +- struct btrfs_key search_key; +- struct btrfs_key found_key; +- int slot; +- +- path = btrfs_alloc_path(); +- if (!path) +- return -ENOMEM; +- +- search_key.objectid = BTRFS_LAST_FREE_OBJECTID; +- search_key.type = -1; +- search_key.offset = (u64)-1; +- ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); +- if (ret < 0) +- goto error; +- BUG_ON(ret == 0); /* Corruption */ +- if (path->slots[0] > 0) { +- slot = path->slots[0] - 1; +- l = path->nodes[0]; +- btrfs_item_key_to_cpu(l, &found_key, slot); +- *objectid = max_t(u64, found_key.objectid, +- BTRFS_FIRST_FREE_OBJECTID - 1); +- } else { +- *objectid = BTRFS_FIRST_FREE_OBJECTID - 1; +- } +- ret = 0; +-error: +- btrfs_free_path(path); +- return ret; +-} +- +-int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid) +-{ +- int ret; +- mutex_lock(&root->objectid_mutex); +- +- if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) { +- btrfs_warn(root->fs_info, +- "the objectid of root %llu reaches its highest value", +- root->root_key.objectid); +- ret = -ENOSPC; +- goto out; +- } +- +- *objectid = ++root->highest_objectid; +- ret = 0; +-out: +- mutex_unlock(&root->objectid_mutex); +- return ret; +-} +diff --git a/fs/btrfs/inode-map.h b/fs/btrfs/inode-map.h +index 7a962811dffe0..629baf9aefb15 100644 +--- a/fs/btrfs/inode-map.h ++++ b/fs/btrfs/inode-map.h +@@ -10,7 +10,4 @@ int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid); + int btrfs_save_ino_cache(struct btrfs_root *root, + struct btrfs_trans_handle *trans); + +-int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid); +-int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid); +- + #endif +-- +2.39.2 + diff --git a/queue-5.10/btrfs-replace-calls-to-btrfs_find_free_ino-with-btrf.patch b/queue-5.10/btrfs-replace-calls-to-btrfs_find_free_ino-with-btrf.patch new file mode 100644 index 00000000000..4f2b2b0c0f5 --- /dev/null +++ b/queue-5.10/btrfs-replace-calls-to-btrfs_find_free_ino-with-btrf.patch @@ -0,0 +1,84 @@ +From bba8659a23803accf40a26e32750dbd803e23d7c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Nov 2020 15:10:38 +0200 +Subject: btrfs: replace calls to btrfs_find_free_ino with + btrfs_find_free_objectid + +From: Nikolay Borisov + +[ Upstream commit abadc1fcd72e887a8f875dabe4a07aa8c28ac8af ] + +The former is going away as part of the inode map removal so switch +callers to btrfs_find_free_objectid. No functional changes since with +INODE_MAP disabled (default) find_free_objectid was called anyway. + +Signed-off-by: Nikolay Borisov +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Stable-dep-of: 0004ff15ea26 ("btrfs: fix space cache inconsistency after error loading it from disk") +Signed-off-by: Sasha Levin +--- + fs/btrfs/inode.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 779b7745cdc48..c900a39666e38 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -6273,7 +6273,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, + if (IS_ERR(trans)) + return PTR_ERR(trans); + +- err = btrfs_find_free_ino(root, &objectid); ++ err = btrfs_find_free_objectid(root, &objectid); + if (err) + goto out_unlock; + +@@ -6337,7 +6337,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, + if (IS_ERR(trans)) + return PTR_ERR(trans); + +- err = btrfs_find_free_ino(root, &objectid); ++ err = btrfs_find_free_objectid(root, &objectid); + if (err) + goto out_unlock; + +@@ -6481,7 +6481,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) + if (IS_ERR(trans)) + return PTR_ERR(trans); + +- err = btrfs_find_free_ino(root, &objectid); ++ err = btrfs_find_free_objectid(root, &objectid); + if (err) + goto out_fail; + +@@ -9135,7 +9135,7 @@ static int btrfs_whiteout_for_rename(struct btrfs_trans_handle *trans, + u64 objectid; + u64 index; + +- ret = btrfs_find_free_ino(root, &objectid); ++ ret = btrfs_find_free_objectid(root, &objectid); + if (ret) + return ret; + +@@ -9631,7 +9631,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, + if (IS_ERR(trans)) + return PTR_ERR(trans); + +- err = btrfs_find_free_ino(root, &objectid); ++ err = btrfs_find_free_objectid(root, &objectid); + if (err) + goto out_unlock; + +@@ -9962,7 +9962,7 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) + if (IS_ERR(trans)) + return PTR_ERR(trans); + +- ret = btrfs_find_free_ino(root, &objectid); ++ ret = btrfs_find_free_objectid(root, &objectid); + if (ret) + goto out; + +-- +2.39.2 + diff --git a/queue-5.10/series b/queue-5.10/series index feb73ce6f97..b71d6883d52 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -81,3 +81,6 @@ iommu-arm-smmu-v3-acknowledge-pri-event-queue-overfl.patch input-xpad-add-constants-for-gip-interface-numbers.patch phy-st-miphy28lp-use-_poll_timeout-functions-for-wai.patch mfd-dln2-fix-memory-leak-in-dln2_probe.patch +btrfs-move-btrfs_find_highest_objectid-btrfs_find_fr.patch +btrfs-replace-calls-to-btrfs_find_free_ino-with-btrf.patch +btrfs-fix-space-cache-inconsistency-after-error-load.patch -- 2.47.3