]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: preserve first error in btrfs_trim_fs()
authorjinbaohong <jinbaohong@synology.com>
Wed, 28 Jan 2026 07:06:39 +0000 (07:06 +0000)
committerDavid Sterba <dsterba@suse.com>
Tue, 3 Feb 2026 06:56:24 +0000 (07:56 +0100)
When multiple block groups or devices fail during trim, preserve the
first error encountered rather than the last one. The first error is
typically more useful for debugging as it represents the original
failure, while subsequent errors may be cascading effects.

Signed-off-by: Robbie Ko <robbieko@synology.com>
Signed-off-by: jinbaohong <jinbaohong@synology.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent-tree.c

index b63296e9abf486b02c194e816f033b973f873373..8e405a1011f4645e6c98dbd0ba81954badcc8ecb 100644 (file)
@@ -6608,7 +6608,7 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
  * 2) trimming the unallocated space on each device
  *
  * This will also continue trimming even if a block group or device encounters
- * an error.  The return value will be the last error, or 0 if nothing bad
+ * an error.  The return value will be the first error, or 0 if nothing bad
  * happens.
  */
 int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
@@ -6653,7 +6653,8 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
                                ret = btrfs_cache_block_group(cache, true);
                                if (ret) {
                                        bg_failed++;
-                                       bg_ret = ret;
+                                       if (!bg_ret)
+                                               bg_ret = ret;
                                        continue;
                                }
                        }
@@ -6666,7 +6667,8 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
                        trimmed += group_trimmed;
                        if (ret) {
                                bg_failed++;
-                               bg_ret = ret;
+                               if (!bg_ret)
+                                       bg_ret = ret;
                                continue;
                        }
                }
@@ -6674,7 +6676,7 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
 
        if (bg_failed)
                btrfs_warn(fs_info,
-                       "failed to trim %llu block group(s), last error %d",
+                       "failed to trim %llu block group(s), first error %d",
                        bg_failed, bg_ret);
 
        mutex_lock(&fs_devices->device_list_mutex);
@@ -6687,7 +6689,8 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
                trimmed += group_trimmed;
                if (ret) {
                        dev_failed++;
-                       dev_ret = ret;
+                       if (!dev_ret)
+                               dev_ret = ret;
                        continue;
                }
        }
@@ -6695,7 +6698,7 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
 
        if (dev_failed)
                btrfs_warn(fs_info,
-                       "failed to trim %llu device(s), last error %d",
+                       "failed to trim %llu device(s), first error %d",
                        dev_failed, dev_ret);
        range->len = trimmed;
        if (bg_ret)