Re: Re: [PATCH] erofs: support for mounting a single block device with multiple devices

From: Jia Zhu
Date: Wed Mar 01 2023 - 02:45:10 EST




在 2023/3/1 15:08, Gao Xiang 写道:
Hi Jia,

On 2023/3/1 15:04, Jia Zhu wrote:
In order to support mounting multi-layer container image as a block
device, add single block device with multiple devices feature for EROFS.

In order to support mounting multi-blob container image as a single
flattened block device, add flattened block device feature for EROFS.

Thanks, I would revise it.

In this mode, all meta/data contents will be mapped into one block address.
User could directly mount the block device by EROFS.

Signed-off-by: Jia Zhu <zhujia.zj@xxxxxxxxxxxxx>
Reviewed-by: Xin Yin <yinxin.x@xxxxxxxxxxxxx>
---
  fs/erofs/data.c  | 8 ++++++--
  fs/erofs/super.c | 5 +++++
  2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/fs/erofs/data.c b/fs/erofs/data.c
index e16545849ea7..870b1f7fe1d4 100644
--- a/fs/erofs/data.c
+++ b/fs/erofs/data.c
@@ -195,9 +195,9 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
  {
      struct erofs_dev_context *devs = EROFS_SB(sb)->devs;
      struct erofs_device_info *dif;
+    bool flatdev = !!sb->s_bdev;

I'd like to land it in sbi and set it in advance?

I'll revise that in next version.
Also, did you test this patch?

I've tested the patch using the following steps mentioned by
https://github.com/dragonflyoss/image-service/pull/1111

1. Compose a (nbd)block device from an EROFS image.
2. mount -t erofs /dev/nbdx /mnt/
3. compare the md5sum between source dir and /mnt dir.


Thanks,
Gao Xiang


      int id;
-    /* primary device by default */
      map->m_bdev = sb->s_bdev;
      map->m_daxdev = EROFS_SB(sb)->dax_dev;
      map->m_dax_part_off = EROFS_SB(sb)->dax_part_off;
@@ -210,12 +210,16 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
              up_read(&devs->rwsem);
              return -ENODEV;
          }
+        if (flatdev) {
+            map->m_pa += blknr_to_addr(dif->mapped_blkaddr);
+            map->m_deviceid = 0;
+        }
          map->m_bdev = dif->bdev;
          map->m_daxdev = dif->dax_dev;
          map->m_dax_part_off = dif->dax_part_off;
          map->m_fscache = dif->fscache;
          up_read(&devs->rwsem);
-    } else if (devs->extra_devices) {
+    } else if (devs->extra_devices && !flatdev) {
          down_read(&devs->rwsem);
          idr_for_each_entry(&devs->tree, dif, id) {
              erofs_off_t startoff, length;
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index 19b1ae79cec4..4f9725b0950c 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -226,6 +226,7 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
      struct erofs_fscache *fscache;
      struct erofs_deviceslot *dis;
      struct block_device *bdev;
+    bool flatdev = !!sb->s_bdev;
      void *ptr;
      ptr = erofs_read_metabuf(buf, sb, erofs_blknr(*pos), EROFS_KMAP);
@@ -248,6 +249,10 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb,
          if (IS_ERR(fscache))
              return PTR_ERR(fscache);
          dif->fscache = fscache;
+    } else if (flatdev) {
+        dif->bdev = sb->s_bdev;
+        dif->dax_dev = EROFS_SB(sb)->dax_dev;
+        dif->dax_part_off = sbi->dax_part_off;
      } else {
          bdev = blkdev_get_by_path(dif->path, FMODE_READ | FMODE_EXCL,
                        sb->s_type);