On 2025/9/28 11:32, ChengyuZhu6 wrote:
From: Chengyu Zhu <[email protected]>
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;
+ }