Merge tag 'for-6.9-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
[linux-2.6-microblaze.git] / fs / btrfs / extent-tree.c
index 8e8cc11..beedd6e 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/crc32c.h>
 #include "ctree.h"
 #include "extent-tree.h"
-#include "tree-log.h"
+#include "transaction.h"
 #include "disk-io.h"
 #include "print-tree.h"
 #include "volumes.h"
 #include "locking.h"
 #include "free-space-cache.h"
 #include "free-space-tree.h"
-#include "sysfs.h"
 #include "qgroup.h"
 #include "ref-verify.h"
 #include "space-info.h"
 #include "block-rsv.h"
-#include "delalloc-space.h"
 #include "discard.h"
-#include "rcu-string.h"
 #include "zoned.h"
 #include "dev-replace.h"
 #include "fs.h"
@@ -2399,7 +2396,14 @@ static noinline int check_committed_ref(struct btrfs_root *root,
        ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0);
        if (ret < 0)
                goto out;
-       BUG_ON(ret == 0); /* Corruption */
+       if (ret == 0) {
+               /*
+                * Key with offset -1 found, there would have to exist an extent
+                * item with such offset, but this is out of the valid range.
+                */
+               ret = -EUCLEAN;
+               goto out;
+       }
 
        ret = -ENOENT;
        if (path->slots[0] == 0)
@@ -2780,6 +2784,7 @@ static int unpin_extent_range(struct btrfs_fs_info *fs_info,
        u64 total_unpinned = 0;
        u64 empty_cluster = 0;
        bool readonly;
+       int ret = 0;
 
        while (start <= end) {
                readonly = false;
@@ -2789,7 +2794,11 @@ static int unpin_extent_range(struct btrfs_fs_info *fs_info,
                                btrfs_put_block_group(cache);
                        total_unpinned = 0;
                        cache = btrfs_lookup_block_group(fs_info, start);
-                       BUG_ON(!cache); /* Logic error */
+                       if (cache == NULL) {
+                               /* Logic error, something removed the block group. */
+                               ret = -EUCLEAN;
+                               goto out;
+                       }
 
                        cluster = fetch_cluster_info(fs_info,
                                                     cache->space_info,
@@ -2858,7 +2867,8 @@ static int unpin_extent_range(struct btrfs_fs_info *fs_info,
 
        if (cache)
                btrfs_put_block_group(cache);
-       return 0;
+out:
+       return ret;
 }
 
 int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
@@ -2888,7 +2898,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
                                                   end + 1 - start, NULL);
 
                clear_extent_dirty(unpin, start, end, &cached_state);
-               unpin_extent_range(fs_info, start, end, true);
+               ret = unpin_extent_range(fs_info, start, end, true);
+               BUG_ON(ret);
                mutex_unlock(&fs_info->unused_bg_unpin_mutex);
                free_extent_state(cached_state);
                cond_resched();
@@ -3447,16 +3458,17 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
                           u64 parent, int last_ref)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
-       struct btrfs_ref generic_ref = { 0 };
        struct btrfs_block_group *bg;
        int ret;
 
-       btrfs_init_generic_ref(&generic_ref, BTRFS_DROP_DELAYED_REF,
-                              buf->start, buf->len, parent, btrfs_header_owner(buf));
-       btrfs_init_tree_ref(&generic_ref, btrfs_header_level(buf),
-                           root_id, 0, false);
-
        if (root_id != BTRFS_TREE_LOG_OBJECTID) {
+               struct btrfs_ref generic_ref = { 0 };
+
+               btrfs_init_generic_ref(&generic_ref, BTRFS_DROP_DELAYED_REF,
+                                      buf->start, buf->len, parent,
+                                      btrfs_header_owner(buf));
+               btrfs_init_tree_ref(&generic_ref, btrfs_header_level(buf),
+                                   root_id, 0, false);
                btrfs_ref_tree_mod(fs_info, &generic_ref);
                ret = btrfs_add_delayed_tree_ref(trans, &generic_ref, NULL);
                BUG_ON(ret); /* -ENOMEM */
@@ -4950,7 +4962,7 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
        u64 root_objectid = root->root_key.objectid;
        u64 owning_root = root_objectid;
 
-       BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID);
+       ASSERT(root_objectid != BTRFS_TREE_LOG_OBJECTID);
 
        if (btrfs_is_data_reloc_root(root) && is_fstree(root->relocation_src_root))
                owning_root = root->relocation_src_root;
@@ -6167,10 +6179,13 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
        return ret;
 }
 
-int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info,
-                                  u64 start, u64 end)
+/*
+ * Unpin the extent range in an error context and don't add the space back.
+ * Errors are not propagated further.
+ */
+void btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, u64 start, u64 end)
 {
-       return unpin_extent_range(fs_info, start, end, false);
+       unpin_extent_range(fs_info, start, end, false);
 }
 
 /*