erofs-utils: mkfs: support flatdev for multi-blob images
authorJingbo Xu <jefflexu@linux.alibaba.com>
Fri, 15 Sep 2023 11:53:33 +0000 (19:53 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Fri, 15 Sep 2023 15:01:39 +0000 (23:01 +0800)
Since kernel commit 8b465fecc35a ("erofs: support flattened block device
for multi-blob images"), the flatdev feature has been introduced to
support mounting multi-blobs container image as a single block device.

To enable this feature, the mapped_blkaddr of each device slot needs to
be set properly to the offset of the device in the flat address space.

The uuid of the source image is used as the corresponding device tag
in rebuild mode.

Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Link: https://lore.kernel.org/r/20230915115333.17599-1-jefflexu@linux.alibaba.com
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
include/erofs/internal.h
lib/blobchunk.c
lib/super.c
mkfs/main.c

index 19b912bb8299c45e4e6f6fba5a950e905637058e..616cd3ad3a4204ec5fe51c4c408dfedbdb17af20 100644 (file)
@@ -54,6 +54,7 @@ extern struct erofs_sb_info sbi;
 struct erofs_buffer_head;
 
 struct erofs_device_info {
+       u8 tag[64];
        u32 blocks;
        u32 mapped_blkaddr;
 };
index aca616e08ac8d5bb9a86eefec328ce09739ccfa6..a599f3a921a39675ae9b2809c61cf6fa58e2c5b8 100644 (file)
@@ -410,20 +410,24 @@ int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi)
        }
 
        if (sbi->extra_devices) {
-               unsigned int i;
+               unsigned int i, ret;
+               erofs_blk_t nblocks;
 
+               nblocks = erofs_mapbh(NULL);
                pos_out = erofs_btell(bh_devt, false);
                i = 0;
                do {
                        struct erofs_deviceslot dis = {
+                               .mapped_blkaddr = cpu_to_le32(nblocks),
                                .blocks = cpu_to_le32(sbi->devs[i].blocks),
                        };
-                       int ret;
 
+                       memcpy(dis.tag, sbi->devs[i].tag, sizeof(dis.tag));
                        ret = dev_write(sbi, &dis, pos_out, sizeof(dis));
                        if (ret)
                                return ret;
                        pos_out += sizeof(dis);
+                       nblocks += sbi->devs[i].blocks;
                } while (++i < sbi->extra_devices);
                bh_devt->op = &erofs_drop_directly_bhops;
                erofs_bdrop(bh_devt, false);
index ce97278b2365bbaa9f6327e12ed7016a850dd38e..f952f7ed41bb763fe8d014b4aa056330438412a4 100644 (file)
@@ -65,6 +65,7 @@ static int erofs_init_devices(struct erofs_sb_info *sbi,
 
                sbi->devs[i].mapped_blkaddr = le32_to_cpu(dis.mapped_blkaddr);
                sbi->devs[i].blocks = le32_to_cpu(dis.blocks);
+               memcpy(sbi->devs[i].tag, dis.tag, sizeof(dis.tag));
                sbi->total_blocks += sbi->devs[i].blocks;
                pos += EROFS_DEVT_SLOT_SIZE;
        }
index 4fa2d92a8454dae95fa48452c15f30e4e438ad9c..a765743355aa1f3c0da70b831dccc7eecc66adec 100644 (file)
@@ -822,7 +822,7 @@ static int erofs_rebuild_load_trees(struct erofs_inode *root)
        struct erofs_sb_info *src;
        unsigned int extra_devices = 0;
        erofs_blk_t nblocks;
-       int ret;
+       int ret, idx;
 
        list_for_each_entry(src, &rebuild_src_list, list) {
                ret = erofs_rebuild_load_tree(root, src);
@@ -849,12 +849,31 @@ static int erofs_rebuild_load_trees(struct erofs_inode *root)
                return ret;
 
        list_for_each_entry(src, &rebuild_src_list, list) {
-               if (extra_devices)
+               u8 *tag = NULL;
+
+               if (extra_devices) {
                        nblocks = src->devs[0].blocks;
-               else
+                       tag = src->devs[0].tag;
+               } else {
                        nblocks = src->primarydevice_blocks;
+               }
                DBG_BUGON(src->dev < 1);
-               sbi.devs[src->dev - 1].blocks = nblocks;
+               idx = src->dev - 1;
+               sbi.devs[idx].blocks = nblocks;
+               if (tag && *tag)
+                       memcpy(sbi.devs[idx].tag, tag, sizeof(sbi.devs[0].tag));
+               else
+                       /* convert UUID of the source image to a hex string */
+                       sprintf((char *)sbi.devs[idx].tag,
+                               "%04x%04x%04x%04x%04x%04x%04x%04x",
+                               (src->uuid[0] << 8) | src->uuid[1],
+                               (src->uuid[2] << 8) | src->uuid[3],
+                               (src->uuid[4] << 8) | src->uuid[5],
+                               (src->uuid[6] << 8) | src->uuid[7],
+                               (src->uuid[8] << 8) | src->uuid[9],
+                               (src->uuid[10] << 8) | src->uuid[11],
+                               (src->uuid[12] << 8) | src->uuid[13],
+                               (src->uuid[14] << 8) | src->uuid[15]);
        }
        return 0;
 }