From 857663c608c5d249db7663d0edcd7071de4e67bc Mon Sep 17 00:00:00 2001 From: Hongzhen Luo Date: Wed, 12 Jun 2024 11:11:24 +0800 Subject: [PATCH] erofs-utils: add I/O control for tarerofs stream via `erofs_vfile` This adds I/O control for tarerofs stream. Signed-off-by: Hongzhen Luo Link: https://lore.kernel.org/r/20240612031124.1227558-1-hongzhen@linux.alibaba.com [ Gao Xiang: code styling fixups. ] Signed-off-by: Gao Xiang --- include/erofs/internal.h | 4 ++-- include/erofs/io.h | 14 +++++++---- include/erofs/tar.h | 2 +- lib/io.c | 51 +++++++++++++++++++++++++++++++++------- lib/tar.c | 34 ++++----------------------- 5 files changed, 60 insertions(+), 45 deletions(-) diff --git a/include/erofs/internal.h b/include/erofs/internal.h index f1d85be..277295e 100644 --- a/include/erofs/internal.h +++ b/include/erofs/internal.h @@ -453,8 +453,8 @@ void erofs_dev_close(struct erofs_sb_info *sbi); void erofs_blob_closeall(struct erofs_sb_info *sbi); int erofs_blob_open_ro(struct erofs_sb_info *sbi, const char *dev); -int erofs_dev_read(struct erofs_sb_info *sbi, int device_id, - void *buf, u64 offset, size_t len); +ssize_t erofs_dev_read(struct erofs_sb_info *sbi, int device_id, + void *buf, u64 offset, size_t len); static inline int erofs_dev_write(struct erofs_sb_info *sbi, const void *buf, u64 offset, size_t len) diff --git a/include/erofs/io.h b/include/erofs/io.h index c82dfdf..f24a563 100644 --- a/include/erofs/io.h +++ b/include/erofs/io.h @@ -25,11 +25,13 @@ extern "C" struct erofs_vfile; struct erofs_vfops { - int (*pread)(struct erofs_vfile *vf, void *buf, u64 offset, size_t len); - int (*pwrite)(struct erofs_vfile *vf, const void *buf, u64 offset, size_t len); + ssize_t (*pread)(struct erofs_vfile *vf, void *buf, u64 offset, size_t len); + ssize_t (*pwrite)(struct erofs_vfile *vf, const void *buf, u64 offset, size_t len); int (*fsync)(struct erofs_vfile *vf); int (*fallocate)(struct erofs_vfile *vf, u64 offset, size_t len, bool pad); int (*ftruncate)(struct erofs_vfile *vf, u64 length); + ssize_t (*read)(struct erofs_vfile *vf, void *buf, size_t len); + off_t (*lseek)(struct erofs_vfile *vf, u64 offset, int whence); }; struct erofs_vfile { @@ -38,11 +40,13 @@ struct erofs_vfile { int fd; }; -int erofs_io_pwrite(struct erofs_vfile *vf, const void *buf, u64 pos, size_t len); +ssize_t erofs_io_pwrite(struct erofs_vfile *vf, const void *buf, u64 pos, size_t len); int erofs_io_fsync(struct erofs_vfile *vf); -int erofs_io_fallocate(struct erofs_vfile *vf, u64 offset, size_t len, bool pad); +ssize_t erofs_io_fallocate(struct erofs_vfile *vf, u64 offset, size_t len, bool pad); int erofs_io_ftruncate(struct erofs_vfile *vf, u64 length); -int erofs_io_pread(struct erofs_vfile *vf, void *buf, u64 offset, size_t len); +ssize_t erofs_io_pread(struct erofs_vfile *vf, void *buf, u64 offset, size_t len); +ssize_t erofs_io_read(struct erofs_vfile *vf, void *buf, size_t len); +off_t erofs_io_lseek(struct erofs_vfile *vf, u64 offset, int whence); ssize_t erofs_copy_file_range(int fd_in, u64 *off_in, int fd_out, u64 *off_out, size_t length); diff --git a/include/erofs/tar.h b/include/erofs/tar.h index b5c966b..e1de0df 100644 --- a/include/erofs/tar.h +++ b/include/erofs/tar.h @@ -39,7 +39,7 @@ struct erofs_iostream_liblzma { struct erofs_iostream { union { - int fd; /* original fd */ + struct erofs_vfile vf; void *handler; #ifdef HAVE_LIBLZMA struct erofs_iostream_liblzma *lzma; diff --git a/lib/io.c b/lib/io.c index 2db384c..c523f00 100644 --- a/lib/io.c +++ b/lib/io.c @@ -26,8 +26,8 @@ #define EROFS_MODNAME "erofs_io" #include "erofs/print.h" -int erofs_io_pwrite(struct erofs_vfile *vf, const void *buf, - u64 pos, size_t len) +ssize_t erofs_io_pwrite(struct erofs_vfile *vf, const void *buf, + u64 pos, size_t len) { ssize_t ret; @@ -74,11 +74,11 @@ int erofs_io_fsync(struct erofs_vfile *vf) return 0; } -int erofs_io_fallocate(struct erofs_vfile *vf, u64 offset, - size_t len, bool zeroout) +ssize_t erofs_io_fallocate(struct erofs_vfile *vf, u64 offset, + size_t len, bool zeroout) { static const char zero[EROFS_MAX_BLOCK_SIZE] = {0}; - int ret; + ssize_t ret; if (unlikely(cfg.c_dry_run)) return 0; @@ -123,7 +123,7 @@ int erofs_io_ftruncate(struct erofs_vfile *vf, u64 length) return ftruncate(vf->fd, length); } -int erofs_io_pread(struct erofs_vfile *vf, void *buf, u64 pos, size_t len) +ssize_t erofs_io_pread(struct erofs_vfile *vf, void *buf, u64 pos, size_t len) { ssize_t ret; @@ -317,8 +317,8 @@ int erofs_blob_open_ro(struct erofs_sb_info *sbi, const char *dev) return 0; } -int erofs_dev_read(struct erofs_sb_info *sbi, int device_id, - void *buf, u64 offset, size_t len) +ssize_t erofs_dev_read(struct erofs_sb_info *sbi, int device_id, + void *buf, u64 offset, size_t len) { if (device_id) return erofs_io_pread(&((struct erofs_vfile) { @@ -420,3 +420,38 @@ out: #endif return __erofs_copy_file_range(fd_in, off_in, fd_out, off_out, length); } + +ssize_t erofs_io_read(struct erofs_vfile *vf, void *buf, size_t bytes) +{ + ssize_t i = 0; + + if (vf->ops) + return vf->ops->read(vf, buf, bytes); + + while (bytes) { + int len = bytes > INT_MAX ? INT_MAX : bytes; + int ret; + + ret = read(vf->fd, buf + i, len); + if (ret < 1) { + if (ret == 0) { + break; + } else if (errno != EINTR) { + erofs_err("failed to read : %s", + strerror(errno)); + return -errno; + } + } + bytes -= ret; + i += ret; + } + return i; +} + +off_t erofs_io_lseek(struct erofs_vfile *vf, u64 offset, int whence) +{ + if (vf->ops) + return vf->ops->lseek(vf, offset, whence); + + return lseek(vf->fd, offset, whence); +} diff --git a/lib/tar.c b/lib/tar.c index 3514381..6202d35 100644 --- a/lib/tar.c +++ b/lib/tar.c @@ -39,30 +39,6 @@ struct tar_header { char padding[12]; /* 500-512 (pad to exactly the 512 byte) */ }; -s64 erofs_read_from_fd(int fd, void *buf, u64 bytes) -{ - s64 i = 0; - - while (bytes) { - int len = bytes > INT_MAX ? INT_MAX : bytes; - int ret; - - ret = read(fd, buf + i, len); - if (ret < 1) { - if (ret == 0) { - break; - } else if (errno != EINTR) { - erofs_err("failed to read : %s\n", - strerror(errno)); - return -errno; - } - } - bytes -= ret; - i += ret; - } - return i; -} - void erofs_iostream_close(struct erofs_iostream *ios) { free(ios->buffer); @@ -79,7 +55,7 @@ void erofs_iostream_close(struct erofs_iostream *ios) #endif return; } - close(ios->fd); + close(ios->vf.fd); } int erofs_iostream_open(struct erofs_iostream *ios, int fd, int decoder) @@ -119,7 +95,7 @@ int erofs_iostream_open(struct erofs_iostream *ios, int fd, int decoder) return -EOPNOTSUPP; #endif } else { - ios->fd = fd; + ios->vf.fd = fd; fsz = lseek(fd, 0, SEEK_END); if (fsz <= 0) { ios->feof = !fsz; @@ -218,8 +194,8 @@ int erofs_iostream_read(struct erofs_iostream *ios, void **buf, u64 bytes) return -EOPNOTSUPP; #endif } else { - ret = erofs_read_from_fd(ios->fd, ios->buffer + rabytes, - ios->bufsize - rabytes); + ret = erofs_io_read(&ios->vf, ios->buffer + rabytes, + ios->bufsize - rabytes); if (ret < 0) return ret; ios->tail += ret; @@ -271,7 +247,7 @@ int erofs_iostream_lskip(struct erofs_iostream *ios, u64 sz) return sz; if (ios->sz && likely(ios->dumpfd < 0)) { - s64 cur = lseek(ios->fd, sz, SEEK_CUR); + s64 cur = erofs_io_lseek(&ios->vf, sz, SEEK_CUR); if (cur > ios->sz) return cur - ios->sz; -- 2.34.1