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;
+       }


Reply via email to