]> git.ipfire.org Git - thirdparty/u-boot.git/blobdiff - fs/erofs/super.c
fs/erofs: Introduce new features including ztailpacking, fragments and dedupe
[thirdparty/u-boot.git] / fs / erofs / super.c
index 8277d9b53fb355ebd59232f58d8567e086c5ed36..d33926281b47cee026eaef45711aca4612e4722a 100644 (file)
@@ -9,7 +9,7 @@ static bool check_layout_compatibility(struct erofs_sb_info *sbi,
        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 @@ static int erofs_init_devices(struct erofs_sb_info *sbi,
 
        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 @@ static int erofs_init_devices(struct erofs_sb_info *sbi,
 
 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);