summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2020-09-18 16:44:33 -0400
committerDavid Sterba <dsterba@suse.com>2020-10-07 12:17:58 +0200
commit92e26df43b1a9725c205a7e4416240ce72eac4a3 (patch)
treeea45b9210a2421ca13e04ed5a53982ee46c377f8
parent124604eb50f88e6c1ff6587bdd2fc09bea810b32 (diff)
downloadlinux-92e26df43b1a9725c205a7e4416240ce72eac4a3.tar.bz2
btrfs: return error if we're unable to read device stats
I noticed when fixing device stats for seed devices that we simply threw away the return value from btrfs_search_slot(). This is because we may not have stat items, but we could very well get an error, and thus miss reporting the error up the chain. Fix this by returning ret if it's an actual error, and then stop trying to init the rest of the devices stats and return the error up the chain. Reviewed-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/volumes.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index d25650600179..46f4efd58652 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -7223,8 +7223,8 @@ static void btrfs_set_dev_stats_value(struct extent_buffer *eb,
sizeof(val));
}
-static void btrfs_device_init_dev_stats(struct btrfs_device *device,
- struct btrfs_path *path)
+static int btrfs_device_init_dev_stats(struct btrfs_device *device,
+ struct btrfs_path *path)
{
struct btrfs_dev_stats_item *ptr;
struct extent_buffer *eb;
@@ -7241,7 +7241,7 @@ static void btrfs_device_init_dev_stats(struct btrfs_device *device,
btrfs_dev_stat_set(device, i, 0);
device->dev_stats_valid = 1;
btrfs_release_path(path);
- return;
+ return ret < 0 ? ret : 0;
}
slot = path->slots[0];
eb = path->nodes[0];
@@ -7260,6 +7260,8 @@ static void btrfs_device_init_dev_stats(struct btrfs_device *device,
device->dev_stats_valid = 1;
btrfs_dev_stat_print_on_load(device);
btrfs_release_path(path);
+
+ return 0;
}
int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info)
@@ -7267,22 +7269,30 @@ int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info)
struct btrfs_fs_devices *fs_devices = fs_info->fs_devices, *seed_devs;
struct btrfs_device *device;
struct btrfs_path *path = NULL;
+ int ret = 0;
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
mutex_lock(&fs_devices->device_list_mutex);
- list_for_each_entry(device, &fs_devices->devices, dev_list)
- btrfs_device_init_dev_stats(device, path);
+ list_for_each_entry(device, &fs_devices->devices, dev_list) {
+ ret = btrfs_device_init_dev_stats(device, path);
+ if (ret)
+ goto out;
+ }
list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list) {
- list_for_each_entry(device, &seed_devs->devices, dev_list)
- btrfs_device_init_dev_stats(device, path);
+ list_for_each_entry(device, &seed_devs->devices, dev_list) {
+ ret = btrfs_device_init_dev_stats(device, path);
+ if (ret)
+ goto out;
+ }
}
+out:
mutex_unlock(&fs_devices->device_list_mutex);
btrfs_free_path(path);
- return 0;
+ return ret;
}
static int update_dev_stat_item(struct btrfs_trans_handle *trans,