Skip to content

Commit 0c646f7

Browse files
raczzoliadam900710
authored andcommitted
btrfs-progs: fix the wrong size from device_get_partition_size_sysfs()
[BUG] When an unprivileged user, who can not access the block device, run "btrfs dev usage", it's very common to result the following incorrect output: $ btrfs dev usage /mnt/btrfs/ WARNING: cannot read detailed chunk info, per-device usage will not be shown, run as root /dev/mapper/test-scratch1, ID: 1 Device size: 20.00MiB <<< Device slack: 16.00EiB <<< Unallocated: N/A Note if the unprivileged user has read access to the raw block file, it will work as expected: $ btrfs dev usage /mnt/btrfs/ WARNING: cannot read detailed chunk info, per-device usage will not be shown, run as root /dev/mapper/test-scratch1, ID: 1 Device size: 10.00GiB Device slack: 0.00B Unallocated: N/A [CAUSE] When device_get_partition_size() is called, firstly the function checks if we can do a read-only open() on the block device. However under most distros, block devices are only accessible by root and "disk" group. If the unprivileged user is not in "disk" group, the open() will fail and we have to fallback to device_get_partition_size_sysfs() as the fallback. The function device_get_partition_size_sysfs() will use "/sys/block/<device>/size" as the size of the disk. But according to the kernel source code, the "size" attribute is implemented by returning bdev_nr_sectors(), and that result is always in sector unit (512 bytes). So if device_get_partition_size_sysfs() returns the value directly, it's 512 times smaller than the original size, causing errors. [FIX] Just do the proper left shift to return size in bytes. Issue: #979 Signed-off-by: Qu Wenruo <[email protected]>
1 parent 6f29461 commit 0c646f7

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

common/device-utils.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,9 @@ static u64 device_get_partition_size_sysfs(const char *dev)
369369
return 0;
370370
}
371371
close(sysfd);
372-
return size;
372+
373+
/* <device>/size value is in sector (512B) unit. */
374+
return size << SECTOR_SHIFT;
373375
}
374376

375377
u64 device_get_partition_size(const char *dev)

0 commit comments

Comments
 (0)