When using `fsck.erofs` to extract some image have a very large file inside, for example 2G, my fsck.erofs report some thing like this:
<E> erofs_io: Failed to read data from device - erofs.image:[4096, 2147483648]. <E> erofs: failed to read data of m_pa 4096, m_plen 2147483648 @ nid 40: -17 <E> erofs: Failed to extract filesystem You can use this script to reproduce this issue. mkdir tmp extract dd if=/dev/urandom of=tmp/big_file bs=1M count=2048 mkfs.erofs erofs.image tmp fsck.erofs erofs.image --extract=extract I found that dev_open will failed if we can not get all data we want with one pread call. I write this little patch try to fix this issue. Signed-off-by: Chen Linxuan <chenlinx...@uniontech.com> --- lib/io.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/io.c b/lib/io.c index 524cfb4..ccd433f 100644 --- a/lib/io.c +++ b/lib/io.c @@ -256,7 +256,7 @@ int dev_resize(unsigned int blocks) int dev_read(int device_id, void *buf, u64 offset, size_t len) { - int ret, fd; + int read_count, fd; if (cfg.c_dry_run) return 0; @@ -278,15 +278,27 @@ int dev_read(int device_id, void *buf, u64 offset, size_t len) fd = erofs_blobfd[device_id - 1]; } + while (len > 0) { #ifdef HAVE_PREAD64 - ret = pread64(fd, buf, len, (off64_t)offset); + read_count = pread64(fd, buf, len, (off64_t)offset); #else - ret = pread(fd, buf, len, (off_t)offset); + read_count = pread(fd, buf, len, (off_t)offset); #endif - if (ret != (int)len) { - erofs_err("Failed to read data from device - %s:[%" PRIu64 ", %zd].", - erofs_devname, offset, len); - return -errno; + if (read_count == -1 || read_count == 0) { + if (errno) { + erofs_err("Failed to read data from device - %s:[%" PRIu64 ", %zd].", + erofs_devname, offset, len); + return -errno; + } else { + erofs_err("Reach EOF of device - %s:[%" PRIu64 ", %zd].", + erofs_devname, offset, len); + return -EINVAL; + } + } + + offset += read_count; + len -= read_count; + buf += read_count; } return 0; } -- 2.37.3