linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] Fix init for device stats for seed devices
@ 2020-09-22 21:18 Josef Bacik
  2020-09-22 21:18 ` [PATCH v3 1/2] btrfs: init " Josef Bacik
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Josef Bacik @ 2020-09-22 21:18 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

v2->v3:
- fixed the name and arguments in the first patch.
- use goto out for the error case with seed devices.

v1->v2:
- Rework initial fix to work with the new seed_list.
- Add a follow up patch to address the fact that we were ignoring errors on
  reading the device tree.

Hello,

We see a lot of messages in the fleet where we use seed devices because we're
not init'ing the stats for seed devices properly.  I have an xfstest that shows
this (which I need to update), and this patch fixes the problem.  It's
relatively straightforward, simply init the stats on seed devices at the same
time we init them on our primary devices.  Thanks,

Josef

Josef Bacik (2):
  btrfs: init device stats for seed devices
  btrfs: return error if we're unable to read device stats

 fs/btrfs/volumes.c | 93 +++++++++++++++++++++++++++-------------------
 1 file changed, 54 insertions(+), 39 deletions(-)

-- 
2.26.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 1/2] btrfs: init device stats for seed devices
  2020-09-22 21:18 [PATCH v3 0/2] Fix init for device stats for seed devices Josef Bacik
@ 2020-09-22 21:18 ` Josef Bacik
  2020-09-22 21:18 ` [PATCH v3 2/2] btrfs: return error if we're unable to read device stats Josef Bacik
  2020-09-24 15:22 ` [PATCH v3 0/2] Fix init for device stats for seed devices David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: Josef Bacik @ 2020-09-22 21:18 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

We recently started recording device stats across the fleet, and noticed
a large increase in messages such as this

BTRFS warning (device dm-0): get dev_stats failed, not yet valid

on our tiers that use seed devices for their root devices.  This is
because we do not initialize the device stats for any seed devices if we
have a sprout device and mount using that sprout device.  The basic
steps for reproducing are

mkfs seed device
mount seed device
fill seed device
umount seed device
btrfstune -S 1 seed device
mount seed device
btrfs device add -f sprout device /mnt/wherever
umount /mnt/wherever
mount sprout device /mnt/wherever
btrfs device stats /mnt/wherever

This will fail with the above message in dmesg.

Fix this by iterating over the fs_devices->seed if they exist in
btrfs_init_dev_stats.  This fixed the problem and properly reports the
stats for both devices.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/volumes.c | 89 +++++++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 41 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 6c7c8819cb31..ed6de5817efb 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -7223,61 +7223,68 @@ static void btrfs_set_dev_stats_value(struct extent_buffer *eb,
 			    sizeof(val));
 }
 
-int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info)
+static void init_dev_stats(struct btrfs_device *device,
+			   struct btrfs_path *path)
 {
-	struct btrfs_key key;
-	struct btrfs_root *dev_root = fs_info->dev_root;
-	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
+	struct btrfs_root *dev_root = device->fs_info->dev_root;
+	struct btrfs_dev_stats_item *ptr;
 	struct extent_buffer *eb;
-	int slot;
-	int ret = 0;
+	struct btrfs_key key;
+	int item_size;
+	int i, ret, slot;
+
+	key.objectid = BTRFS_DEV_STATS_OBJECTID;
+	key.type = BTRFS_PERSISTENT_ITEM_KEY;
+	key.offset = device->devid;
+	ret = btrfs_search_slot(NULL, dev_root, &key, path, 0, 0);
+	if (ret) {
+		for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++)
+			btrfs_dev_stat_set(device, i, 0);
+		device->dev_stats_valid = 1;
+		btrfs_release_path(path);
+		return;
+	}
+	slot = path->slots[0];
+	eb = path->nodes[0];
+	item_size = btrfs_item_size_nr(eb, slot);
+
+	ptr = btrfs_item_ptr(eb, slot,
+			     struct btrfs_dev_stats_item);
+
+	for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++) {
+		if (item_size >= (1 + i) * sizeof(__le64))
+			btrfs_dev_stat_set(device, i,
+					   btrfs_dev_stats_value(eb, ptr, i));
+		else
+			btrfs_dev_stat_set(device, i, 0);
+	}
+
+	device->dev_stats_valid = 1;
+	btrfs_dev_stat_print_on_load(device);
+	btrfs_release_path(path);
+}
+
+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 i;
 
 	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) {
-		int item_size;
-		struct btrfs_dev_stats_item *ptr;
-
-		key.objectid = BTRFS_DEV_STATS_OBJECTID;
-		key.type = BTRFS_PERSISTENT_ITEM_KEY;
-		key.offset = device->devid;
-		ret = btrfs_search_slot(NULL, dev_root, &key, path, 0, 0);
-		if (ret) {
-			for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++)
-				btrfs_dev_stat_set(device, i, 0);
-			device->dev_stats_valid = 1;
-			btrfs_release_path(path);
-			continue;
-		}
-		slot = path->slots[0];
-		eb = path->nodes[0];
-		item_size = btrfs_item_size_nr(eb, slot);
-
-		ptr = btrfs_item_ptr(eb, slot,
-				     struct btrfs_dev_stats_item);
-
-		for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++) {
-			if (item_size >= (1 + i) * sizeof(__le64))
-				btrfs_dev_stat_set(device, i,
-					btrfs_dev_stats_value(eb, ptr, i));
-			else
-				btrfs_dev_stat_set(device, i, 0);
-		}
-
-		device->dev_stats_valid = 1;
-		btrfs_dev_stat_print_on_load(device);
-		btrfs_release_path(path);
+	list_for_each_entry(device, &fs_devices->devices, dev_list)
+		init_dev_stats(device, path);
+	list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list) {
+		list_for_each_entry(device, &seed_devs->devices, dev_list)
+			init_dev_stats(device, path);
 	}
 	mutex_unlock(&fs_devices->device_list_mutex);
 
 	btrfs_free_path(path);
