btrfs-progs: fi usage: wrong values in case of raid56 and not root

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
information. 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>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Goffredo Baroncelli 2024-01-04 21:41:42 +01:00 committed by David Sterba
parent c653596cff
commit fdf7f35d3e

View File

@ -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,18 @@ 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 there's a raid56 profile, the computation of
* "unallocated", "data/metadata ratio", "free estimated" are wrong.
*/
unreliable_allocated = (raid56 && chunkinfos->length == 0);
if (unreliable_allocated) {
warning("radid56 found, we cannots compute some values, run as root if needed");
ret = 1;
goto exit;
}
pr_verbose(LOG_DEFAULT, "Overall:\n");
pr_verbose(LOG_DEFAULT, " Device size:\t\t%*s\n", width,