erofs-utils: add I/O control for tarerofs stream via `erofs_vfile`
authorHongzhen Luo <hongzhen@linux.alibaba.com>
Wed, 12 Jun 2024 03:11:24 +0000 (11:11 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Wed, 12 Jun 2024 17:22:45 +0000 (01:22 +0800)
This adds I/O control for tarerofs stream.

Signed-off-by: Hongzhen Luo <hongzhen@linux.alibaba.com>
Link: https://lore.kernel.org/r/20240612031124.1227558-1-hongzhen@linux.alibaba.com
[ Gao Xiang: code styling fixups. ]
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
include/erofs/internal.h
include/erofs/io.h
include/erofs/tar.h
lib/io.c
lib/tar.c

index f1d85beb5c1a862f02e13a31f42babcfccc0598f..277295e1552184c3ab9bb259449e51cda09feb00 100644 (file)
@@ -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)
index c82dfdf401c83bff14b6ee0c82c219598d5205ba..f24a563b877c8948147ae769760ba183953bf874 100644 (file)
@@ -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);
index b5c966bb9184ac76a4471f25c7ffa659ab10baad..e1de0dfdca7c79ad749266a13c57bc2cae54f38c 100644 (file)
@@ -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;
index 2db384c3da252a14089c505abd53c8281c5e38d0..c523f006a24dd2725014a3d3ff723f537ee78dab 100644 (file)
--- 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);
+}
index 3514381b27ddcb5cb3333b445602115ee971ca84..6202d35f56dafbfb5583ce60bb0910ff56163b95 100644 (file)
--- 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;