diff --git a/src/overlaybd/tar/CMakeLists.txt b/src/overlaybd/tar/CMakeLists.txt index fe06bc11..a3eb8ed0 100644 --- a/src/overlaybd/tar/CMakeLists.txt +++ b/src/overlaybd/tar/CMakeLists.txt @@ -8,3 +8,6 @@ target_include_directories(tar_lib PUBLIC if(BUILD_TESTING) add_subdirectory(test) endif() + +add_subdirectory(erofs) +target_link_libraries(tar_lib PRIVATE erofs_lib) \ No newline at end of file diff --git a/src/overlaybd/tar/erofs/CMakeLists.txt b/src/overlaybd/tar/erofs/CMakeLists.txt new file mode 100644 index 00000000..045cfddb --- /dev/null +++ b/src/overlaybd/tar/erofs/CMakeLists.txt @@ -0,0 +1,43 @@ +include(FetchContent) + +FetchContent_Declare( + erofs-utils + GIT_REPOSITORY https://github.com/salvete/erofs-utils.git + GIT_TAG overlaybd-incremental-io +) + +FetchContent_MakeAvailable(erofs-utils) + +execute_process( + COMMAND ./autogen.sh + WORKING_DIRECTORY ${erofs-utils_SOURCE_DIR} +) +execute_process( + COMMAND ./configure --disable-lz4 --without-liblzma + WORKING_DIRECTORY ${erofs-utils_SOURCE_DIR} +) +execute_process( + COMMAND make + WORKING_DIRECTORY ${erofs-utils_SOURCE_DIR} +) + +set(EROFS_LIB_INCLUDE_DIR "${erofs-utils_SOURCE_DIR}/include/" CACHE PATH "erofs-utils include path.") +set(EROFS_CONFIG_FILE "${erofs-utils_SOURCE_DIR}/config.h" CACHE PATH "erofs-utils config file.") +set(EROFS_LIB_STATIC "${erofs-utils_SOURCE_DIR}/lib/.libs/liberofs.a" CACHE PATH "erofs-utils static lib.") + +file(GLOB EROFS_SOURCE "*.cpp") + +add_library(erofs_lib STATIC ${EROFS_SOURCE}) + +target_include_directories(erofs_lib PRIVATE + ${PHOTON_INCLUDE_DIR} +) + +target_include_directories(erofs_lib PRIVATE + ${EROFS_LIB_INCLUDE_DIR} +) + +target_link_libraries(erofs_lib PRIVATE uuid) + +target_compile_options(erofs_lib PRIVATE "-include${EROFS_CONFIG_FILE}") +target_link_libraries(erofs_lib PRIVATE ${EROFS_LIB_STATIC}) \ No newline at end of file diff --git a/src/overlaybd/tar/erofs/tarerofs_impl.cpp b/src/overlaybd/tar/erofs/tarerofs_impl.cpp new file mode 100644 index 00000000..64c34d6a --- /dev/null +++ b/src/overlaybd/tar/erofs/tarerofs_impl.cpp @@ -0,0 +1,506 @@ +#include "tarerofs_interface.h" +#include "tarerofs_impl.h" +#include "erofs/tar.h" +#include "erofs/io.h" +#include "erofs/cache.h" +#include "erofs/block_list.h" +#include "erofs/inode.h" +#include "../../lsmt/file.h" +#include "../../lsmt/index.h" +#include + +#define TAREROFS_BLOCK_SIZE 4096 +#define TAREROFS_BLOCK_BITS 12 +#define DATA_OFFSET 1073741824 +#define MIN_RW_LEN 512ULL +#define round_down_blk(addr) ((addr) & (~(MIN_RW_LEN - 1))) +#define round_up_blk(addr) (round_down_blk((addr) + MIN_RW_LEN - 1)) +#define MAP_FILE_NAME "upper.map" + +/* + * Helper function for reading from the photon file, since + * the photon file requires reads to be 512-byte aligned. + */ +static ssize_t read_photon_file(void *buf, u64 offset, size_t len, photon::fs::IFile *file) +{ + size_t ret; + u64 start, end; + char *big_buf; + + start = round_down_blk(offset); + end = round_up_blk(offset + len); + + big_buf = (char *)malloc(end - start); + if (!big_buf) { + LOG_ERROR("Fail to malloc."); + return -1; + } + + ret = file->pread(big_buf, end - start, start); + if (ret != end - start) { + LOG_ERROR("Pread faild."); + free(big_buf); + return -1; + } + + memcpy(buf, big_buf + offset - start, len); + return len; +} + +/* + * Helper function for writing to a photon file. + */ + static ssize_t write_photon_file(const void *buf, u64 offset, size_t len, photon::fs::IFile *file) + { + ssize_t ret; + u64 start, end; + size_t saved_len = len; + char *big_buf; + + start = round_down_blk(offset); + end = round_up_blk(offset + len); + + if (start != offset || end != offset + len) { + big_buf = (char *)malloc(end - start); + if (!big_buf) { + LOG_ERROR("Fail to malloc."); + return -1; + } + /* writes within a sector range */ + if (end - start == MIN_RW_LEN) { + ret = file->pread(big_buf, MIN_RW_LEN, start); + if (ret != MIN_RW_LEN) { + LOG_ERROR("Fail to pread."); + free(big_buf); + return -1; + } + } else { + /* + * writes that span at least two sectors, + * we read the head and tail sectors in such case + */ + if (start != offset) { + ret = file->pread(big_buf, (size_t)MIN_RW_LEN, start); + if (ret != MIN_RW_LEN) { + LOG_ERROR("Fail to pread."); + free(big_buf); + return -1; + } + } + + if (end != offset + len) { + ret = file->pread(big_buf + end - start - MIN_RW_LEN, + (size_t)MIN_RW_LEN, + (off_t)end - MIN_RW_LEN); + if (ret != MIN_RW_LEN) { + LOG_ERROR("Fail to pread."); + free(big_buf); + return -1; + } + } + } + + memcpy(big_buf + offset - start, buf, len); + len = end - start; + ret = file->pwrite(big_buf, len, start); + free(big_buf); + } else { + ret = file->pwrite(buf, len, offset); + } + + if ((size_t)ret != len) { + LOG_ERROR("Fail to write photo file."); + return -1; + } + + return saved_len; + } + +TarErofsInter::TarErofsImpl *TarErofsInter::TarErofsImpl::ops_to_tarerofsimpl(struct erofs_vfops *ops) +{ + struct erofs_vfops_wrapper *evw = reinterpret_cast(ops); + TarErofsImpl *obj = reinterpret_cast(evw->private_data); + return obj; +} + +/* I/O control for target */ +ssize_t TarErofsInter::TarErofsImpl::target_pread(struct erofs_vfile *vf, void *buf, u64 offset, size_t len) +{ + TarErofsImpl *obj = ops_to_tarerofsimpl(vf->ops); + photon::fs::IFile *fout = obj->fout; + + if (read_photon_file(buf, offset, len, fout) != (ssize_t)len) + return -1; + return len; +} + +ssize_t TarErofsInter::TarErofsImpl::target_pwrite(struct erofs_vfile *vf, const void *buf, u64 offset, size_t len) +{ + TarErofsImpl *obj = ops_to_tarerofsimpl(vf->ops); + photon::fs::IFile *fout = obj->fout; + ssize_t ret; + + if (!buf) + return -EINVAL; + + ret = write_photon_file(buf, offset, len, fout); + return ret; +} + +int TarErofsInter::TarErofsImpl::target_fsync(struct erofs_vfile *vf) +{ + TarErofsImpl *obj = ops_to_tarerofsimpl(vf->ops); + photon::fs::IFile *fout = obj->fout; + + return fout->fsync(); +} + +int TarErofsInter::TarErofsImpl::target_fallocate(struct erofs_vfile *vf, u64 offset, size_t len, bool pad) +{ + static const char zero[4096] = {0}; + ssize_t ret; + + while (len > 4096) { + ret = target_pwrite(vf, zero, offset, 4096); + if (ret) + return ret; + len -= 4096; + offset += 4096; + } + ret = target_pwrite(vf, zero, offset, len); + if (ret != (ssize_t)len) { + return -2; + } + return 0; +} + +int TarErofsInter::TarErofsImpl::target_ftruncate(struct erofs_vfile *vf, u64 length) +{ + return 0; +} + + +ssize_t TarErofsInter::TarErofsImpl::target_read(struct erofs_vfile *vf, void *buf, size_t len) +{ + return -1; +} + +off_t TarErofsInter::TarErofsImpl::target_lseek(struct erofs_vfile *vf, u64 offset, int whence) +{ + return -1; +} + +/* I/O control for source */ +ssize_t TarErofsInter::TarErofsImpl::source_pread(struct erofs_vfile *vf, void *buf, u64 offset, size_t len) +{ + return -1; +} + +ssize_t TarErofsInter::TarErofsImpl::source_pwrite(struct erofs_vfile *vf, const void *buf, u64 offset, size_t len) +{ + return -1; +} + +int TarErofsInter::TarErofsImpl::source_fsync(struct erofs_vfile *vf) +{ + return -1; +} + +int TarErofsInter::TarErofsImpl::source_fallocate(struct erofs_vfile *vf, u64 offset, size_t len, bool pad) +{ + return -1; +} + +int TarErofsInter::TarErofsImpl::source_ftruncate(struct erofs_vfile *vf, u64 length) +{ + return -1; +} + + +ssize_t TarErofsInter::TarErofsImpl::source_read(struct erofs_vfile *vf, void *buf, size_t bytes) +{ + TarErofsImpl *obj = ops_to_tarerofsimpl(vf->ops); + + u64 i = 0; + while (bytes) { + u64 len = bytes > INT_MAX ? INT_MAX : bytes; + u64 ret; + + ret = obj->file->read(buf + i, len); + if (ret < 1) { + if (ret == 0) + break; + else + return -1; + } + bytes -= ret; + i += ret; + } + return i; +} + + +off_t TarErofsInter::TarErofsImpl::source_lseek(struct erofs_vfile *vf, u64 offset, int whence) +{ + TarErofsImpl *obj = ops_to_tarerofsimpl(vf->ops); + photon::fs::IFile *file = obj->file; + + return file->lseek(offset, whence); +} + + +struct erofs_mkfs_cfg { + struct erofs_sb_info *sbi; + struct erofs_tarfile *erofstar; + bool incremental; + bool ovlfs_strip; +}; + +static int rebuild_src_count; + +int erofs_mkfs(struct erofs_mkfs_cfg *cfg) { + int err; + struct erofs_tarfile *erofstar; + struct erofs_sb_info *sbi; + struct erofs_buffer_head *sb_bh; + struct erofs_inode *root; + erofs_blk_t nblocks; + + erofstar = cfg->erofstar; + sbi = cfg->sbi; + if (!erofstar || !sbi) + return -EINVAL; + + if (!erofstar->mapfile) + return -EINVAL; + + + err = erofs_blocklist_open(erofstar->mapfile, true); + if (err) { + LOG_ERROR("[erofs] Fail to open erofs blocklist."); + return -EINVAL; + } + + if (!erofstar->rvsp_mode) { + LOG_ERROR("[erofs] Must be in RVSP mode."); + return -EINVAL; + } + + if (!cfg->incremental) { + sb_bh = erofs_reserve_sb(sbi); + if (IS_ERR(sb_bh)) { + LOG_ERROR("[erofs] Fail to reseve space for superblock."); + err = PTR_ERR(sb_bh); + goto exit; + } + //erofs_uuid_generate(sbi->uuid); + } else { + err = erofs_read_superblock(sbi); + if (err) { + LOG_ERROR("[erofs] Fail to read superblock."); + goto exit; + } + erofs_buffer_init(sbi, sbi->primarydevice_blocks); + sb_bh = NULL; + } + + erofs_inode_manager_init(); + + root = erofs_mkfs_alloc_root(sbi); + if (IS_ERR(root)) { + LOG_ERROR("[erofs] Fail to alloc root inode."); + err = PTR_ERR(root); + goto exit; + } + + while (!(err = tarerofs_parse_tar(root, erofstar))); + if (err < 0) { + LOG_ERROR("[erofs] Fail to parse tar file."); + goto exit; + } + + err = erofs_rebuild_dump_tree(root, cfg->incremental, cfg->ovlfs_strip); + if (err < 0) { + LOG_ERROR("[erofs] Fail to dump tree."); + goto exit; + } + + err = erofs_bflush(NULL); + if (err) { + LOG_ERROR("[erofs] Bflush failed."); + goto exit; + } + + erofs_fixup_root_inode(root); + erofs_iput(root); + root = NULL; + + err = erofs_writesb(sbi, sb_bh, &nblocks); + if (err) { + LOG_ERROR("[erofs] Fail to writesb"); + goto exit; + } + + err = erofs_dev_resize(sbi, nblocks); +exit: + if (root) + erofs_iput(root); + erofs_blocklist_close(); + return err; +} + +static int init_sbi(struct erofs_sb_info *sbi, photon::fs::IFile *fout, struct erofs_vfops *ops) +{ + int err; + struct timeval t; + + sbi->blkszbits = TAREROFS_BLOCK_BITS; + err = gettimeofday(&t, NULL); + if (err) + return err; + sbi->build_time = t.tv_sec; + sbi->build_time_nsec = t.tv_usec; + sbi->bdev.ops = ops; + fout->lseek(0, 0); + sbi->devsz = INT64_MAX; + + return 0; +} + +static int init_tar(struct erofs_tarfile *erofstar, photon::fs::IFile *tar_file, struct erofs_vfops *ops) +{ + int err; + struct stat st; + + erofstar->global.xattrs = LIST_HEAD_INIT(erofstar->global.xattrs); + erofstar->mapfile = MAP_FILE_NAME; + erofstar->aufs = true; + erofstar->rvsp_mode = true; + erofstar->dev = rebuild_src_count + 1; + + erofstar->ios.feof = false; + erofstar->ios.tail = erofstar->ios.head = 0; + erofstar->ios.dumpfd = -1; + err = tar_file->fstat(&st); + if (err) { + LOG_ERROR("Fail to fstat tar file."); + return err; + } + erofstar->ios.sz = st.st_size; + erofstar->ios.bufsize = 16384; + do { + erofstar->ios.buffer = (char*)malloc(erofstar->ios.bufsize); + if (erofstar->ios.buffer) + break; + erofstar->ios.bufsize >>= 1; + } while (erofstar->ios.bufsize >= 1024); + + if (!erofstar->ios.buffer) + return -ENOMEM; + + erofstar->ios.vf.ops = ops; + + return 0; +} + +static int write_map_file(photon::fs::IFile *fout) +{ + FILE *fp; + uint64_t blkaddr, toff; + uint32_t nblocks; + + fp = fopen(MAP_FILE_NAME, "r"); + if (fp == NULL) { + LOG_ERROR("unable to get upper.map, ignored"); + return -1; + } + + while (fscanf(fp, "%" PRIx64" %x %" PRIx64 "\n", &blkaddr, &nblocks, &toff) >= 3) { + LSMT::RemoteMapping lba; + lba.offset = blkaddr * TAREROFS_BLOCK_SIZE; + lba.count = nblocks * TAREROFS_BLOCK_SIZE; + lba.roffset = toff; + int nwrite = fout->ioctl(LSMT::IFileRW::RemoteData, lba); + if ((unsigned) nwrite != lba.count) { + LOG_ERRNO_RETURN(0, -1, "failed to write lba"); + } + } + + fclose(fp); + return 0; +} + +static void close_sbi(struct erofs_sb_info *sbi) +{ + return; +} + +static void close_tar(struct erofs_tarfile *erofstar) +{ + free(erofstar->ios.buffer); +} + +int TarErofsInter::TarErofsImpl::extract_all() { + struct erofs_sb_info sbi = {}; + struct erofs_tarfile erofstar = {}; + struct erofs_mkfs_cfg cfg; + int err; + + /* initialization of sbi */ + err = init_sbi(&sbi, fout, reinterpret_cast(&target_vfops)); + if (err) { + close_sbi(&sbi); + LOG_ERROR("Failed to init sbi."); + return err; + } + /* initialization of erofstar */ + err = init_tar(&erofstar, file, reinterpret_cast(&source_vfops)); + if (err) { + close_sbi(&sbi); + close_tar(&erofstar); + LOG_ERROR("Failed to init tarerofs"); + return err; + } + + cfg.sbi = &sbi; + cfg.erofstar = &erofstar; + cfg.incremental = !first_layer; + cfg.ovlfs_strip = true; + + err = erofs_mkfs(&cfg); + if (err) { + close_sbi(&sbi); + close_tar(&erofstar); + LOG_ERROR("Failed to mkfs."); + return err; + } + + /* write mapfile */ + err = write_map_file(fout); + if (err) { + close_sbi(&sbi); + close_tar(&erofstar); + LOG_ERROR("Failed to write mapfile."); + return err; + } + + close_sbi(&sbi); + close_tar(&erofstar); + return 0; +} + +TarErofsInter::TarErofsInter(photon::fs::IFile *file, photon::fs::IFile *target, uint64_t fs_blocksize, + photon::fs::IFile *bf, bool meta_only, bool first_layer) : + impl(new TarErofsImpl(file, target, fs_blocksize, bf, meta_only, first_layer)) +{ +} + +TarErofsInter:: ~TarErofsInter() +{ + delete impl; +} + +int TarErofsInter::extract_all() +{ + return impl->extract_all(); +} diff --git a/src/overlaybd/tar/erofs/tarerofs_impl.h b/src/overlaybd/tar/erofs/tarerofs_impl.h new file mode 100644 index 00000000..a9c9e19a --- /dev/null +++ b/src/overlaybd/tar/erofs/tarerofs_impl.h @@ -0,0 +1,67 @@ +#include "erofs/tar.h" +#include "erofs/io.h" +#include + + +struct erofs_vfops_wrapper { + struct erofs_vfops ops; + void *private_data; +}; + +class TarErofsInter::TarErofsImpl { +public: + TarErofsImpl(photon::fs::IFile *file, photon::fs::IFile *target, uint64_t fs_blocksize = 4096, + photon::fs::IFile *bf = nullptr, bool meta_only = true, bool first_layer = true) + : file(file), fout(target), fs_base_file(bf), meta_only(meta_only), first_layer(first_layer) { + + target_vfops.ops.pread = target_pread; + target_vfops.ops.pwrite = target_pwrite; + target_vfops.ops.fsync = target_fsync; + target_vfops.ops.fallocate = target_fallocate; + target_vfops.ops.ftruncate = target_ftruncate; + target_vfops.ops.read = target_read; + target_vfops.ops.lseek = target_lseek; + target_vfops.private_data = (void*)this; + + source_vfops.ops.pread = source_pread; + source_vfops.ops.pwrite = source_pwrite; + source_vfops.ops.fsync = source_fsync; + source_vfops.ops.fallocate = source_fallocate; + source_vfops.ops.ftruncate = source_ftruncate; + source_vfops.ops.read = source_read; + source_vfops.ops.lseek = source_lseek; + source_vfops.private_data = (void*)this; + } + + int extract_all(); + +public: + photon::fs::IFile *file = nullptr; // source + photon::fs::IFile *fout = nullptr; // target + photon::fs::IFile *fs_base_file = nullptr; + bool meta_only; + bool first_layer; + struct erofs_vfops_wrapper target_vfops; + struct erofs_vfops_wrapper source_vfops; +public: + /* I/O control for target */ + static ssize_t target_pread(struct erofs_vfile *vf, void *buf, u64 offset, size_t len); + static ssize_t target_pwrite(struct erofs_vfile *vf, const void *buf, u64 offset, size_t len); + static int target_fsync(struct erofs_vfile *vf); + static int target_fallocate(struct erofs_vfile *vf, u64 offset, size_t len, bool pad); + static int target_ftruncate(struct erofs_vfile *vf, u64 length); + static ssize_t target_read(struct erofs_vfile *vf, void *buf, size_t len); + static off_t target_lseek(struct erofs_vfile *vf, u64 offset, int whence); + + /* I/O control for source */ + static ssize_t source_pread(struct erofs_vfile *vf, void *buf, u64 offset, size_t len); + static ssize_t source_pwrite(struct erofs_vfile *vf, const void *buf, u64 offset, size_t len); + static int source_fsync(struct erofs_vfile *vf); + static int source_fallocate(struct erofs_vfile *vf, u64 offset, size_t len, bool pad); + static int source_ftruncate(struct erofs_vfile *vf, u64 length); + static ssize_t source_read(struct erofs_vfile *vf, void *buf, size_t len); + static off_t source_lseek(struct erofs_vfile *vf, u64 offset, int whence); + + /* helper function */ + static TarErofsImpl *ops_to_tarerofsimpl(struct erofs_vfops *ops); +}; diff --git a/src/overlaybd/tar/erofs/tarerofs_interface.h b/src/overlaybd/tar/erofs/tarerofs_interface.h new file mode 100644 index 00000000..90512304 --- /dev/null +++ b/src/overlaybd/tar/erofs/tarerofs_interface.h @@ -0,0 +1,22 @@ +#ifndef TAREROFS_INTERFACE_H +#define TAREROFS_INTERFACE_H + +#include +#include +#include + +class TarErofsInter { +public: + TarErofsInter(photon::fs::IFile *file, photon::fs::IFile *target, uint64_t fs_blocksize = 4096, + photon::fs::IFile *bf = nullptr, bool meta_only = true, bool first_layer = true); + ~TarErofsInter(); + + int extract_all(); + +private: + class TarErofsImpl; + TarErofsImpl *impl; +}; +#endif + + diff --git a/src/overlaybd/tar/tarerofs.cpp b/src/overlaybd/tar/tarerofs.cpp deleted file mode 100644 index b7b20fa7..00000000 --- a/src/overlaybd/tar/tarerofs.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include "tarerofs.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../lsmt/file.h" -#include "../lsmt/index.h" - -#define TAREROFS_BLOCK_SIZE 4096 -#define __stringify_1(x...) #x -#define __stringify(x...) __stringify_1(x) - -#define LSMT_ALIGNMENT 512 - -int TarErofs::extract_all() { - ssize_t read; - struct stat st; - char buf[128*1024]; - char base_path[64] = "/tmp/tarerofs_base_XXXXXX"; - char command_line[256] = "mkfs.erofs --tar=0,upper.map,1073741824 -b" __stringify(TAREROFS_BLOCK_SIZE) " --aufs"; - const char command_line2[] = " upper.erofs"; - - FILE *fp; - photon::fs::IFile *rawfs = nullptr; - int status; - uint64_t blkaddr, toff, metasize; - uint32_t nblocks; - - if (!meta_only) { - LOG_ERROR("currently EROFS supports fastoci mode only", strerror(errno)); - return -1; - } - - if (!first_layer) { - int fd = mkstemp(base_path); - if (fd < 0) { - LOG_ERROR("cannot generate a temporary file to dump overlaybd disk"); - return -1; - } - std::strcat(command_line, " --base "); - std::strcat(command_line, base_path); - - // lsmt.pread should align to 512 - if (fs_base_file->pread(&buf, LSMT_ALIGNMENT, 0) != LSMT_ALIGNMENT) { - LOG_ERROR("failed to read EROFS metadata size"); - return -1; - } - metasize = *(uint64_t *)buf; - - while (metasize) { - int count = std::min(sizeof(buf), metasize); - read = fs_base_file->read(buf, count); - if (read != count || - write(fd, buf, read) != read) { - read = -1; - break; - } - metasize -= read; - } - close(fd); - if (read < 0) { - return -1; - } - } - std::strcat(command_line, command_line2); - fp = popen(command_line, "w"); - if (fp == NULL) { - LOG_ERROR("failed to execute mkfs.erofs", strerror(errno)); - return -1; - } - - while ((read = file->read(buf, sizeof(buf))) > 0) { - if (fwrite(buf, read, 1, fp) != 1) { - read = -1; - break; - } - } - status = pclose(fp); - - if (!first_layer) - unlink(base_path); - - if (read < 0 || status) { - return -1; - } - - rawfs = photon::fs::open_localfile_adaptor("upper.erofs", O_RDONLY, 0644); - DEFER({ delete rawfs; }); - - /* write to LSMT */ - metasize = rawfs->lseek(0, SEEK_END); - rawfs->lseek(0, 0); - fout->lseek(0, 0); - while ((read = rawfs->read(buf, sizeof(buf))) > 0) { - if (metasize) { // since pwrite < 512 is unsupported. - *(uint64_t *)buf = metasize; - metasize = 0; - } - - if (fout->write(buf, read) != read) { - read = -1; - break; - } - } - - /* write mapfile */ - fp = fopen("upper.map", "r"); - if (fp == NULL) { - LOG_ERROR("unable to get upper.map, ignored"); - return -1; - } - while (fscanf(fp, "%" PRIx64" %x %" PRIx64 "\n", &blkaddr, &nblocks, &toff) >= 3) { - LSMT::RemoteMapping lba; - lba.offset = blkaddr * TAREROFS_BLOCK_SIZE; - lba.count = nblocks * TAREROFS_BLOCK_SIZE; - lba.roffset = toff; - int nwrite = fout->ioctl(LSMT::IFileRW::RemoteData, lba); - if ((unsigned) nwrite != lba.count) { - LOG_ERRNO_RETURN(0, -1, "failed to write lba"); - } - } - fclose(fp); - return 0; -} diff --git a/src/overlaybd/tar/tarerofs.h b/src/overlaybd/tar/tarerofs.h deleted file mode 100644 index 51d61232..00000000 --- a/src/overlaybd/tar/tarerofs.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class TarErofs { -public: - TarErofs(photon::fs::IFile *file, photon::fs::IFile *target, uint64_t fs_blocksize = 4096, - photon::fs::IFile *bf = nullptr, bool meta_only = true, bool first_layer = true) - : file(file), fout(target), fs_base_file(bf), meta_only(meta_only), first_layer(first_layer) {} - - int extract_all(); - -private: - photon::fs::IFile *file = nullptr; // source - photon::fs::IFile *fout = nullptr; // target - photon::fs::IFile *fs_base_file = nullptr; - bool meta_only; - bool first_layer; - std::set unpackedPaths; - std::list> dirs; // -}; diff --git a/src/tools/turboOCI-apply.cpp b/src/tools/turboOCI-apply.cpp index 49f410fc..b1e431aa 100644 --- a/src/tools/turboOCI-apply.cpp +++ b/src/tools/turboOCI-apply.cpp @@ -23,7 +23,7 @@ #include "../overlaybd/lsmt/file.h" #include "../overlaybd/zfile/zfile.h" #include "../overlaybd/tar/libtar.h" -#include "../overlaybd/tar/tarerofs.h" +#include "../overlaybd/tar/erofs/tarerofs_interface.h" #include "../overlaybd/gzindex/gzfile.h" #include "../overlaybd/gzip/gz.h" #include @@ -136,7 +136,7 @@ int main(int argc, char **argv) { } auto tar = - new TarErofs(src_file, imgfile, 4096, base_file, true, cfg.lowers().size() == 0); + new TarErofsInter(src_file, imgfile, 4096, base_file, true, cfg.lowers().size() == 0); if (tar->extract_all() < 0) { fprintf(stderr, "failed to extract\n");