]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/path: add VFS support
authorKarel Zak <kzak@redhat.com>
Tue, 30 Jun 2026 15:08:53 +0000 (17:08 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 9 Jul 2026 10:18:04 +0000 (12:18 +0200)
Add ul_path_refer_vfs() to set a borrowed VFS ops pointer on
path_cxt. Replace direct I/O in the read/write/fopen paths with
VFS dispatch:

 - ul_path_read(): ul_vfs_read_all + ul_vfs_close
 - ul_path_write_string(): ul_vfs_write_all + ul_vfs_close
 - ul_path_write_s64/u64(): ul_vfs_write_all + ul_vfs_close
 - ul_path_fopen(): ul_vfs_fdopen (fopencookie when VFS set)

Addresses: https://github.com/util-linux/util-linux/issues/4308
Signed-off-by: Karel Zak <kzak@redhat.com>
include/path.h
lib/path.c

index 84bd42c6d36fdc4dbcb05ee01e3647e6b3138aff..a54651c426117718787e8471904c5feb617aa20d 100644 (file)
@@ -25,6 +25,8 @@ struct path_cxt {
        void    *dialect;
        void    (*free_dialect)(struct path_cxt *);
        int     (*redirect_on_enoent)(struct path_cxt *, const char *, int *);
+
+       const struct ul_vfs_ops *vfs;
 };
 
 struct path_cxt *ul_new_path(const char *dir, ...)
@@ -44,6 +46,9 @@ int ul_path_set_dialect(struct path_cxt *pc, void *data, void free_data(struct p
 void *ul_path_get_dialect(struct path_cxt *pc);
 
 int ul_path_set_enoent_redirect(struct path_cxt *pc, int (*func)(struct path_cxt *, const char *, int *));
+
+struct ul_vfs_ops;
+void ul_path_refer_vfs(struct path_cxt *pc, const struct ul_vfs_ops *vfs);
 int ul_path_get_dirfd(struct path_cxt *pc);
 void ul_path_close_dirfd(struct path_cxt *pc);
 int ul_path_isopen_dirfd(struct path_cxt *pc);
index 65a7b5648de37228655aa0cc865c0193110e8942..90aac2058034143a7ccea5bf6f43f2831df492f0 100644 (file)
@@ -102,6 +102,12 @@ void ul_unref_path(struct path_cxt *pc)
        }
 }
 
+void ul_path_refer_vfs(struct path_cxt *pc, const struct ul_vfs_ops *vfs)
+{
+       if (pc)
+               pc->vfs = vfs;
+}
+
 int ul_path_set_prefix(struct path_cxt *pc, const char *prefix)
 {
        char *p = NULL;
@@ -511,7 +517,7 @@ FILE *ul_path_fopen(struct path_cxt *pc, const char *mode, const char *path)
        if (fd < 0)
                return NULL;
 
-       return fdopen(fd, mode);
+       return ul_vfs_fdopen(pc ? pc->vfs : NULL, fd, mode);
 }
 
 
@@ -649,10 +655,10 @@ int ul_path_read(struct path_cxt *pc, char *buf, size_t len, const char *path)
                return -errno;
 
        DBG(CXT, ul_debug(" reading '%s'", path));
-       rc = ul_read_all(fd, buf, len);
+       rc = ul_vfs_read_all(pc ? pc->vfs : NULL, fd, buf, len);
 
        errsv = errno;
-       close(fd);
+       ul_vfs_close(pc ? pc->vfs : NULL, fd);
        errno = errsv;
        return rc;
 }
@@ -926,10 +932,10 @@ int ul_path_write_string(struct path_cxt *pc, const char *str, const char *path)
        if (fd < 0)
                return -errno;
 
-       rc = ul_write_all(fd, str, strlen(str));
+       rc = ul_vfs_write_all(pc ? pc->vfs : NULL, fd, str, strlen(str));
 
        errsv = errno;
-       close(fd);
+       ul_vfs_close(pc ? pc->vfs : NULL, fd);
        errno = errsv;
        return rc;
 }
@@ -960,10 +966,10 @@ int ul_path_write_s64(struct path_cxt *pc, int64_t num, const char *path)
        if (len < 0 || (size_t) len >= sizeof(buf))
                rc = len < 0 ? -errno : -E2BIG;
        else
-               rc = ul_write_all(fd, buf, len);
+               rc = ul_vfs_write_all(pc ? pc->vfs : NULL, fd, buf, len);
 
        errsv = errno;
-       close(fd);
+       ul_vfs_close(pc ? pc->vfs : NULL, fd);
        errno = errsv;
        return rc;
 }
@@ -982,10 +988,10 @@ int ul_path_write_u64(struct path_cxt *pc, uint64_t num, const char *path)
        if (len < 0 || (size_t) len >= sizeof(buf))
                rc = len < 0 ? -errno : -E2BIG;
        else
-               rc = ul_write_all(fd, buf, len);
+               rc = ul_vfs_write_all(pc ? pc->vfs : NULL, fd, buf, len);
 
        errsv = errno;
-       close(fd);
+       ul_vfs_close(pc ? pc->vfs : NULL, fd);
        errno = errsv;
        return rc;
 }