[PATCH v4 1/6] erofs-utils: add extra device I/O interface
Gao Xiang
hsiangkao at linux.alibaba.com
Tue Nov 16 20:49:34 AEDT 2021
In order for erofsfuse to support multiple devices.
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
fsck/main.c | 8 ++++----
include/erofs/io.h | 10 ++++++----
lib/data.c | 6 +++---
lib/io.c | 48 +++++++++++++++++++++++++++++++++++++---------
lib/namei.c | 4 ++--
lib/super.c | 2 +-
lib/zmap.c | 4 ++--
mkfs/main.c | 2 +-
8 files changed, 58 insertions(+), 26 deletions(-)
diff --git a/fsck/main.c b/fsck/main.c
index d81d60024c8a..b742e3579c59 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -97,7 +97,7 @@ static int erofs_check_sb_chksum(void)
u32 crc;
struct erofs_super_block *sb;
- ret = blk_read(buf, 0, 1);
+ ret = blk_read(0, buf, 0, 1);
if (ret) {
erofs_err("failed to read superblock to check checksum: %d",
ret);
@@ -317,7 +317,7 @@ static int verify_compressed_inode(struct erofs_inode *inode)
BUG_ON(!buffer);
}
- ret = dev_read(raw, map.m_pa, map.m_plen);
+ ret = dev_read(0, raw, map.m_pa, map.m_plen);
if (ret < 0) {
erofs_err("failed to read compressed data of m_pa %" PRIu64 ", m_plen %" PRIu64 " @ nid %llu: %d",
map.m_pa, map.m_plen, inode->nid | 0ULL, ret);
@@ -381,7 +381,7 @@ static int erofs_verify_xattr(struct erofs_inode *inode)
}
addr = iloc(inode->nid) + inode->inode_isize;
- ret = dev_read(buf, addr, xattr_hdr_size);
+ ret = dev_read(0, buf, addr, xattr_hdr_size);
if (ret < 0) {
erofs_err("failed to read xattr header @ nid %llu: %d",
inode->nid | 0ULL, ret);
@@ -411,7 +411,7 @@ static int erofs_verify_xattr(struct erofs_inode *inode)
while (remaining > 0) {
unsigned int entry_sz;
- ret = dev_read(buf, addr, xattr_entry_size);
+ ret = dev_read(0, buf, addr, xattr_entry_size);
if (ret) {
erofs_err("failed to read xattr entry @ nid %llu: %d",
inode->nid | 0ULL, ret);
diff --git a/include/erofs/io.h b/include/erofs/io.h
index 9d73adc5f5f9..10a3681882e1 100644
--- a/include/erofs/io.h
+++ b/include/erofs/io.h
@@ -15,11 +15,13 @@
#define O_BINARY 0
#endif
+void blob_closeall(void);
+int blob_open_ro(const char *dev);
int dev_open(const char *devname);
int dev_open_ro(const char *dev);
void dev_close(void);
int dev_write(const void *buf, u64 offset, size_t len);
-int dev_read(void *buf, u64 offset, size_t len);
+int dev_read(int device_id, void *buf, u64 offset, size_t len);
int dev_fillzero(u64 offset, size_t len, bool padding);
int dev_fsync(void);
int dev_resize(erofs_blk_t nblocks);
@@ -38,10 +40,10 @@ static inline int blk_write(const void *buf, erofs_blk_t blkaddr,
blknr_to_addr(nblocks));
}
-static inline int blk_read(void *buf, erofs_blk_t start,
- u32 nblocks)
+static inline int blk_read(int device_id, void *buf,
+ erofs_blk_t start, u32 nblocks)
{
- return dev_read(buf, blknr_to_addr(start),
+ return dev_read(device_id, buf, blknr_to_addr(start),
blknr_to_addr(nblocks));
}
diff --git a/lib/data.c b/lib/data.c
index b5f0196c97dd..b83cbff3e731 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -91,7 +91,7 @@ int erofs_map_blocks(struct erofs_inode *inode,
pos = roundup(iloc(vi->nid) + vi->inode_isize +
vi->xattr_isize, unit) + unit * chunknr;
- err = blk_read(buf, erofs_blknr(pos), 1);
+ err = blk_read(0, buf, erofs_blknr(pos), 1);
if (err < 0)
return -EIO;
@@ -176,7 +176,7 @@ static int erofs_read_raw_data(struct erofs_inode *inode, char *buffer,
map.m_la = ptr;
}
- ret = dev_read(estart, map.m_pa, eend - map.m_la);
+ ret = dev_read(0, estart, map.m_pa, eend - map.m_la);
if (ret < 0)
return -EIO;
ptr = eend;
@@ -240,7 +240,7 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer,
break;
}
}
- ret = dev_read(raw, map.m_pa, map.m_plen);
+ ret = dev_read(0, raw, map.m_pa, map.m_plen);
if (ret < 0)
break;
diff --git a/lib/io.c b/lib/io.c
index 279c7dd4b877..a0d366a4c3f1 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -26,6 +26,7 @@
static const char *erofs_devname;
int erofs_devfd = -1;
static u64 erofs_devsz;
+static unsigned int erofs_nblobs, erofs_blobfd[256];
int dev_get_blkdev_size(int fd, u64 *bytes)
{
@@ -106,6 +107,30 @@ int dev_open(const char *dev)
return 0;
}
+void blob_closeall(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < erofs_nblobs; ++i)
+ close(erofs_blobfd[i]);
+ erofs_nblobs = 0;
+}
+
+int blob_open_ro(const char *dev)
+{
+ int fd = open(dev, O_RDONLY | O_BINARY);
+
+ if (fd < 0) {
+ erofs_err("failed to open(%s).", dev);
+ return -errno;
+ }
+
+ erofs_blobfd[erofs_nblobs] = fd;
+ erofs_info("successfully to open blob%u %s", erofs_nblobs, dev);
+ ++erofs_nblobs;
+ return 0;
+}
+
/* XXX: temporary soluation. Disk I/O implementation needs to be refactored. */
int dev_open_ro(const char *dev)
{
@@ -229,9 +254,9 @@ int dev_resize(unsigned int blocks)
return dev_fillzero(st.st_size, length, true);
}
-int dev_read(void *buf, u64 offset, size_t len)
+int dev_read(int device_id, void *buf, u64 offset, size_t len)
{
- int ret;
+ int ret, fd;
if (cfg.c_dry_run)
return 0;
@@ -240,16 +265,21 @@ int dev_read(void *buf, u64 offset, size_t len)
erofs_err("buf is NULL");
return -EINVAL;
}
- if (offset >= erofs_devsz || len > erofs_devsz ||
- offset > erofs_devsz - len) {
- erofs_err("read posion[%" PRIu64 ", %zd] is too large beyond the end of device(%" PRIu64 ").",
- offset, len, erofs_devsz);
- return -EINVAL;
+
+ if (!device_id) {
+ fd = erofs_devfd;
+ } else {
+ if (device_id > erofs_nblobs) {
+ erofs_err("invalid device id %d", device_id);
+ return -ENODEV;
+ }
+ fd = erofs_blobfd[device_id - 1];
}
+
#ifdef HAVE_PREAD64
- ret = pread64(erofs_devfd, buf, len, (off64_t)offset);
+ ret = pread64(fd, buf, len, (off64_t)offset);
#else
- ret = pread(erofs_devfd, buf, len, (off_t)offset);
+ ret = pread(fd, buf, len, (off_t)offset);
#endif
if (ret != (int)len) {
erofs_err("Failed to read data from device - %s:[%" PRIu64 ", %zd].",
diff --git a/lib/namei.c b/lib/namei.c
index 56f199aba382..7377e74fad9b 100644
--- a/lib/namei.c
+++ b/lib/namei.c
@@ -30,7 +30,7 @@ int erofs_read_inode_from_disk(struct erofs_inode *vi)
struct erofs_inode_extended *die;
const erofs_off_t inode_loc = iloc(vi->nid);
- ret = dev_read(buf, inode_loc, sizeof(*dic));
+ ret = dev_read(0, buf, inode_loc, sizeof(*dic));
if (ret < 0)
return -EIO;
@@ -47,7 +47,7 @@ int erofs_read_inode_from_disk(struct erofs_inode *vi)
case EROFS_INODE_LAYOUT_EXTENDED:
vi->inode_isize = sizeof(struct erofs_inode_extended);
- ret = dev_read(buf + sizeof(*dic), inode_loc + sizeof(*dic),
+ ret = dev_read(0, buf + sizeof(*dic), inode_loc + sizeof(*dic),
sizeof(*die) - sizeof(*dic));
if (ret < 0)
return -EIO;
diff --git a/lib/super.c b/lib/super.c
index 0c3040394272..bf4d4318a321 100644
--- a/lib/super.c
+++ b/lib/super.c
@@ -30,7 +30,7 @@ int erofs_read_superblock(void)
unsigned int blkszbits;
int ret;
- ret = blk_read(data, 0, 1);
+ ret = blk_read(0, data, 0, 1);
if (ret < 0) {
erofs_err("cannot read erofs superblock: %d", ret);
return -EIO;
diff --git a/lib/zmap.c b/lib/zmap.c
index 7dbda87c3b13..9dd0c7633a45 100644
--- a/lib/zmap.c
+++ b/lib/zmap.c
@@ -38,7 +38,7 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY);
pos = round_up(iloc(vi->nid) + vi->inode_isize + vi->xattr_isize, 8);
- ret = dev_read(buf, pos, sizeof(buf));
+ ret = dev_read(0, buf, pos, sizeof(buf));
if (ret < 0)
return -EIO;
@@ -88,7 +88,7 @@ static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m,
if (map->index == eblk)
return 0;
- ret = blk_read(mpage, eblk, 1);
+ ret = blk_read(0, mpage, eblk, 1);
if (ret < 0)
return -EIO;
diff --git a/mkfs/main.c b/mkfs/main.c
index 4ea5467679b7..2604bf2abd6b 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -436,7 +436,7 @@ static int erofs_mkfs_superblock_csum_set(void)
u32 crc;
struct erofs_super_block *sb;
- ret = blk_read(buf, 0, 1);
+ ret = blk_read(0, buf, 0, 1);
if (ret) {
erofs_err("failed to read superblock to set checksum: %s",
erofs_strerror(ret));
--
2.24.4
More information about the Linux-erofs
mailing list