Collect inode data source state into struct erofs_inode_datasource instead of carrying separate fields on the inode. Add a vfile wrapper for local path, diskbuf, and rebuild blob sources.
Assisted-by: Codex:GPT-5.5 Signed-off-by: Yifan Zhao <[email protected]> --- include/erofs/blobchunk.h | 4 +- include/erofs/internal.h | 32 ++-- lib/blobchunk.c | 24 +-- lib/compress.c | 7 + lib/inode.c | 330 +++++++++++++++++++++++++++----------- lib/liberofs_compress.h | 2 + lib/rebuild.c | 20 +-- lib/remotes/s3.c | 25 +-- lib/tar.c | 23 +-- 9 files changed, 323 insertions(+), 144 deletions(-) diff --git a/include/erofs/blobchunk.h b/include/erofs/blobchunk.h index 1761fdd..e2e306f 100644 --- a/include/erofs/blobchunk.h +++ b/include/erofs/blobchunk.h @@ -19,8 +19,8 @@ struct erofs_blobchunk *erofs_get_unhashed_chunk(unsigned int device_id, void erofs_inode_fixup_chunkformat(struct erofs_inode *inode); int erofs_write_chunk_indexes(struct erofs_inode *inode, struct erofs_vfile *vf, erofs_off_t off); -int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd, - erofs_off_t startoff); +int erofs_blob_write_chunked_file(struct erofs_inode *inode, + struct erofs_vfile *vf); int erofs_write_zero_inode(struct erofs_inode *inode); int tarerofs_write_chunkes(struct erofs_inode *inode, erofs_off_t data_offset); int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi); diff --git a/include/erofs/internal.h b/include/erofs/internal.h index 2cc9cc8..cba1348 100644 --- a/include/erofs/internal.h +++ b/include/erofs/internal.h @@ -204,11 +204,24 @@ EROFS_FEATURE_FUNCS(ishare_xattrs, compat, COMPAT_ISHARE_XATTRS) struct erofs_diskbuf; -#define EROFS_INODE_DATA_SOURCE_NONE 0 -#define EROFS_INODE_DATA_SOURCE_LOCALPATH 1 -#define EROFS_INODE_DATA_SOURCE_DISKBUF 2 -#define EROFS_INODE_DATA_SOURCE_RESVSP 3 -#define EROFS_INODE_DATA_SOURCE_REBUILD_BLOB 4 +enum erofs_inode_data_source_type { + EROFS_INODE_DATA_SOURCE_NONE, + EROFS_INODE_DATA_SOURCE_LOCALPATH, + EROFS_INODE_DATA_SOURCE_DISKBUF, + EROFS_INODE_DATA_SOURCE_RESVSP, + EROFS_INODE_DATA_SOURCE_REBUILD_BLOB, +}; + +struct erofs_inode_datasource { + unsigned char type; + union { + struct erofs_diskbuf *diskbuf; + struct { + char *path; + erofs_off_t dataoff; + } rebuild_blob; + }; +}; enum erofs_idata_type { EROFS_IDATA_TYPE_RAW, @@ -256,17 +269,12 @@ struct erofs_inode { } u; char *i_srcpath; - union { - char *i_link; - struct erofs_diskbuf *i_diskbuf; - }; - char *rebuild_blobpath; - erofs_off_t rebuild_src_dataoff; + char *i_link; + struct erofs_inode_datasource datasource; unsigned char datalayout; unsigned char inode_isize; /* inline tail-end packing size */ unsigned short idata_size; - char datasource; bool in_metabox; char idata_type; bool lazy_tailblock; diff --git a/lib/blobchunk.c b/lib/blobchunk.c index e39bf68..8015c05 100644 --- a/lib/blobchunk.c +++ b/lib/blobchunk.c @@ -300,8 +300,8 @@ static bool erofs_blob_can_merge(struct erofs_sb_info *sbi, return false; } -int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd, - erofs_off_t startoff) +int erofs_blob_write_chunked_file(struct erofs_inode *inode, + struct erofs_vfile *vf) { struct erofs_sb_info *sbi = inode->sbi; unsigned int chunkbits = cfg.c_chunkbits; @@ -314,7 +314,7 @@ int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd, int ret; /* if the file is fully sparsed, use one big chunk instead */ - if (lseek(fd, startoff, SEEK_DATA) < 0 && errno == ENXIO) { + if (erofs_io_lseek(vf, 0, SEEK_DATA) == -ENXIO) { chunkbits = ilog2(inode->i_size - 1) + 1; if (chunkbits < sbi->blkszbits) chunkbits = sbi->blkszbits; @@ -366,20 +366,18 @@ int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd, } for (pos = 0; pos < inode->i_size; pos += len) { - off_t offset = lseek(fd, pos + startoff, SEEK_DATA); + off_t offset = erofs_io_lseek(vf, pos, SEEK_DATA); if (offset < 0) { - if (errno != ENXIO) + if (offset != -ENXIO) offset = pos; else offset = ((pos >> chunkbits) + 1) << chunkbits; } else { - offset -= startoff; - if (offset != (offset & ~(chunksize - 1))) { offset &= ~(chunksize - 1); - if (lseek(fd, offset + startoff, SEEK_SET) != - startoff + offset) { + if (erofs_io_lseek(vf, offset, SEEK_SET) != + offset) { ret = -EIO; goto err; } @@ -404,7 +402,13 @@ int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd, } len = min_t(u64, inode->i_size - pos, chunksize); - ret = read(fd, chunkdata, len); + ret = erofs_io_lseek(vf, pos, SEEK_SET); + if (ret != pos) { + ret = ret < 0 ? ret : -EIO; + goto err; + } + + ret = erofs_io_read(vf, chunkdata, len); if (ret < len) { ret = -EIO; goto err; diff --git a/lib/compress.c b/lib/compress.c index e7c60b2..633b69a 100644 --- a/lib/compress.c +++ b/lib/compress.c @@ -1914,6 +1914,13 @@ void *erofs_prepare_compressed_file(struct erofs_importer *im, return ictx; } +void erofs_bind_compressed_file_with_vfile(struct z_erofs_compress_ictx *ictx, + struct erofs_vfile *vf) +{ + ictx->vf = vf; + ictx->fpos = 0; +} + void erofs_bind_compressed_file_with_fd(struct z_erofs_compress_ictx *ictx, int fd, u64 fpos) { diff --git a/lib/inode.c b/lib/inode.c index c225faa..328215b 100644 --- a/lib/inode.c +++ b/lib/inode.c @@ -76,6 +76,13 @@ static const umode_t erofs_dtype_by_umode[EROFS_FT_MAX] = { [EROFS_FT_SYMLINK] = S_IFLNK }; +struct erofs_inode_datasource_vfile { + struct erofs_vfile vf; + struct erofs_inode *inode; + u64 base; + u64 pos; +}; + umode_t erofs_ftype_to_mode(unsigned int ftype, unsigned int perm) { if (ftype >= EROFS_FT_MAX) @@ -138,6 +145,172 @@ struct erofs_inode *erofs_iget(dev_t dev, ino_t ino) return ret; } +static void erofs_inode_free_datasource(struct erofs_inode *inode) +{ + switch (inode->datasource.type) { + case EROFS_INODE_DATA_SOURCE_DISKBUF: + erofs_diskbuf_close(inode->datasource.diskbuf); + free(inode->datasource.diskbuf); + inode->datasource.diskbuf = NULL; + break; + case EROFS_INODE_DATA_SOURCE_REBUILD_BLOB: + free(inode->datasource.rebuild_blob.path); + inode->datasource.rebuild_blob.path = NULL; + break; + default: + return; + } + inode->datasource.type = EROFS_INODE_DATA_SOURCE_NONE; +} + +static ssize_t erofs_inode_vfpread(struct erofs_vfile *vf, void *buf, + size_t len, u64 offset) +{ + struct erofs_inode_datasource_vfile *dvf = + container_of(vf, struct erofs_inode_datasource_vfile, vf); + + return erofs_io_pread(&(struct erofs_vfile){ .fd = vf->fd }, + buf, len, dvf->base + offset); +} + +static ssize_t erofs_inode_vfread(struct erofs_vfile *vf, void *buf, + size_t len) +{ + struct erofs_inode_datasource_vfile *dvf = + container_of(vf, struct erofs_inode_datasource_vfile, vf); + ssize_t ret; + + ret = erofs_inode_vfpread(vf, buf, len, dvf->pos); + if (ret > 0) + dvf->pos += ret; + return ret; +} + +static off_t erofs_inode_vflseek(struct erofs_vfile *vf, u64 offset, + int whence) +{ + struct erofs_inode_datasource_vfile *dvf = + container_of(vf, struct erofs_inode_datasource_vfile, vf); + u64 pos; + off_t ret; + + switch (whence) { + case SEEK_SET: + if (offset > dvf->inode->i_size) + return -EINVAL; + pos = offset; + break; + case SEEK_CUR: + if (dvf->pos > dvf->inode->i_size || + offset > dvf->inode->i_size - dvf->pos) + return -EINVAL; + pos = dvf->pos + offset; + break; + case SEEK_END: + if (offset) + return -EINVAL; + pos = dvf->inode->i_size; + break; + case SEEK_DATA: + case SEEK_HOLE: + if (offset > dvf->inode->i_size) + return -ENXIO; + if (offset == dvf->inode->i_size) { + if (whence == SEEK_DATA) + return -ENXIO; + dvf->pos = offset; + return dvf->pos; + } + + ret = erofs_io_lseek(&(struct erofs_vfile){ .fd = vf->fd }, + dvf->base + offset, whence); + if (ret < 0) + return ret; + if (ret < dvf->base) + return -EIO; + if (whence == SEEK_DATA && + ret >= dvf->base + dvf->inode->i_size) + return -ENXIO; + if (ret > dvf->base + dvf->inode->i_size) + ret = dvf->base + dvf->inode->i_size; + dvf->pos = ret - dvf->base; + return dvf->pos; + default: + return -EOPNOTSUPP; + } + + dvf->pos = pos; + return dvf->pos; +} + +static void erofs_inode_vfclose(struct erofs_vfile *vf) +{ + struct erofs_inode_datasource_vfile *dvf = + container_of(vf, struct erofs_inode_datasource_vfile, vf); + struct erofs_inode *inode = dvf->inode; + + if (vf->fd >= 0 && + (inode->datasource.type == EROFS_INODE_DATA_SOURCE_LOCALPATH || + inode->datasource.type == EROFS_INODE_DATA_SOURCE_REBUILD_BLOB)) + close(vf->fd); + vf->fd = -1; + erofs_inode_free_datasource(inode); + free(dvf); +} + +static struct erofs_vfops erofs_inode_vfops = { + .pread = erofs_inode_vfpread, + .read = erofs_inode_vfread, + .lseek = erofs_inode_vflseek, + .close = erofs_inode_vfclose, +}; + +static struct erofs_inode_datasource_vfile *erofs_inode_open_data_vfile( + struct erofs_inode *inode) +{ + struct erofs_inode_datasource_vfile *dvf; + int ret; + + if (inode->datasource.type != EROFS_INODE_DATA_SOURCE_LOCALPATH && + inode->datasource.type != EROFS_INODE_DATA_SOURCE_DISKBUF && + inode->datasource.type != EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) + return NULL; + + dvf = calloc(1, sizeof(*dvf)); + if (!dvf) + return ERR_PTR(-ENOMEM); + + dvf->vf = (struct erofs_vfile) { + .ops = &erofs_inode_vfops, + .fd = -1, + }; + dvf->inode = inode; + + switch (inode->datasource.type) { + case EROFS_INODE_DATA_SOURCE_DISKBUF: + dvf->vf.fd = erofs_diskbuf_getfd(inode->datasource.diskbuf, + &dvf->base); + break; + case EROFS_INODE_DATA_SOURCE_LOCALPATH: + dvf->vf.fd = open(inode->i_srcpath, O_RDONLY | O_BINARY); + break; + case EROFS_INODE_DATA_SOURCE_REBUILD_BLOB: + dvf->vf.fd = open(inode->datasource.rebuild_blob.path, + O_RDONLY | O_BINARY); + dvf->base = inode->datasource.rebuild_blob.dataoff; + break; + default: + break; + } + if (dvf->vf.fd < 0) { + ret = inode->datasource.type == EROFS_INODE_DATA_SOURCE_DISKBUF ? + dvf->vf.fd : -errno; + free(dvf); + return ERR_PTR(ret); + } + return dvf; +} + unsigned int erofs_iput(struct erofs_inode *inode) { struct erofs_dentry *d, *t; @@ -155,14 +328,8 @@ unsigned int erofs_iput(struct erofs_inode *inode) if (!erofs_is_special_identifier(inode->i_srcpath)) free(inode->i_srcpath); - if (inode->datasource == EROFS_INODE_DATA_SOURCE_DISKBUF) { - erofs_diskbuf_close(inode->i_diskbuf); - free(inode->i_diskbuf); - } else if (inode->datasource == EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) { - free(inode->rebuild_blobpath); - } else { - free(inode->i_link); - } + erofs_inode_free_datasource(inode); + free(inode->i_link); if (inode->datalayout == EROFS_INODE_CHUNK_BASED) free(inode->chunkindexes); @@ -700,30 +867,32 @@ static int erofs_write_unencoded_data(struct erofs_inode *inode, return 0; } -int erofs_write_unencoded_file(struct erofs_inode *inode, int fd, u64 fpos) +static int erofs_write_unencoded_file(struct erofs_inode *inode, + struct erofs_inode_datasource_vfile *src) { - struct erofs_vfile vf = { .fd = fd }; + int ret; + + ret = erofs_io_lseek(&src->vf, 0, SEEK_SET); + if (ret) + return ret; if (cfg.c_chunkbits && - inode->datasource != EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) { + inode->datasource.type != EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) { inode->u.chunkbits = cfg.c_chunkbits; /* chunk indexes when explicitly specified */ inode->u.chunkformat = 0; if (cfg.c_force_chunkformat == FORCE_INODE_CHUNK_INDEXES) inode->u.chunkformat = EROFS_CHUNK_FORMAT_INDEXES; - return erofs_blob_write_chunked_file(inode, fd, fpos); + return erofs_blob_write_chunked_file(inode, &src->vf); } - if (inode->datasource == EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) { - if (erofs_io_lseek(&vf, fpos, SEEK_SET) != (off_t)fpos) - return -EIO; - return erofs_write_unencoded_data(inode, &vf, fpos, true, false); - } - - inode->datalayout = EROFS_INODE_FLAT_INLINE; + if (inode->datasource.type != EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) + inode->datalayout = EROFS_INODE_FLAT_INLINE; /* fallback to all data uncompressed */ - return erofs_write_unencoded_data(inode, &vf, fpos, - inode->datasource == EROFS_INODE_DATA_SOURCE_DISKBUF, false); + return erofs_write_unencoded_data(inode, &src->vf, 0, + inode->datasource.type == EROFS_INODE_DATA_SOURCE_DISKBUF || + inode->datasource.type == EROFS_INODE_DATA_SOURCE_REBUILD_BLOB, + false); } static int erofs_write_dir_file(const struct erofs_importer *im, @@ -1428,7 +1597,7 @@ static struct erofs_inode *erofs_iget_from_local(struct erofs_importer *im, erofs_iput(inode); return ERR_PTR(ret); } - inode->datasource = EROFS_INODE_DATA_SOURCE_LOCALPATH; + inode->datasource.type = EROFS_INODE_DATA_SOURCE_LOCALPATH; return inode; } @@ -1489,9 +1658,8 @@ static int erofs_inode_reserve_data_blocks(struct erofs_inode *inode) struct erofs_mkfs_job_ndir_ctx { struct erofs_inode *inode; + struct erofs_inode_datasource_vfile *src; void *ictx; - int fd; - u64 fpos; }; static int erofs_mkfs_job_write_file(struct erofs_mkfs_job_ndir_ctx *ctx) @@ -1499,39 +1667,20 @@ static int erofs_mkfs_job_write_file(struct erofs_mkfs_job_ndir_ctx *ctx) struct erofs_inode *inode = ctx->inode; int ret; - if (inode->datasource == EROFS_INODE_DATA_SOURCE_DISKBUF && - lseek(ctx->fd, ctx->fpos, SEEK_SET) < 0) { - ret = -errno; - goto out; - } - if (ctx->ictx) { + ret = erofs_io_lseek(&ctx->src->vf, 0, SEEK_SET); + if (ret) + goto out; ret = erofs_write_compressed_file(ctx->ictx); if (ret != -ENOSPC) goto out; - if (lseek(ctx->fd, ctx->fpos, SEEK_SET) < 0) { - ret = -errno; - goto out; - } } /* fallback to all data uncompressed */ - ret = erofs_write_unencoded_file(inode, ctx->fd, ctx->fpos); + ret = erofs_write_unencoded_file(inode, ctx->src); out: - if (inode->datasource == EROFS_INODE_DATA_SOURCE_DISKBUF) { - erofs_diskbuf_close(inode->i_diskbuf); - free(inode->i_diskbuf); - inode->i_diskbuf = NULL; - inode->datasource = EROFS_INODE_DATA_SOURCE_NONE; - } else if (inode->datasource == EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) { - free(inode->rebuild_blobpath); - inode->rebuild_blobpath = NULL; - inode->datasource = EROFS_INODE_DATA_SOURCE_NONE; - DBG_BUGON(ctx->fd < 0); - close(ctx->fd); - } else { - DBG_BUGON(ctx->fd < 0); - close(ctx->fd); - } + DBG_BUGON(!ctx->src || ctx->src->vf.fd < 0); + erofs_io_close(&ctx->src->vf); + ctx->src = NULL; return ret; } @@ -1549,7 +1698,7 @@ static int erofs_mkfs_handle_nondirectory(const struct erofs_mkfs_btctx *btctx, ret = erofs_prepare_xattr_ibody(inode, btctx->incremental && IS_ROOT(inode)); if (ret) - return ret; + goto out; if (S_ISLNK(inode->i_mode)) { char *symlink = inode->i_link; @@ -1568,16 +1717,22 @@ static int erofs_mkfs_handle_nondirectory(const struct erofs_mkfs_btctx *btctx, free(symlink); inode->i_link = NULL; } else if (inode->i_size) { - if (inode->datasource == EROFS_INODE_DATA_SOURCE_RESVSP) + if (inode->datasource.type == EROFS_INODE_DATA_SOURCE_RESVSP) ret = erofs_inode_reserve_data_blocks(inode); - else if (ctx->fd >= 0) + else if (ctx->src) ret = erofs_mkfs_job_write_file(ctx); } if (ret) - return ret; + goto out; erofs_prepare_inode_buffer(btctx->im, inode); erofs_write_tail_end(btctx->im, inode); return 0; +out: + if (ctx->src) { + erofs_io_close(&ctx->src->vf); + ctx->src = NULL; + } + return ret; } static int erofs_mkfs_create_directory(const struct erofs_mkfs_btctx *ctx, @@ -1760,7 +1915,8 @@ static int erofs_mkfs_go(const struct erofs_mkfs_btctx *ctx, struct erofs_mkfs_jobitem item; item.type = type; - memcpy(&item.u, elem, size); + if (size) + memcpy(&item.u, elem, size); return erofs_mkfs_jobfn(ctx, &item); } static void erofs_mkfs_flushjobs(struct erofs_sb_info *sbi) @@ -1983,12 +2139,12 @@ static int erofs_prepare_dir_inode(const struct erofs_mkfs_btctx *ctx, return 0; } -static int erofs_set_inode_fingerprint(struct erofs_inode *inode, int fd, - erofs_off_t pos) +static int erofs_set_inode_fingerprint(struct erofs_inode *inode, + struct erofs_vfile *vf) { u8 ishare_xattr_prefix_id = inode->sbi->ishare_xattr_prefix_id; erofs_off_t remaining = inode->i_size; - struct erofs_vfile vf = { .fd = fd }; + erofs_off_t pos = 0; struct sha256_state md; u8 out[32 + sizeof("sha256:") - 1]; int ret; @@ -1999,7 +2155,7 @@ static int erofs_set_inode_fingerprint(struct erofs_inode *inode, int fd, do { u8 buf[32768]; - ret = erofs_io_pread(&vf, buf, + ret = erofs_io_pread(vf, buf, min_t(u64, remaining, sizeof(buf)), pos); if (ret < 0) return ret; @@ -2018,51 +2174,45 @@ static int erofs_mkfs_begin_nondirectory(const struct erofs_mkfs_btctx *btctx, struct erofs_inode *inode) { struct erofs_importer *im = btctx->im; - struct erofs_mkfs_job_ndir_ctx ctx = - { .inode = inode, .fd = -1 }; + struct erofs_mkfs_job_ndir_ctx ctx = { .inode = inode }; int ret; if (S_ISREG(inode->i_mode) && inode->i_size) { - switch (inode->datasource) { - case EROFS_INODE_DATA_SOURCE_DISKBUF: - ctx.fd = erofs_diskbuf_getfd(inode->i_diskbuf, &ctx.fpos); - if (ctx.fd < 0) - return ctx.fd; - break; - case EROFS_INODE_DATA_SOURCE_LOCALPATH: - ctx.fd = open(inode->i_srcpath, O_RDONLY | O_BINARY); - if (ctx.fd < 0) - return -errno; - break; - case EROFS_INODE_DATA_SOURCE_REBUILD_BLOB: - ctx.fd = open(inode->rebuild_blobpath, O_RDONLY | O_BINARY); - if (ctx.fd < 0) - return -errno; - ctx.fpos = inode->rebuild_src_dataoff; - break; - default: + ctx.src = erofs_inode_open_data_vfile(inode); + if (IS_ERR(ctx.src)) + return PTR_ERR(ctx.src); + if (!ctx.src) goto out; - } - ret = erofs_set_inode_fingerprint(inode, ctx.fd, ctx.fpos); + ret = erofs_set_inode_fingerprint(inode, &ctx.src->vf); if (ret < 0) - return ret; + goto err_close; - if (inode->datasource != EROFS_INODE_DATA_SOURCE_REBUILD_BLOB && + if (inode->datasource.type != EROFS_INODE_DATA_SOURCE_REBUILD_BLOB && inode->sbi->available_compr_algs && erofs_file_is_compressible(im, inode)) { ctx.ictx = erofs_prepare_compressed_file(im, inode); - if (IS_ERR(ctx.ictx)) - return PTR_ERR(ctx.ictx); - erofs_bind_compressed_file_with_fd(ctx.ictx, - ctx.fd, ctx.fpos); + if (IS_ERR(ctx.ictx)) { + ret = PTR_ERR(ctx.ictx); + goto err_close; + } + erofs_bind_compressed_file_with_vfile(ctx.ictx, + &ctx.src->vf); ret = erofs_begin_compressed_file(ctx.ictx); if (ret) - return ret; + goto err_close; } } out: - return erofs_mkfs_go(btctx, EROFS_MKFS_JOB_NDIR, &ctx, sizeof(ctx)); + ret = erofs_mkfs_go(btctx, EROFS_MKFS_JOB_NDIR, &ctx, sizeof(ctx)); +#ifdef EROFS_MT_ENABLED + if (ret && ctx.src) + erofs_io_close(&ctx.src->vf); +#endif + return ret; +err_close: + erofs_io_close(&ctx.src->vf); + return ret; } static int erofs_mkfs_handle_inode(const struct erofs_mkfs_btctx *ctx, @@ -2402,7 +2552,7 @@ struct erofs_inode *erofs_mkfs_build_special_from_fd(struct erofs_importer *im, inode->datalayout = EROFS_INODE_FLAT_INLINE; ret = erofs_write_unencoded_data(inode, &(struct erofs_vfile){ .fd = fd }, 0, - inode->datasource == EROFS_INODE_DATA_SOURCE_DISKBUF, + inode->datasource.type == EROFS_INODE_DATA_SOURCE_DISKBUF, false); if (ret) return ERR_PTR(ret); diff --git a/lib/liberofs_compress.h b/lib/liberofs_compress.h index da6eb1a..55a8943 100644 --- a/lib/liberofs_compress.h +++ b/lib/liberofs_compress.h @@ -17,6 +17,8 @@ struct z_erofs_compress_ictx; void z_erofs_drop_inline_pcluster(struct erofs_inode *inode); void *erofs_prepare_compressed_file(struct erofs_importer *im, struct erofs_inode *inode); +void erofs_bind_compressed_file_with_vfile(struct z_erofs_compress_ictx *ictx, + struct erofs_vfile *vf); void erofs_bind_compressed_file_with_fd(struct z_erofs_compress_ictx *ictx, int fd, u64 fpos); int erofs_begin_compressed_file(struct z_erofs_compress_ictx *ictx); diff --git a/lib/rebuild.c b/lib/rebuild.c index 51dfe18..abe3b74 100644 --- a/lib/rebuild.c +++ b/lib/rebuild.c @@ -233,24 +233,26 @@ static int erofs_rebuild_write_full_data(struct erofs_inode *inode) return -EFSCORRUPTED; return 0; } - inode->rebuild_blobpath = strdup(src_sbi->devname); - if (!inode->rebuild_blobpath) + inode->datasource.rebuild_blob.path = strdup(src_sbi->devname); + if (!inode->datasource.rebuild_blob.path) return -ENOMEM; - inode->rebuild_src_dataoff = + inode->datasource.rebuild_blob.dataoff = erofs_pos(src_sbi, erofs_inode_dev_baddr(inode)); - inode->datasource = EROFS_INODE_DATA_SOURCE_REBUILD_BLOB; + inode->datasource.type = EROFS_INODE_DATA_SOURCE_REBUILD_BLOB; } else if (inode->datalayout == EROFS_INODE_FLAT_INLINE) { erofs_blk_t nblocks = erofs_blknr(src_sbi, inode->i_size); unsigned int inline_size = inode->i_size % erofs_blksiz(src_sbi); if (nblocks > 0 && inode->u.i_blkaddr != EROFS_NULL_ADDR) { - inode->rebuild_blobpath = strdup(src_sbi->devname); - if (!inode->rebuild_blobpath) + inode->datasource.rebuild_blob.path = + strdup(src_sbi->devname); + if (!inode->datasource.rebuild_blob.path) return -ENOMEM; - inode->rebuild_src_dataoff = + inode->datasource.rebuild_blob.dataoff = erofs_pos(src_sbi, erofs_inode_dev_baddr(inode)); - inode->datasource = EROFS_INODE_DATA_SOURCE_REBUILD_BLOB; + inode->datasource.type = + EROFS_INODE_DATA_SOURCE_REBUILD_BLOB; } inode->idata_size = inline_size; @@ -330,7 +332,7 @@ static int erofs_rebuild_update_inode(struct erofs_sb_info *dst_sb, if (datamode == EROFS_REBUILD_DATA_BLOB_INDEX) err = erofs_rebuild_write_blob_index(dst_sb, inode); else if (datamode == EROFS_REBUILD_DATA_RESVSP) - inode->datasource = EROFS_INODE_DATA_SOURCE_RESVSP; + inode->datasource.type = EROFS_INODE_DATA_SOURCE_RESVSP; else if (datamode == EROFS_REBUILD_DATA_FULL) err = erofs_rebuild_write_full_data(inode); else diff --git a/lib/remotes/s3.c b/lib/remotes/s3.c index 245efe5..fb8a1a5 100644 --- a/lib/remotes/s3.c +++ b/lib/remotes/s3.c @@ -1063,33 +1063,36 @@ static int s3erofs_remote_getobject(struct erofs_importer *im, return ret; resp.vf = &sbi->bdev; resp.pos = erofs_pos(inode->sbi, inode->u.i_blkaddr); - inode->datasource = EROFS_INODE_DATA_SOURCE_NONE; + inode->datasource.type = EROFS_INODE_DATA_SOURCE_NONE; } else { - if (!inode->i_diskbuf) { - inode->i_diskbuf = calloc(1, sizeof(*inode->i_diskbuf)); - if (!inode->i_diskbuf) + if (!inode->datasource.diskbuf) { + inode->datasource.diskbuf = + calloc(1, sizeof(*inode->datasource.diskbuf)); + if (!inode->datasource.diskbuf) return -ENOSPC; } else { - erofs_diskbuf_close(inode->i_diskbuf); + erofs_diskbuf_close(inode->datasource.diskbuf); } vf = (struct erofs_vfile) {.fd = - erofs_diskbuf_reserve(inode->i_diskbuf, 0, &diskbuf_off)}; + erofs_diskbuf_reserve(inode->datasource.diskbuf, 0, + &diskbuf_off)}; if (vf.fd < 0) return -EBADF; resp.pos = diskbuf_off; resp.vf = &vf; - inode->datasource = EROFS_INODE_DATA_SOURCE_DISKBUF; + inode->datasource.type = EROFS_INODE_DATA_SOURCE_DISKBUF; } resp.end = resp.pos + inode->i_size; ret = s3erofs_request_perform(s3, &req, &resp); if (resp.vf == &vf) { - erofs_diskbuf_commit(inode->i_diskbuf, resp.pos - diskbuf_off); + erofs_diskbuf_commit(inode->datasource.diskbuf, + resp.pos - diskbuf_off); if (ret) { - erofs_diskbuf_close(inode->i_diskbuf); - inode->i_diskbuf = NULL; - inode->datasource = EROFS_INODE_DATA_SOURCE_NONE; + erofs_diskbuf_close(inode->datasource.diskbuf); + inode->datasource.diskbuf = NULL; + inode->datasource.type = EROFS_INODE_DATA_SOURCE_NONE; } } if (ret) diff --git a/lib/tar.c b/lib/tar.c index 9e53af5..420275a 100644 --- a/lib/tar.c +++ b/lib/tar.c @@ -715,7 +715,7 @@ static int tarerofs_write_uncompressed_file(struct erofs_inode *inode, erofs_sha256_process(&md, buf, ret); } inode->idata_size = 0; - inode->datasource = EROFS_INODE_DATA_SOURCE_NONE; + inode->datasource.type = EROFS_INODE_DATA_SOURCE_NONE; if (ret < 0) return ret; @@ -738,15 +738,16 @@ static int tarerofs_write_file_data(struct erofs_inode *inode, int fd, nread; u64 off, j; - if (!inode->i_diskbuf) { - inode->i_diskbuf = calloc(1, sizeof(*inode->i_diskbuf)); - if (!inode->i_diskbuf) + if (!inode->datasource.diskbuf) { + inode->datasource.diskbuf = + calloc(1, sizeof(*inode->datasource.diskbuf)); + if (!inode->datasource.diskbuf) return -ENOSPC; } else { - erofs_diskbuf_close(inode->i_diskbuf); + erofs_diskbuf_close(inode->datasource.diskbuf); } - fd = erofs_diskbuf_reserve(inode->i_diskbuf, 0, &off); + fd = erofs_diskbuf_reserve(inode->datasource.diskbuf, 0, &off); if (fd < 0) return -EBADF; @@ -766,8 +767,8 @@ static int tarerofs_write_file_data(struct erofs_inode *inode, j -= nread; off += nread; } while (j); - erofs_diskbuf_commit(inode->i_diskbuf, inode->i_size); - inode->datasource = EROFS_INODE_DATA_SOURCE_DISKBUF; + erofs_diskbuf_commit(inode->datasource.diskbuf, inode->i_size); + inode->datasource.type = EROFS_INODE_DATA_SOURCE_DISKBUF; return nread < 0 ? nread : 0; } @@ -1180,14 +1181,16 @@ new_inode: } else if (tar->ddtaridx_mode) { dataoff = le64_to_cpu(*(__le64 *)(th->devmajor)); if (tar->rvsp_mode) { - inode->datasource = EROFS_INODE_DATA_SOURCE_RESVSP; + inode->datasource.type = + EROFS_INODE_DATA_SOURCE_RESVSP; inode->i_ino[1] = dataoff; ret = 0; } else { ret = tarerofs_write_chunkes(inode, dataoff); } } else if (tar->rvsp_mode) { - inode->datasource = EROFS_INODE_DATA_SOURCE_RESVSP; + inode->datasource.type = + EROFS_INODE_DATA_SOURCE_RESVSP; inode->i_ino[1] = dataoff; if (erofs_iostream_lskip(&tar->ios, inode->i_size)) ret = -EIO; -- 2.47.3
