[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 0/2] fs/erofs: Add support for EROFS
From: |
Yifan Zhao |
Subject: |
[PATCH v2 0/2] fs/erofs: Add support for EROFS |
Date: |
Thu, 20 Jul 2023 21:36:54 +0800 |
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