1 // SPDX-License-Identifier: GPL-2.0+
4 static bool check_layout_compatibility(struct erofs_sb_info
*sbi
,
5 struct erofs_super_block
*dsb
)
7 const unsigned int feature
= le32_to_cpu(dsb
->feature_incompat
);
9 sbi
->feature_incompat
= feature
;
11 /* check if current kernel meets all mandatory requirements */
12 if (feature
& (~EROFS_ALL_FEATURE_INCOMPAT
)) {
13 erofs_err("unidentified incompatible feature %x, please upgrade kernel version",
14 feature
& ~EROFS_ALL_FEATURE_INCOMPAT
);
20 static int erofs_init_devices(struct erofs_sb_info
*sbi
,
21 struct erofs_super_block
*dsb
)
23 unsigned int ondisk_extradevs
, i
;
26 sbi
->total_blocks
= sbi
->primarydevice_blocks
;
28 if (!erofs_sb_has_device_table())
31 ondisk_extradevs
= le16_to_cpu(dsb
->extra_devices
);
33 if (ondisk_extradevs
!= sbi
->extra_devices
) {
34 erofs_err("extra devices don't match (ondisk %u, given %u)",
35 ondisk_extradevs
, sbi
->extra_devices
);
38 if (!ondisk_extradevs
)
41 sbi
->device_id_mask
= roundup_pow_of_two(ondisk_extradevs
+ 1) - 1;
42 sbi
->devs
= calloc(ondisk_extradevs
, sizeof(*sbi
->devs
));
43 pos
= le16_to_cpu(dsb
->devt_slotoff
) * EROFS_DEVT_SLOT_SIZE
;
44 for (i
= 0; i
< ondisk_extradevs
; ++i
) {
45 struct erofs_deviceslot dis
;
48 ret
= erofs_dev_read(0, &dis
, pos
, sizeof(dis
));
52 sbi
->devs
[i
].mapped_blkaddr
= dis
.mapped_blkaddr
;
53 sbi
->total_blocks
+= dis
.blocks
;
54 pos
+= EROFS_DEVT_SLOT_SIZE
;
59 int erofs_read_superblock(void)
61 char data
[EROFS_BLKSIZ
];
62 struct erofs_super_block
*dsb
;
63 unsigned int blkszbits
;
66 ret
= erofs_blk_read(data
, 0, 1);
68 erofs_dbg("cannot read erofs superblock: %d", ret
);
71 dsb
= (struct erofs_super_block
*)(data
+ EROFS_SUPER_OFFSET
);
74 if (le32_to_cpu(dsb
->magic
) != EROFS_SUPER_MAGIC_V1
) {
75 erofs_dbg("cannot find valid erofs superblock");
79 sbi
.feature_compat
= le32_to_cpu(dsb
->feature_compat
);
81 blkszbits
= dsb
->blkszbits
;
82 /* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */
83 if (blkszbits
!= LOG_BLOCK_SIZE
) {
84 erofs_err("blksize %u isn't supported on this platform",
89 if (!check_layout_compatibility(&sbi
, dsb
))
92 sbi
.primarydevice_blocks
= le32_to_cpu(dsb
->blocks
);
93 sbi
.meta_blkaddr
= le32_to_cpu(dsb
->meta_blkaddr
);
94 sbi
.xattr_blkaddr
= le32_to_cpu(dsb
->xattr_blkaddr
);
95 sbi
.islotbits
= EROFS_ISLOTBITS
;
96 sbi
.root_nid
= le16_to_cpu(dsb
->root_nid
);
97 sbi
.inos
= le64_to_cpu(dsb
->inos
);
98 sbi
.checksum
= le32_to_cpu(dsb
->checksum
);
100 sbi
.build_time
= le64_to_cpu(dsb
->build_time
);
101 sbi
.build_time_nsec
= le32_to_cpu(dsb
->build_time_nsec
);
103 memcpy(&sbi
.uuid
, dsb
->uuid
, sizeof(dsb
->uuid
));
104 return erofs_init_devices(&sbi
, dsb
);