[PATCH v1] erofs-utils: add hybrid source support for local metadata and gzran
Gao Xiang
hsiangkao at linux.alibaba.com
Sun Sep 28 14:07:08 AEST 2025
On 2025/9/28 11:32, ChengyuZhu6 wrote:
> From: Chengyu Zhu <hudsonzhu at tencent.com>
>
> Add support for combining local metadata files with remote OCI blobs
> through a new hybrid source mechanism. This enables local metadata
> storage while keeping blob data in remote registries.
>
..
> oci_iostream = calloc(1, sizeof(*oci_iostream));
> if (!oci_iostream) {
> ocierofs_ctx_cleanup(ctx);
> diff --git a/mount/main.c b/mount/main.c
> index eb0dd01..fd5736d 100644
> --- a/mount/main.c
> +++ b/mount/main.c
> @@ -16,6 +16,7 @@
> #include "erofs/io.h"
> #include "../lib/liberofs_nbd.h"
> #include "../lib/liberofs_oci.h"
> +#include "../lib/liberofs_gzran.h"
> #ifdef HAVE_LINUX_LOOP_H
> #include <linux/loop.h>
> #else
> @@ -141,7 +142,25 @@ static int erofsmount_parse_oci_option(const char *option)
> if (!oci_cfg->password)
> return -ENOMEM;
> } else {
> - return -EINVAL;
> + p = strstr(option, "oci.local_meta=");
oci.tarindex ?
> + if (p != NULL) {
> + p += strlen("oci.local_meta=");
> + free(oci_cfg->local_meta_path);
> + oci_cfg->local_meta_path = strdup(p);
> + if (!oci_cfg->local_meta_path)
> + return -ENOMEM;
> + } else {
> + p = strstr(option, "oci.zinfo=");
> + if (p != NULL) {
> + p += strlen("oci.zinfo=");
> + free(oci_cfg->zinfo_path);
> + oci_cfg->zinfo_path = strdup(p);
> + if (!oci_cfg->zinfo_path)
> + return -ENOMEM;
> + } else {
> + return -EINVAL;
> + }
> + }
> }
> }
> }
> @@ -332,11 +351,265 @@ static int erofsmount_fuse(const char *source, const char *mountpoint,
> return 0;
> }
>
> +struct erofs_hybrid_source {
struct erofsmount_tarindex_source {
> + struct erofs_vfile local_vf;
struct erofs_vfile *tarindex_vf;
> + struct erofs_vfile *gzran_vf;
struct erofs_vfile *zinfo_vf;
> + u64 local_size;
> +};
> +
> struct erofsmount_nbd_ctx {
> struct erofs_vfile vd; /* virtual device */
> struct erofs_vfile sk; /* socket file */
> };
>
> +static ssize_t erofs_hybrid_pread(struct erofs_vfile *vf, void *buf,
> + size_t count, u64 offset)
s/hybrid/tarindex/
> +{
> + struct erofs_hybrid_source *hs;
> + ssize_t local_read, remote_read;
> +
> + hs = *(struct erofs_hybrid_source **)vf->payload;
> + if (!hs)
> + return -EINVAL;
> +
> + /* Handle device boundary probe requests */
> + if (offset >= (INT64_MAX >> 9))
Let's define a macro for this.
> + return 0;
> +
> + if (hs->local_size == 0)
> + return hs->gzran_vf->ops->pread(hs->gzran_vf, buf, count, offset);
> +
> + if (offset >= hs->local_size) {
> + u64 remote_offset = offset - hs->local_size;
no need to defina a variable, if it's needed, add a comment for this.
> +
> + return hs->gzran_vf->ops->pread(hs->gzran_vf, buf, count, remote_offset);
> + }
> +
> + if (offset + count <= hs->local_size)
> + return erofs_io_pread(&hs->local_vf, buf, count, offset);
> +
> + u64 local_part = hs->local_size - offset;
> + u64 remote_part = count - local_part;
they shouldn't be defined here.
Thanks,
Gao Xiang
> +
> + local_read = erofs_io_pread(&hs->local_vf, buf, local_part, offset);
> + if (local_read < 0)
> + return local_read;
> +
> + remote_read = hs->gzran_vf->ops->pread(hs->gzran_vf,
> + (char *)buf + local_read,
> + remote_part, 0);
> + if (remote_read < 0)
> + return remote_read;
> + return local_read + remote_read;
> +}
> +
> +static void erofs_hybrid_close(struct erofs_vfile *vf)
> +{
> + struct erofs_hybrid_source *hs;
> +
> + if (!vf)
> + return;
> +
> + hs = *(struct erofs_hybrid_source **)vf->payload;
> + if (!hs)
> + return;
> +
> + if (hs->local_size > 0)
> + erofs_io_close(&hs->local_vf);
> +
> + if (hs->gzran_vf)
> + erofs_io_close(hs->gzran_vf);
> +
> + free(hs);
> +}
> +
> +static int load_file_to_buf(const char *path, void **out, unsigned int *out_len)
> +{
> + FILE *fp = NULL;
> + void *buf = NULL;
> + int ret = 0;
> + long sz;
> + size_t num;
> +
> + fp = fopen(path, "rb");
> + if (!fp)
> + return -errno;
> +
> + if (fseek(fp, 0, SEEK_END) != 0) {
> + ret = -errno;
> + goto out;
> + }
More information about the Linux-erofs
mailing list