changes since v1: - Rename some fields and fix format issues according to reviewer's comment
Note that all 8 spaces are replaced with tabs, which is not shown in the interdiff below. Yifan Zhao (2): fs/erofs: Add support for EROFS fs/erofs: Add tests for EROFS in grub-fs-tester .gitignore | 1 + INSTALL | 8 +- Makefile.util.def | 7 + docs/grub.texi | 3 +- grub-core/Makefile.core.def | 5 + grub-core/fs/erofs.c | 976 +++++++++++++++++++++++++++++++++++ grub-core/kern/misc.c | 14 + include/grub/misc.h | 1 + tests/erofs_test.in | 20 + tests/util/grub-fs-tester.in | 32 +- 10 files changed, 1055 insertions(+), 12 deletions(-) create mode 100644 grub-core/fs/erofs.c create mode 100644 tests/erofs_test.in Interdiff against v1: diff --git a/docs/grub.texi b/docs/grub.texi index 20c119c96..60c98e931 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -361,7 +361,8 @@ blocklist notation. The currently supported filesystem types are @dfn{Amiga Fast FileSystem (AFFS)}, @dfn{AtheOS fs}, @dfn{BeFS}, @dfn{BtrFS} (including raid0, raid1, raid10, gzip and lzo), @dfn{cpio} (little- and big-endian bin, odc and newc variants), -@dfn{EROFS}, @dfn{Linux ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, +@dfn{EROFS} (only uncompressed support for now), +@dfn{Linux ext2/ext3/ext4}, @dfn{DOS FAT12/FAT16/FAT32}, @dfn{exFAT}, @dfn{F2FS}, @dfn{HFS}, @dfn{HFS+}, @dfn{ISO9660} (including Joliet, Rock-ridge and multi-chunk files), @dfn{JFS}, @dfn{Minix fs} (versions 1, 2 and 3), @dfn{nilfs2}, diff --git a/grub-core/fs/erofs.c b/grub-core/fs/erofs.c index f1366ce05..6552a3fdc 100644 --- a/grub-core/fs/erofs.c +++ b/grub-core/fs/erofs.c @@ -30,8 +30,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); -#define ROUND_UP(x, y) ({ grub_divmod64 (x + (y - 1), y, NULL) * y; }) - #define EROFS_SUPER_OFFSET (1024) #define EROFS_MAGIC 0xE0F5E1E2 #define EROFS_ISLOTBITS (5) @@ -44,7 +42,7 @@ struct grub_erofs_super grub_uint32_t magic; grub_uint32_t checksum; grub_uint32_t feature_compat; - grub_uint8_t blkszbits; + grub_uint8_t log2_blksz; grub_uint8_t sb_extslots; grub_uint16_t root_nid; @@ -67,7 +65,7 @@ struct grub_erofs_super grub_uint16_t extra_devices; grub_uint16_t devt_slotoff; - grub_uint8_t dirblkbits; + grub_uint8_t log2_dirblksz; grub_uint8_t xattr_prefix_count; grub_uint32_t xattr_prefix_start; grub_uint64_t packed_nid; @@ -229,14 +227,14 @@ struct grub_erofs_data struct grub_fshelp_node inode; }; -#define erofs_blocksz(data) (1u << data->sb.blkszbits) +#define erofs_blocksz(data) (1u << data->sb.log2_blksz) static inline grub_uint64_t erofs_iloc (grub_fshelp_node_t node) { struct grub_erofs_super *sb = &node->data->sb; - return (grub_le_to_cpu32 (sb->meta_blkaddr) << sb->blkszbits) + + return (grub_le_to_cpu32 (sb->meta_blkaddr) << sb->log2_blksz) + (node->ino << EROFS_ISLOTBITS); } @@ -333,12 +331,12 @@ grub_erofs_map_blocks_flatmode (grub_fshelp_node_t node, grub_uint32_t blocksz = erofs_blocksz (node->data); file_size = erofs_inode_file_size (node); - nblocks = grub_divmod64 (file_size + blocksz - 1, blocksz, NULL); + nblocks = (file_size + blocksz - 1) >> node->data->sb.log2_blksz; lastblk = nblocks - tailendpacking; map->m_flags = EROFS_MAP_MAPPED; - if (map->m_la < lastblk * blocksz) + if (map->m_la < (lastblk * blocksz)) { map->m_pa = grub_le_to_cpu32 (node->inode.i_u.raw_blkaddr) * blocksz + map->m_la; @@ -347,22 +345,20 @@ grub_erofs_map_blocks_flatmode (grub_fshelp_node_t node, else if (tailendpacking) { map->m_pa = erofs_iloc (node) + erofs_inode_size (node) + - erofs_inode_xattr_ibody_size (node) + map->m_la % blocksz; + erofs_inode_xattr_ibody_size (node) + (map->m_la % blocksz); map->m_plen = file_size - map->m_la; - if (map->m_pa % blocksz + map->m_plen > blocksz) + if (((map->m_pa % blocksz) + map->m_plen) > blocksz) return grub_error ( GRUB_ERR_BAD_FS, "inline data cross block boundary @ inode %" PRIuGRUB_UINT64_T, node->ino); } else - { return grub_error (GRUB_ERR_BAD_FS, - "internal error: invalid map->m_la=%" PRIuGRUB_UINT64_T + "invalid map->m_la=%" PRIuGRUB_UINT64_T " @ inode %" PRIuGRUB_UINT64_T, map->m_la, node->ino); - } map->m_llen = map->m_plen; return GRUB_ERR_NONE; @@ -383,18 +379,18 @@ grub_erofs_map_blocks_chunkmode (grub_fshelp_node_t node, else unit = EROFS_BLOCK_MAP_ENTRY_SIZE; - chunkbits = node->data->sb.blkszbits + + chunkbits = node->data->sb.log2_blksz + (chunk_format & EROFS_CHUNK_FORMAT_BLKBITS_MASK); chunknr = map->m_la >> chunkbits; - pos = ROUND_UP (erofs_iloc (node) + erofs_inode_size (node) + + pos = ALIGN_UP (erofs_iloc (node) + erofs_inode_size (node) + erofs_inode_xattr_ibody_size (node), unit); pos += chunknr * unit; map->m_la = chunknr << chunkbits; map->m_plen = grub_min (1ULL << chunkbits, - ROUND_UP (erofs_inode_file_size (node) - map->m_la, + ALIGN_UP (erofs_inode_file_size (node) - map->m_la, erofs_blocksz (node->data))); if (chunk_format & EROFS_CHUNK_FORMAT_INDEXES) @@ -416,7 +412,7 @@ grub_erofs_map_blocks_chunkmode (grub_fshelp_node_t node, } else { - map->m_pa = blkaddr << node->data->sb.blkszbits; + map->m_pa = blkaddr << node->data->sb.log2_blksz; map->m_flags = EROFS_MAP_MAPPED; } } @@ -438,7 +434,7 @@ grub_erofs_map_blocks_chunkmode (grub_fshelp_node_t node, } else { - map->m_pa = blkaddr << node->data->sb.blkszbits; + map->m_pa = blkaddr << node->data->sb.log2_blksz; map->m_flags = EROFS_MAP_MAPPED; } } @@ -894,7 +890,10 @@ grub_erofs_close (grub_file_t file) static grub_err_t grub_erofs_uuid (grub_device_t device, char **uuid) { - struct grub_erofs_data *data = grub_erofs_mount (device->disk, false); + struct grub_erofs_data *data; + + grub_errno = GRUB_ERR_NONE; + data = grub_erofs_mount (device->disk, false); if (data) *uuid = grub_xasprintf ( @@ -916,7 +915,10 @@ grub_erofs_uuid (grub_device_t device, char **uuid) static grub_err_t grub_erofs_label (grub_device_t device, char **label) { - struct grub_erofs_data *data = grub_erofs_mount (device->disk, false); + struct grub_erofs_data *data; + + grub_errno = GRUB_ERR_NONE; + data = grub_erofs_mount (device->disk, false); if (data) *label = grub_strndup ((char *) data->sb.volume_name, @@ -932,7 +934,10 @@ grub_erofs_label (grub_device_t device, char **label) static grub_err_t grub_erofs_mtime (grub_device_t device, grub_int64_t *tm) { - struct grub_erofs_data *data = grub_erofs_mount (device->disk, false); + struct grub_erofs_data *data; + + grub_errno = GRUB_ERR_NONE; + data = grub_erofs_mount (device->disk, false); if (!data) *tm = 0; -- 2.41.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel