]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: add blkid_probe_set_vfs() for pluggable I/O
authorKarel Zak <kzak@redhat.com>
Tue, 30 Jun 2026 12:38:56 +0000 (14:38 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 9 Jul 2026 10:18:04 +0000 (12:18 +0200)
Add public API to set custom VFS I/O operations on a blkid probe.
This allows callers (e.g., systemd fibers) to replace standard
read/write/lseek/open/close/fsync with custom implementations.

The ops struct is copied into a private allocation owned by the
probe. NULL function pointers fall back to standard syscalls.
Passing NULL resets to defaults.

New public symbol: blkid_probe_set_vfs()
New struct in public header: struct ul_vfs_ops (with include guard
shared with include/vfs.h)

Addresses: https://github.com/util-linux/util-linux/issues/4308
Signed-off-by: Karel Zak <kzak@redhat.com>
libblkid/docs/libblkid-sections.txt
libblkid/src/blkid.h.in
libblkid/src/blkidP.h
libblkid/src/libblkid.sym
libblkid/src/probe.c

index 60a43b5024af88d0b18dc13e3e759af386bf692c..75b2b3a320f744334379325cd42c69e91bed4eb2 100644 (file)
@@ -62,6 +62,7 @@ blkid_probe_reset_hints
 blkid_probe_set_device
 blkid_probe_set_hint
 blkid_probe_set_sectorsize
+blkid_probe_set_vfs
 blkid_probe_step_back
 blkid_reset_probe
 BLKID_PROBE_OK
index 8dfea21523e2ca2d96953f6e7add5907bad17a47..adfd3c3a6313efdcca40edcbc2253f72d504c0c6 100644 (file)
@@ -243,6 +243,25 @@ extern int blkid_probe_set_device(blkid_probe pr, int fd,
                        blkid_loff_t off, blkid_loff_t size)
                        __ul_attribute__((nonnull));
 
+#ifndef UL_VFS_OPS_DEFINED
+#define UL_VFS_OPS_DEFINED
+
+struct ul_vfs_ops {
+       size_t size;
+
+       ssize_t (*vfs_read)(int fd, void *buf, size_t count);
+       ssize_t (*vfs_write)(int fd, const void *buf, size_t count);
+       int     (*vfs_open)(const char *pathname, int flags, mode_t mode);
+       int     (*vfs_close)(int fd);
+       off_t   (*vfs_lseek)(int fd, off_t offset, int whence);
+       int     (*vfs_fsync)(int fd);
+};
+
+#endif /* UL_VFS_OPS_DEFINED */
+
+extern int blkid_probe_set_vfs(blkid_probe pr, const struct ul_vfs_ops *ops)
+                       __ul_attribute__((nonnull(1)));
+
 extern dev_t blkid_probe_get_devno(blkid_probe pr)
                        __ul_attribute__((nonnull));
 
index 753dbb58f5650fe9a9b61b293f5764de7b653029..66ef69a8ae8ca2e3ee410d314f8151d7713bb0e5 100644 (file)
@@ -32,6 +32,7 @@
 #include "blkdev.h"
 
 #include "debug.h"
+#include "vfs.h"
 #include "blkid.h"
 #include "list.h"
 #include "encode.h"
@@ -232,6 +233,8 @@ struct blkid_struct_probe
 
        struct blkid_struct_probe *parent;      /* for clones */
        struct blkid_struct_probe *disk_probe;  /* whole-disk probing */
+
+       struct ul_vfs_ops       *vfs;           /* pluggable I/O ops (owned, or NULL) */
 };
 
 /* private flags library flags */
index 01b6170f9c65ae83dfe73c05261439565e07ebf9..cf520d9b71a42ac371b89708fafbf901b3e1dbea 100644 (file)
@@ -194,4 +194,5 @@ BLKID_2_40 {
 
 BLKID_2_43 {
     blkid_evaluate_tag2;
+    blkid_probe_set_vfs;
 } BLKID_2_40;
index 45691f4ad8660f8de489c056117ca30f1e793762..3464a3736e89e1b6198077d4192549dbd1a40fad 100644 (file)
@@ -2244,6 +2244,45 @@ int blkid_probe_set_sectorsize(blkid_probe pr, unsigned int sz)
        return 0;
 }
 
+/**
+ * blkid_probe_set_vfs:
+ * @pr: probe
+ * @ops: VFS operations or NULL to reset to defaults
+ *
+ * Sets custom I/O operations for the probe. This allows replacing
+ * standard read/write/lseek/etc. with custom implementations
+ * (e.g., fiber-aware I/O).
+ *
+ * The @ops struct is copied into a private allocation owned by the
+ * probe. The caller sets ops->size to sizeof(struct ul_vfs_ops) to
+ * enable forward/backward compatibility. NULL function pointers fall
+ * back to standard syscalls. Passing @ops as NULL frees the private
+ * copy and resets the probe to default (direct syscall) I/O.
+ *
+ * Note: blkid_new_probe_from_filename() opens the device before VFS
+ * can be set. VFS users should use blkid_new_probe(), then
+ * blkid_probe_set_vfs(), then blkid_probe_open_device().
+ *
+ * Since: 2.43
+ *
+ * Returns: 0 on success, or <0 in case of error.
+ */
+int blkid_probe_set_vfs(blkid_probe pr, const struct ul_vfs_ops *ops)
+{
+       if (!ops) {
+               free(pr->vfs);
+               pr->vfs = NULL;
+               return 0;
+       }
+       if (!pr->vfs) {
+               pr->vfs = calloc(1, sizeof(*pr->vfs));
+               if (!pr->vfs)
+                       return -ENOMEM;
+       }
+       ul_vfs_init(pr->vfs, ops);
+       return 0;
+}
+
 /**
  * blkid_probe_get_sectors:
  * @pr: probe