fs/erofs: Introduce new features including ztailpacking, fragments and dedupe
This patch updates erofs driver code to catch up with the latest code of
erofs_utils (commit e4939f9eaa177e05d697ace85d8dc283e25dc2ed).
LZMA will be supported in the separate patch later.
Signed-off-by: Yifan Zhao <zhaoyifan@sjtu.edu.cn>
Reviewed-by: Huang Jianan <jnhuang95@gmail.com>
diff --git a/fs/erofs/super.c b/fs/erofs/super.c
index 8277d9b..d339262 100644
--- a/fs/erofs/super.c
+++ b/fs/erofs/super.c
@@ -9,7 +9,7 @@
sbi->feature_incompat = feature;
/* check if current kernel meets all mandatory requirements */
- if (feature & (~EROFS_ALL_FEATURE_INCOMPAT)) {
+ if (feature & ~EROFS_ALL_FEATURE_INCOMPAT) {
erofs_err("unidentified incompatible feature %x, please upgrade kernel version",
feature & ~EROFS_ALL_FEATURE_INCOMPAT);
return false;
@@ -40,14 +40,18 @@
sbi->device_id_mask = roundup_pow_of_two(ondisk_extradevs + 1) - 1;
sbi->devs = calloc(ondisk_extradevs, sizeof(*sbi->devs));
+ if (!sbi->devs)
+ return -ENOMEM;
pos = le16_to_cpu(dsb->devt_slotoff) * EROFS_DEVT_SLOT_SIZE;
for (i = 0; i < ondisk_extradevs; ++i) {
struct erofs_deviceslot dis;
int ret;
ret = erofs_dev_read(0, &dis, pos, sizeof(dis));
- if (ret < 0)
+ if (ret < 0) {
+ free(sbi->devs);
return ret;
+ }
sbi->devs[i].mapped_blkaddr = dis.mapped_blkaddr;
sbi->total_blocks += dis.blocks;
@@ -58,42 +62,41 @@
int erofs_read_superblock(void)
{
- char data[EROFS_BLKSIZ];
+ u8 data[EROFS_MAX_BLOCK_SIZE];
struct erofs_super_block *dsb;
- unsigned int blkszbits;
int ret;
- ret = erofs_blk_read(data, 0, 1);
+ ret = erofs_blk_read(data, 0, erofs_blknr(sizeof(data)));
if (ret < 0) {
- erofs_dbg("cannot read erofs superblock: %d", ret);
+ erofs_err("cannot read erofs superblock: %d", ret);
return -EIO;
}
dsb = (struct erofs_super_block *)(data + EROFS_SUPER_OFFSET);
ret = -EINVAL;
if (le32_to_cpu(dsb->magic) != EROFS_SUPER_MAGIC_V1) {
- erofs_dbg("cannot find valid erofs superblock");
+ erofs_err("cannot find valid erofs superblock");
return ret;
}
sbi.feature_compat = le32_to_cpu(dsb->feature_compat);
- blkszbits = dsb->blkszbits;
- /* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */
- if (blkszbits != LOG_BLOCK_SIZE) {
- erofs_err("blksize %u isn't supported on this platform",
- 1 << blkszbits);
+ sbi.blkszbits = dsb->blkszbits;
+ if (sbi.blkszbits < 9 ||
+ sbi.blkszbits > ilog2(EROFS_MAX_BLOCK_SIZE)) {
+ erofs_err("blksize %llu isn't supported on this platform",
+ erofs_blksiz() | 0ULL);
return ret;
- }
-
- if (!check_layout_compatibility(&sbi, dsb))
+ } else if (!check_layout_compatibility(&sbi, dsb)) {
return ret;
+ }
sbi.primarydevice_blocks = le32_to_cpu(dsb->blocks);
sbi.meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
sbi.xattr_blkaddr = le32_to_cpu(dsb->xattr_blkaddr);
sbi.islotbits = EROFS_ISLOTBITS;
sbi.root_nid = le16_to_cpu(dsb->root_nid);
+ sbi.packed_nid = le64_to_cpu(dsb->packed_nid);
sbi.inos = le64_to_cpu(dsb->inos);
sbi.checksum = le32_to_cpu(dsb->checksum);