-	return ret < 0 ? ret : 0;
+	return 0;
 }
 
 static int update_dev_stat_item(struct btrfs_trans_handle *trans,
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] btrfs: return error if we're unable to read device stats
  2020-09-22 21:18 [PATCH v3 0/2] Fix init for device stats for seed devices Josef Bacik
  2020-09-22 21:18 ` [PATCH v3 1/2] btrfs: init " Josef Bacik
@ 2020-09-22 21:18 ` Josef Bacik
  2020-09-24 15:22 ` [PATCH v3 0/2] Fix init for device stats for seed devices David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: Josef Bacik @ 2020-09-22 21:18 UTC (permalink / raw)
  To: linux-btrfs, kernel-team

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.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/volumes.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index ed6de5817efb..5c7b0c0e9408 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -7223,8 +7223,7 @@ static void btrfs_set_dev_stats_value(struct extent_buffer *eb,
 			    sizeof(val));
 }
 
-static void init_dev_stats(struct btrfs_device *device,
-			   struct btrfs_path *path)
+static int init_dev_stats(struct btrfs_device *device, struct btrfs_path *path)
 {
 	struct btrfs_root *dev_root = device->fs_info->dev_root;
 	struct btrfs_dev_stats_item *ptr;
@@ -7242,7 +7241,7 @@ static void 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];
@@ -7262,6 +7261,7 @@ static void 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)
@@ -7269,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)
-		init_dev_stats(device, path);
+	list_for_each_entry(device, &fs_devices->devices, dev_list) {
+		ret = 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)
-			init_dev_stats(device, path);
+		list_for_each_entry(device, &seed_devs->devices, dev_list) {
+			ret = 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,
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 0/2] Fix init for device stats for seed devices
  2020-09-22 21:18 [PATCH v3 0/2] Fix init for device stats for seed devices Josef Bacik
  2020-09-22 21:18 ` [PATCH v3 1/2] btrfs: init " Josef Bacik
  2020-09-22 21:18 ` [PATCH v3 2/2] btrfs: return error if we're unable to read device stats Josef Bacik
@ 2020-09-24 15:22 ` David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2020-09-24 15:22 UTC (permalink / raw)
  To: Josef Bacik; +Cc: linux-btrfs, kernel-team

On Tue, Sep 22, 2020 at 05:18:28PM -0400, Josef Bacik wrote:
> v2->v3:
> - fixed the name and arguments in the first patch.
> - use goto out for the error case with seed devices.
> 
> v1->v2:
> - Rework initial fix to work with the new seed_list.
> - Add a follow up patch to address the fact that we were ignoring errors on
>   reading the device tree.
> 
> Hello,
> 
> We see a lot of messages in the fleet where we use seed devices because we're
> not init'ing the stats for seed devices properly.  I have an xfstest that shows
> this (which I need to update), and this patch fixes the problem.  It's
> relatively straightforward, simply init the stats on seed devices at the same
> time we init them on our primary devices.  Thanks,
> 
> Josef
> 
> Josef Bacik (2):
>   btrfs: init device stats for seed devices
>   btrfs: return error if we're unable to read device stats

Added to misc-next, thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-09-24 15:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-22 21:18 [PATCH v3 0/2] Fix init for device stats for seed devices Josef Bacik
2020-09-22 21:18 ` [PATCH v3 1/2] btrfs: init " Josef Bacik
2020-09-22 21:18 ` [PATCH v3 2/2] btrfs: return error if we're unable to read device stats Josef Bacik
2020-09-24 15:22 ` [PATCH v3 0/2] Fix init for device stats for seed devices David Sterba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).