EROFS [1] is a lightweight read-only filesystem designed for performance
which has already been shipped in most Linux distributions as well as widely
used in several scenarios, such as Android system partitions, container
images, and rootfs for embedded devices.

This patch brings EROFS uncompressed support together with related tests.
Now, it's possible to boot directly through GRUB with an EROFS rootfs.

EROFS compressed files will be supported later since it has more work to
polish.

[1] https://erofs.docs.kernel.org

changelog since v5:
- add comment for abbreviated fields in `grub_erofs_map_blocks`
- fix buggy code which does not consider endianness
- use grub_uint8_t* instead of char* for pointer casting in `erofs_read_inode`
- other style and readability improvements according to Glenn's review

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         | 980 +++++++++++++++++++++++++++++++++++
 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, 1059 insertions(+), 12 deletions(-)
 create mode 100644 grub-core/fs/erofs.c
 create mode 100644 tests/erofs_test.in

Interdiff against v5:
diff --git a/grub-core/fs/erofs.c b/grub-core/fs/erofs.c
index 34f16ba20..8d143dd1b 100644
--- a/grub-core/fs/erofs.c
+++ b/grub-core/fs/erofs.c
@@ -178,10 +178,10 @@ struct grub_erofs_dirent
 
 struct grub_erofs_map_blocks
 {
-  grub_uint64_t m_pa;
-  grub_uint64_t m_la;
-  grub_uint64_t m_plen;
-  grub_uint64_t m_llen;
+  grub_uint64_t m_pa;    /* physical address */
+  grub_uint64_t m_la;    /* logical address */
+  grub_uint64_t m_plen;  /* physical length */
+  grub_uint64_t m_llen;  /* logical length */
   grub_uint32_t m_flags;
 };
 
@@ -229,6 +229,7 @@ erofs_read_inode (struct grub_erofs_data *data, 
grub_fshelp_node_t node)
 {
   struct grub_erofs_inode_compact *dic;
   grub_err_t err;
+  grub_uint16_t i_format;
   grub_uint64_t addr = erofs_iloc (node);
 
   dic = (struct grub_erofs_inode_compact *) &node->inode;
@@ -239,8 +240,9 @@ erofs_read_inode (struct grub_erofs_data *data, 
grub_fshelp_node_t node)
   if (err != GRUB_ERR_NONE)
     return err;
 
-  node->inode_type = (dic->i_format >> EROFS_I_VERSION_BIT) & 
EROFS_I_VERSION_MASKS;
-  node->inode_datalayout = (dic->i_format >> EROFS_I_DATALAYOUT_BIT) & 
EROFS_I_DATALAYOUT_MASKS;
+  i_format = grub_le_to_cpu16 (dic->i_format);
+  node->inode_type = (i_format >> EROFS_I_VERSION_BIT) & EROFS_I_VERSION_MASKS;
+  node->inode_datalayout = (i_format >> EROFS_I_DATALAYOUT_BIT) & 
EROFS_I_DATALAYOUT_MASKS;
 
   switch (node->inode_type)
     {
@@ -250,7 +252,7 @@ erofs_read_inode (struct grub_erofs_data *data, 
grub_fshelp_node_t node)
          data->disk, addr >> GRUB_DISK_SECTOR_BITS,
          addr & (GRUB_DISK_SECTOR_SIZE - 1),
          sizeof (struct grub_erofs_inode_extended) - sizeof (struct 
grub_erofs_inode_compact),
-         (char *) dic + sizeof (struct grub_erofs_inode_compact));
+         (grub_uint8_t *) dic + sizeof (struct grub_erofs_inode_compact));
       if (err != GRUB_ERR_NONE)
        return err;
       break;
@@ -292,7 +294,7 @@ erofs_inode_xattr_ibody_size (grub_fshelp_node_t node)
   if (cnt == 0)
     return 0;
 
-  return sizeof (struct grub_erofs_xattr_ibody_header) + (cnt - 1) * sizeof 
(grub_uint32_t);
+  return sizeof (struct grub_erofs_xattr_ibody_header) + ((cnt - 1) * sizeof 
(grub_uint32_t));
 }
 
 static grub_uint64_t
@@ -313,7 +315,7 @@ erofs_map_blocks_flatmode (grub_fshelp_node_t node,
 
   file_size = erofs_inode_file_size (node);
   nblocks = (file_size + blocksz - 1) >> node->data->sb.log2_blksz;
-  lastblk = nblocks - (tailendpacking ? 1 : 0);
+  lastblk = nblocks - tailendpacking;
 
   map->m_flags = EROFS_MAP_MAPPED;
 
@@ -804,7 +806,7 @@ static grub_err_t
 grub_erofs_open (grub_file_t file, const char *name)
 {
   struct grub_erofs_data *data;
-  struct grub_fshelp_node *fdiro = 0;
+  struct grub_fshelp_node *fdiro = NULL;
   grub_err_t err;
 
   data = erofs_mount (file->device->disk, true);
-- 
2.44.0


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to