btrfs-progs: dev usage: don't print incorrect unallocated data

If "btrfs dev us" is invoked by a not root user, it is impossible to
collect the chunk info data (not enough privileges). This causes
"btrfs dev us" to print as "Unallocated" value the size of the disk.

This patch handles the case where print_device_chunks() is invoked
without the chunk info data, printing "Unallocated N/A":

Before the patch:

  $ btrfs dev us t/
  WARNING: cannot read detailed chunk info, per-device usage will not be shown, run as root
  /dev/loop0, ID: 1
     Device size:             5.00GiB
     Device slack:              0.00B
     Unallocated:             5.00GiB  <-- Wrong

  $ sudo btrfs dev us t/
  [sudo] password for ghigo:
  /dev/loop0, ID: 1
     Device size:             5.00GiB
     Device slack:              0.00B
     Data,single:             8.00MiB
     Metadata,DUP:          512.00MiB
     System,DUP:             16.00MiB
     Unallocated:             4.48GiB  <-- Correct

After the patch:

  $ ./btrfs dev us /tmp/t/
  WARNING: cannot read detailed chunk info, per-device usage will not be shown, run as root
  /dev/loop0, ID: 1
     Device size:             5.00GiB
     Device slack:              0.00B
     Unallocated:                 N/A

  $ sudo ./btrfs dev us /tmp/t/
  [sudo] password for ghigo:
  /dev/loop0, ID: 1
     Device size:             5.00GiB
     Device slack:              0.00B
     Data,single:             8.00MiB
     Metadata,DUP:          512.00MiB
     System,DUP:             16.00MiB
     Unallocated:             4.48GiB

Reviewed-by: Anand Jain <anand.jain@oracle.com>
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 20:53:44 +01:00 committed by David Sterba
parent 389c959d6d
commit c653596cff

View file

@ -1302,10 +1302,19 @@ void print_device_chunks(const struct device_info *devinfo,
allocated += size;
}
pr_verbose(LOG_DEFAULT, " Unallocated: %*s%10s\n",
(int)(20 - strlen("Unallocated")), "",
pretty_size_mode(devinfo->size - allocated,
unit_mode | UNITS_NEGATIVE));
/*
* If chunkinfos is empty, we cannot compute the unallocated size, so
* don't print incorrect data.
*/
if (chunkinfos->length == 0)
pr_verbose(LOG_DEFAULT, " Unallocated: %*s%10s\n",
(int)(20 - strlen("Unallocated")), "", "N/A");
else
pr_verbose(LOG_DEFAULT, " Unallocated: %*s%10s\n",
(int)(20 - strlen("Unallocated")), "",
pretty_size_mode(devinfo->size - allocated,
unit_mode | UNITS_NEGATIVE));
}
void print_device_sizes(const struct device_info *devinfo, unsigned unit_mode)