diff mbox series

btrfs fi us: wrong values in case of raid5 and not root

Message ID e8659631b0481defe32fcde435432da630af6789.1704400902.git.kreijack@inwind.it (mailing list archive)
State New, archived
Headers show
Series btrfs fi us: wrong values in case of raid5 and not root | expand

Commit Message

Goffredo Baroncelli Jan. 4, 2024, 8:41 p.m. UTC
From: Goffredo Baroncelli <kreijack@inwind.it>

In case of a raid5/6 filesystem 'btrfs fi us' returns wrong values
without the root capabilities.

$ sudo btrfs fi us /tmp/raid5fs  # as root
Overall:
    Device size:                   3.00GiB
    Device allocated:              1.51GiB		<--- OK
    Device unallocated:            1.49GiB		<--- OK
    Device missing:                  0.00B
    Device slack:                    0.00B
    Used:                        769.03MiB		<--- OK
    Free (estimated):              1.32GiB      (min: 1.32GiB) <-OK
    Free (statfs, df):             1.32GiB
    Data ratio:                       1.50		<--- OK
    Metadata ratio:                   1.50		<--- OK
    Global reserve:                5.50MiB      (used: 0.00B)
    Multiple profiles:                  no
[...]

$ btrfs fi us /tmp/raid5fs      # as user
WARNING: cannot read detailed chunk info, per-device usage will not be shown, run as root
Overall:
    Device size:                   3.00GiB
    Device allocated:                0.00B		<--- WRONG
    Device unallocated:            3.00GiB		<--- WRONG
    Device missing:                  0.00B
    Device slack:                    0.00B
    Used:                            0.00B		<--- WRONG
    Free (estimated):                0.00B      (min: 8.00EiB) <- WRONG
    Free (statfs, df):             1.32GiB
    Data ratio:                       0.00		<--- WRONG
    Metadata ratio:                   0.00		<--- WRONG
    Global reserve:                5.50MiB      (used: 0.00B)
    Multiple profiles:                  no
[...]

The reason is that the BTRFS_IOC_SPACE_INFO ioctl doesn't return enough
info. To bypass it a scan of the chunks is required when a raid5/6
profile is present.

To avoid providing wrong information, in case of a raid5/6 filesystem
without the root capabilities the "btrfs fi us" is not executed at all
and a warning with a suggestion to run it as root is printed.

$ ./btrfs fi us /tmp/t/
WARNING: cannot read detailed chunk info, per-device usage will not be shown, run as root
WARNING: due to the presence of a raid5/raid6 profile, we cannots compute some values;
WARNING: run as root instead.
$

Signed-off-by: Goffredo Baroncelli <kreijack@libero.it>
---
 cmds/filesystem-usage.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

Comments

David Sterba Jan. 17, 2024, 7:58 p.m. UTC | #1
On Thu, Jan 04, 2024 at 09:41:42PM +0100, Goffredo Baroncelli wrote:
> From: Goffredo Baroncelli <kreijack@inwind.it>
> 
> In case of a raid5/6 filesystem 'btrfs fi us' returns wrong values
> without the root capabilities.
> 
> $ sudo btrfs fi us /tmp/raid5fs  # as root
> Overall:
>     Device size:                   3.00GiB
>     Device allocated:              1.51GiB		<--- OK
>     Device unallocated:            1.49GiB		<--- OK
>     Device missing:                  0.00B
>     Device slack:                    0.00B
>     Used:                        769.03MiB		<--- OK
>     Free (estimated):              1.32GiB      (min: 1.32GiB) <-OK
>     Free (statfs, df):             1.32GiB
>     Data ratio:                       1.50		<--- OK
>     Metadata ratio:                   1.50		<--- OK
>     Global reserve:                5.50MiB      (used: 0.00B)
>     Multiple profiles:                  no
> [...]
> 
> $ btrfs fi us /tmp/raid5fs      # as user
> WARNING: cannot read detailed chunk info, per-device usage will not be shown, run as root
> Overall:
>     Device size:                   3.00GiB
>     Device allocated:                0.00B		<--- WRONG
>     Device unallocated:            3.00GiB		<--- WRONG
>     Device missing:                  0.00B
>     Device slack:                    0.00B
>     Used:                            0.00B		<--- WRONG
>     Free (estimated):                0.00B      (min: 8.00EiB) <- WRONG
>     Free (statfs, df):             1.32GiB
>     Data ratio:                       0.00		<--- WRONG
>     Metadata ratio:                   0.00		<--- WRONG
>     Global reserve:                5.50MiB      (used: 0.00B)
>     Multiple profiles:                  no
> [...]
> 
> The reason is that the BTRFS_IOC_SPACE_INFO ioctl doesn't return enough
> info. To bypass it a scan of the chunks is required when a raid5/6
> profile is present.
> 
> To avoid providing wrong information, in case of a raid5/6 filesystem
> without the root capabilities the "btrfs fi us" is not executed at all
> and a warning with a suggestion to run it as root is printed.
> 
> $ ./btrfs fi us /tmp/t/
> WARNING: cannot read detailed chunk info, per-device usage will not be shown, run as root
> WARNING: due to the presence of a raid5/raid6 profile, we cannots compute some values;
> WARNING: run as root instead.
> $
> 
> Signed-off-by: Goffredo Baroncelli <kreijack@libero.it>

Added to devel, thanks.
diff mbox series

Patch

diff --git a/cmds/filesystem-usage.c b/cmds/filesystem-usage.c
index 015c401e..9ba03d46 100644
--- a/cmds/filesystem-usage.c
+++ b/cmds/filesystem-usage.c
@@ -478,6 +478,8 @@  static int print_filesystem_usage_overall(int fd, const struct array *chunkinfos
 	bool mixed = false;
 	struct statvfs statvfs_buf;
 	struct btrfs_ioctl_feature_flags feature_flags;
+	bool raid56 = false;
+	bool unreliable_allocated = false;
 
 	sargs = load_space_info(fd, path);
 	if (!sargs) {
@@ -518,8 +520,10 @@  static int print_filesystem_usage_overall(int fd, const struct array *chunkinfos
 		 * computed separately. Setting ratio to 0 will not account
 		 * the chunks in this loop.
 		 */
-		if (flags & BTRFS_BLOCK_GROUP_RAID56_MASK)
+		if (flags & BTRFS_BLOCK_GROUP_RAID56_MASK) {
 			ratio = 0;
+			raid56 = true;
+		}
 
 		if (ratio > max_data_ratio)
 			max_data_ratio = ratio;
@@ -610,6 +614,20 @@  static int print_filesystem_usage_overall(int fd, const struct array *chunkinfos
 		ret = 0;
 	}
 
+	/*
+	 * if we don't have any chunk information (e.g. due to missing
+	 * privileges) and is present a raid56 profile, the computation
+	 * of 'unallocated', "data/metadata ratio", "free estimated" are
+	 * wrong.
+	 */
+	unreliable_allocated = raid56 && chunkinfos->length == 0;
+	if (unreliable_allocated) {
+		warning("due to the presence of a raid5/raid6 profile, we cannots compute some values;");
+		warning("run as root instead.");
+		ret = 1;
+		goto exit;
+	}
+
 	pr_verbose(LOG_DEFAULT, "Overall:\n");
 
 	pr_verbose(LOG_DEFAULT, "    Device size:\t\t%*s\n", width,