[PATCH 1/2] erofs-utils: lib: fix erofs_io_sendfile()
Gao Xiang
hsiangkao at linux.alibaba.com
Fri Oct 10 14:49:21 AEDT 2025
The fallback logic was incomplete and has been fixed.
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
include/erofs/io.h | 1 +
lib/io.c | 29 ++++++++++++++++++++++-------
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/include/erofs/io.h b/include/erofs/io.h
index a9f6d2e..4bc216a 100644
--- a/include/erofs/io.h
+++ b/include/erofs/io.h
@@ -35,6 +35,7 @@ struct erofs_vfops {
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);
+ ssize_t (*write)(struct erofs_vfile *vf, void *buf, size_t len);
off_t (*lseek)(struct erofs_vfile *vf, u64 offset, int whence);
int (*fstat)(struct erofs_vfile *vf, struct stat *buf);
ssize_t (*sendfile)(struct erofs_vfile *vout, struct erofs_vfile *vin,
diff --git a/lib/io.c b/lib/io.c
index 664dd8d..d4cfbef 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -558,6 +558,13 @@ ssize_t erofs_io_read(struct erofs_vfile *vf, void *buf, size_t bytes)
return i;
}
+ssize_t erofs_io_write(struct erofs_vfile *vf, void *buf, size_t len)
+{
+ if (vf->ops)
+ return vf->ops->write(vf, buf, len);
+ return __erofs_io_write(vf->fd, buf, len);
+}
+
#ifdef HAVE_SYS_SENDFILE_H
#include <sys/sendfile.h>
#endif
@@ -573,7 +580,7 @@ off_t erofs_io_lseek(struct erofs_vfile *vf, u64 offset, int whence)
ssize_t erofs_io_sendfile(struct erofs_vfile *vout, struct erofs_vfile *vin,
off_t *pos, size_t count)
{
- ssize_t written;
+ ssize_t read, written;
if (vin->ops || vout->ops) {
if (vin->ops)
@@ -597,16 +604,24 @@ ssize_t erofs_io_sendfile(struct erofs_vfile *vout, struct erofs_vfile *vin,
while (count) {
char buf[EROFS_MAX_BLOCK_SIZE];
- written = min_t(u64, count, sizeof(buf));
+ read = min_t(u64, count, sizeof(buf));
if (pos)
- written = erofs_io_pread(vin, buf, written, *pos);
+ read = erofs_io_pread(vin, buf, read, *pos);
else
- written = erofs_io_read(vin, buf, written);
- if (written <= 0)
+ read = erofs_io_read(vin, buf, read);
+ if (read <= 0) {
+ written = read;
break;
- count -= written;
+ }
+ count -= read;
if (pos)
- *pos += written;
+ *pos += read;
+ do {
+ written = erofs_io_write(vout, buf, read);
+ if (written < 0)
+ break;
+ read -= written;
+ } while (read);
}
return written < 0 ? written : count;
}
--
2.43.5
More information about the Linux-erofs
mailing list