]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: don't BUG_ON() in btrfs_drop_extents()
authorJohannes Thumshirn <johannes.thumshirn@wdc.com>
Mon, 2 Dec 2024 05:48:53 +0000 (21:48 -0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 13 Jan 2025 13:53:14 +0000 (14:53 +0100)
btrfs_drop_extents() calls BUG_ON() in case the counter of to be deleted
extents is greater than 0. But all of these code paths can handle errors,
so there's no need to crash the kernel. Instead WARN() that the condition
has been met and gracefully bail out.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/file.c

index 14e27473c5bcea8d1959ac1814babe022c7f5cf0..d314a7e03a38db356d89c74caee49f528c2a30bf 100644 (file)
@@ -36,6 +36,7 @@
 #include "ioctl.h"
 #include "file.h"
 #include "super.h"
+#include "print-tree.h"
 
 /*
  * Helper to fault in page and copy.  This should go away and be replaced with
@@ -245,7 +246,11 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
 next_slot:
                leaf = path->nodes[0];
                if (path->slots[0] >= btrfs_header_nritems(leaf)) {
-                       BUG_ON(del_nr > 0);
+                       if (WARN_ON(del_nr > 0)) {
+                               btrfs_print_leaf(leaf);
+                               ret = -EINVAL;
+                               break;
+                       }
                        ret = btrfs_next_leaf(root, path);
                        if (ret < 0)
                                break;
@@ -321,7 +326,11 @@ next_slot:
                 *  | -------- extent -------- |
                 */
                if (args->start > key.offset && args->end < extent_end) {
-                       BUG_ON(del_nr > 0);
+                       if (WARN_ON(del_nr > 0)) {
+                               btrfs_print_leaf(leaf);
+                               ret = -EINVAL;
+                               break;
+                       }
                        if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
                                ret = -EOPNOTSUPP;
                                break;
@@ -409,7 +418,11 @@ next_slot:
                 *  | -------- extent -------- |
                 */
                if (args->start > key.offset && args->end >= extent_end) {
-                       BUG_ON(del_nr > 0);
+                       if (WARN_ON(del_nr > 0)) {
+                               btrfs_print_leaf(leaf);
+                               ret = -EINVAL;
+                               break;
+                       }
                        if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
                                ret = -EOPNOTSUPP;
                                break;
@@ -437,7 +450,11 @@ delete_extent_item:
                                del_slot = path->slots[0];
                                del_nr = 1;
                        } else {
-                               BUG_ON(del_slot + del_nr != path->slots[0]);
+                               if (WARN_ON(del_slot + del_nr != path->slots[0])) {
+                                       btrfs_print_leaf(leaf);
+                                       ret = -EINVAL;
+                                       break;
+                               }
                                del_nr++;
                        }