Message ID | 7523436ccbf95d7fde690f41095637ce9d9fc1b4.1676124188.git.anand.jain@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs-progs: read device fsid from the sysfs | expand |
On Mon, Feb 13, 2023 at 05:37:42PM +0800, Anand Jain wrote: > The kernel commit a26d60dedf9a ("btrfs: sysfs: add devinfo/fsid to > retrieve actual fsid from the device" introduced a sysfs interface > to access the device's fsid from the kernel. This is a more > reliable method to obtain the fsid compared to reading the > superblock, and it even works if the device is not present. > Additionally, this sysfs interface can be read by non-root users. > > Therefore, it is recommended to utilize this new sysfs interface to > retrieve the fsid. > > Reviewed-by: Josef Bacik <josef@toxicpanda.com> > Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > cmds/filesystem-usage.c | 38 ++++++++++++++++++++++++++++++-------- > 1 file changed, 30 insertions(+), 8 deletions(-) > > diff --git a/cmds/filesystem-usage.c b/cmds/filesystem-usage.c > index bef9a1129a63..e7fa18dc82dc 100644 > --- a/cmds/filesystem-usage.c > +++ b/cmds/filesystem-usage.c > @@ -39,6 +39,7 @@ > #include "common/help.h" > #include "common/device-utils.h" > #include "common/messages.h" > +#include "common/path-utils.h" > #include "cmds/filesystem-usage.h" > #include "cmds/commands.h" > > @@ -701,14 +702,33 @@ out: > return ret; > } > > -static int device_is_seed(const char *dev_path, u8 *mnt_fsid) > +static int device_is_seed(int fd, const char *dev_path, u64 devid, u8 *mnt_fsid) > { > + char fsidparse[BTRFS_UUID_UNPARSED_SIZE]; > + char fsid_path[PATH_MAX]; > + char devid_str[20]; > uuid_t fsid; > - int ret; > + int ret = -1; > + int sysfs_fd; > + > + snprintf(devid_str, 20, "%llu", devid); > + /* devinfo/<devid>/fsid */ > + path_cat3_out(fsid_path, "devinfo", devid_str, "fsid"); This could potentially fail so the return value needs to be checked. > + > + /* /sys/fs/btrfs/<fsid>/devinfo/<devid>/fsid */ > + sysfs_fd = sysfs_open_fsid_file(fd, fsid_path); > + if (sysfs_fd >= 0) { > + sysfs_read_file(sysfs_fd, fsidparse, BTRFS_UUID_UNPARSED_SIZE); > + fsidparse[BTRFS_UUID_UNPARSED_SIZE - 1] = 0; > + ret = uuid_parse(fsidparse, fsid); > + close(sysfs_fd); > + } > > - ret = dev_to_fsid(dev_path, fsid); > - if (ret) > - return ret; > + if (ret) { > + ret = dev_to_fsid(dev_path, fsid); > + if (ret) > + return ret; > + }
diff --git a/cmds/filesystem-usage.c b/cmds/filesystem-usage.c index bef9a1129a63..e7fa18dc82dc 100644 --- a/cmds/filesystem-usage.c +++ b/cmds/filesystem-usage.c @@ -39,6 +39,7 @@ #include "common/help.h" #include "common/device-utils.h" #include "common/messages.h" +#include "common/path-utils.h" #include "cmds/filesystem-usage.h" #include "cmds/commands.h" @@ -701,14 +702,33 @@ out: return ret; } -static int device_is_seed(const char *dev_path, u8 *mnt_fsid) +static int device_is_seed(int fd, const char *dev_path, u64 devid, u8 *mnt_fsid) { + char fsidparse[BTRFS_UUID_UNPARSED_SIZE]; + char fsid_path[PATH_MAX]; + char devid_str[20]; uuid_t fsid; - int ret; + int ret = -1; + int sysfs_fd; + + snprintf(devid_str, 20, "%llu", devid); + /* devinfo/<devid>/fsid */ + path_cat3_out(fsid_path, "devinfo", devid_str, "fsid"); + + /* /sys/fs/btrfs/<fsid>/devinfo/<devid>/fsid */ + sysfs_fd = sysfs_open_fsid_file(fd, fsid_path); + if (sysfs_fd >= 0) { + sysfs_read_file(sysfs_fd, fsidparse, BTRFS_UUID_UNPARSED_SIZE); + fsidparse[BTRFS_UUID_UNPARSED_SIZE - 1] = 0; + ret = uuid_parse(fsidparse, fsid); + close(sysfs_fd); + } - ret = dev_to_fsid(dev_path, fsid); - if (ret) - return ret; + if (ret) { + ret = dev_to_fsid(dev_path, fsid); + if (ret) + return ret; + } if (memcmp(mnt_fsid, fsid, BTRFS_FSID_SIZE)) return 0; @@ -763,13 +783,15 @@ static int load_device_info(int fd, struct device_info **devinfo_ret, } /* - * Skip seed device by checking device's fsid (requires root). - * And we will skip only if dev_to_fsid is successful and dev + * Skip seed device by checking device's fsid (requires root if + * kernel is not patched to provide fsid from the sysfs). + * And we will skip only if device_is_seed is successful and dev * is a seed device. * Ignore any other error including -EACCES, which is seen when * a non-root process calls dev_to_fsid(path)->open(path). */ - ret = device_is_seed((const char *)dev_info.path, fi_args.fsid); + ret = device_is_seed(fd, (const char *)dev_info.path, i, + fi_args.fsid); if (!ret) continue;