From: Karel Zak Date: Tue, 30 Jun 2026 13:18:25 +0000 (+0200) Subject: libblkid: add blkid_probe_open_device() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8b6ca6fef9e17c195167d3622808cb411132eadb;p=thirdparty%2Futil-linux.git libblkid: add blkid_probe_open_device() Add a convenience function that opens a device and assigns it to the probe, using VFS operations if previously set. This enables the composable pattern: blkid_new_probe() → blkid_probe_set_vfs() → blkid_probe_open_device() Refactor blkid_new_probe_from_filename() to use it internally. Addresses: https://github.com/util-linux/util-linux/issues/4308 Signed-off-by: Karel Zak --- diff --git a/libblkid/docs/libblkid-sections.txt b/libblkid/docs/libblkid-sections.txt index 75b2b3a32..9a4ae2a54 100644 --- a/libblkid/docs/libblkid-sections.txt +++ b/libblkid/docs/libblkid-sections.txt @@ -61,6 +61,7 @@ blkid_probe_reset_buffers blkid_probe_reset_hints blkid_probe_set_device blkid_probe_set_hint +blkid_probe_open_device blkid_probe_set_sectorsize blkid_probe_set_vfs blkid_probe_step_back diff --git a/libblkid/src/blkid.h.in b/libblkid/src/blkid.h.in index adfd3c3a6..ee85ef015 100644 --- a/libblkid/src/blkid.h.in +++ b/libblkid/src/blkid.h.in @@ -262,6 +262,10 @@ struct ul_vfs_ops { extern int blkid_probe_set_vfs(blkid_probe pr, const struct ul_vfs_ops *ops) __ul_attribute__((nonnull(1))); +extern int blkid_probe_open_device(blkid_probe pr, const char *filename, + int flags) + __ul_attribute__((nonnull)); + extern dev_t blkid_probe_get_devno(blkid_probe pr) __ul_attribute__((nonnull)); diff --git a/libblkid/src/libblkid.sym b/libblkid/src/libblkid.sym index cf520d9b7..55c4e23ac 100644 --- a/libblkid/src/libblkid.sym +++ b/libblkid/src/libblkid.sym @@ -194,5 +194,6 @@ BLKID_2_40 { BLKID_2_43 { blkid_evaluate_tag2; + blkid_probe_open_device; blkid_probe_set_vfs; } BLKID_2_40; diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index 6fa8ba563..7f4c2791d 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -205,60 +205,82 @@ blkid_probe blkid_clone_probe(blkid_probe parent) return pr; } - - /** - * blkid_new_probe_from_filename: + * blkid_probe_open_device: + * @pr: probe * @filename: device or regular file + * @flags: open(2) flags or 0 for default (O_RDONLY|O_CLOEXEC|O_NONBLOCK) * - * This function is same as call open(filename), blkid_new_probe() and - * blkid_probe_set_device(pr, fd, 0, 0). + * Opens the @filename and assigns it to the probe. This is equivalent to + * calling open() and blkid_probe_set_device(), but uses VFS operations + * if previously set by blkid_probe_set_vfs(). + * + * This allows probe setup before the device is opened: + * + * blkid_new_probe() → blkid_probe_set_vfs() → blkid_probe_open_device() * * The @filename is closed by blkid_free_probe() or by the * blkid_probe_set_device() call. * - * Returns: a pointer to the newly allocated probe struct or NULL in case of - * error. + * Since: 2.43 + * + * Returns: 0 on success, or <0 in case of error. */ -blkid_probe blkid_new_probe_from_filename(const char *filename) +int blkid_probe_open_device(blkid_probe pr, const char *filename, int flags) { int fd; - blkid_probe pr = NULL; struct stat sb; - /* - * Check for hidden device-mapper devices (LVM internals, etc.) - * before open() to avoid bumping the kernel open count. A racing - * DM_DEVICE_REMOVE would otherwise see EBUSY. - * - * Use sysfs_devno_is_dm_hidden() rather than _dm_private() so that - * Stratis devices remain accessible to tools like mkfs.xfs that - * need to probe device geometry. - */ if (stat(filename, &sb) == 0 && S_ISBLK(sb.st_mode) && sysfs_devno_is_dm_hidden(sb.st_rdev, NULL)) { DBG(LOWPROBE, ul_debug("ignore hidden device mapper device")); errno = EINVAL; - return NULL; + return -EINVAL; } - fd = open(filename, O_RDONLY | O_CLOEXEC | O_NONBLOCK); + if (!flags) + flags = O_RDONLY | O_CLOEXEC | O_NONBLOCK; + + fd = ul_vfs_open(pr->vfs, filename, flags, 0); if (fd < 0) - return NULL; + return -errno; + + if (blkid_probe_set_device(pr, fd, 0, 0)) { + ul_vfs_close(pr->vfs, fd); + return -errno ? -errno : -EINVAL; + } + + pr->flags |= BLKID_FL_PRIVATE_FD; + return 0; +} + +/** + * blkid_new_probe_from_filename: + * @filename: device or regular file + * + * This function is same as call open(filename), blkid_new_probe() and + * blkid_probe_set_device(pr, fd, 0, 0). + * + * The @filename is closed by blkid_free_probe() or by the + * blkid_probe_set_device() call. + * + * Returns: a pointer to the newly allocated probe struct or NULL in case of + * error. + */ +blkid_probe blkid_new_probe_from_filename(const char *filename) +{ + blkid_probe pr; pr = blkid_new_probe(); if (!pr) - goto err; + return NULL; - if (blkid_probe_set_device(pr, fd, 0, 0)) - goto err; + if (blkid_probe_open_device(pr, filename, 0)) { + blkid_free_probe(pr); + return NULL; + } - pr->flags |= BLKID_FL_PRIVATE_FD; return pr; -err: - close(fd); - blkid_free_probe(pr); - return NULL; } /**