[PATCH] erofs-utils: add I/O control for tarerofs stream via `erofs_vfile`
Hongzhen Luo
hongzhen at linux.alibaba.com
Tue Jun 11 21:19:37 AEST 2024
This adds I/O control for tarerofs stream.
Signed-off-by: Hongzhen Luo <hongzhen at linux.alibaba.com>
---
v3: Make the code cleaner.
v2: https://lore.kernel.org/all/20240611095359.294925-1-hongzhen@linux.alibaba.com/
v1: https://lore.kernel.org/all/20240611075445.178659-1-hongzhen@linux.alibaba.com/
---
include/erofs/io.h | 4 ++++
include/erofs/tar.h | 2 +-
lib/io.c | 35 +++++++++++++++++++++++++++++++++++
lib/tar.c | 34 +++++-----------------------------
4 files changed, 45 insertions(+), 30 deletions(-)
diff --git a/include/erofs/io.h b/include/erofs/io.h
index c82dfdf..2c91314 100644
--- a/include/erofs/io.h
+++ b/include/erofs/io.h
@@ -30,6 +30,8 @@ struct erofs_vfops {
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);
+ int (*read)(struct erofs_vfile *vf, void *buf, size_t len);
+ off_t (*lseek)(struct erofs_vfile *vf, u64 offset, int whence);
};
struct erofs_vfile {
@@ -43,6 +45,8 @@ int erofs_io_fsync(struct erofs_vfile *vf);
int 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);
+int 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..8e01948 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -420,3 +420,38 @@ out:
#endif
return __erofs_copy_file_range(fd_in, off_in, fd_out, off_out, length);
}
+
+int erofs_io_read(struct erofs_vfile *vf, void *buf, size_t bytes)
+{
+ s64 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\n",
+ 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.39.3
More information about the Linux-erofs
mailing list