• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * erofs-utils/lib/super.c
4  *
5  * Created by Li Guifu <blucerlee@gmail.com>
6  */
7 #include <string.h>
8 #include <stdlib.h>
9 #include <asm-generic/errno-base.h>
10 
11 #include "erofs/io.h"
12 #include "erofs/print.h"
13 
check_layout_compatibility(struct erofs_sb_info * sbi,struct erofs_super_block * dsb)14 static bool check_layout_compatibility(struct erofs_sb_info *sbi,
15 				       struct erofs_super_block *dsb)
16 {
17 	const unsigned int feature = le32_to_cpu(dsb->feature_incompat);
18 
19 	sbi->feature_incompat = feature;
20 
21 	/* check if current kernel meets all mandatory requirements */
22 	if (feature & (~EROFS_ALL_FEATURE_INCOMPAT)) {
23 		erofs_err("unidentified incompatible feature %x, please upgrade kernel version",
24 			  feature & ~EROFS_ALL_FEATURE_INCOMPAT);
25 		return false;
26 	}
27 	return true;
28 }
29 
erofs_read_superblock(void)30 int erofs_read_superblock(void)
31 {
32 	char data[EROFS_BLKSIZ];
33 	struct erofs_super_block *dsb;
34 	unsigned int blkszbits;
35 	int ret;
36 
37 	ret = blk_read(data, 0, 1);
38 	if (ret < 0) {
39 		erofs_err("cannot read erofs superblock: %d", ret);
40 		return -EIO;
41 	}
42 	dsb = (struct erofs_super_block *)(data + EROFS_SUPER_OFFSET);
43 
44 	ret = -EINVAL;
45 	if (le32_to_cpu(dsb->magic) != EROFS_SUPER_MAGIC_V1) {
46 		erofs_err("cannot find valid erofs superblock");
47 		return ret;
48 	}
49 
50 	sbi.feature_compat = le32_to_cpu(dsb->feature_compat);
51 
52 	blkszbits = dsb->blkszbits;
53 	/* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */
54 	if (blkszbits != LOG_BLOCK_SIZE) {
55 		erofs_err("blksize %u isn't supported on this platform",
56 			  1 << blkszbits);
57 		return ret;
58 	}
59 
60 	if (!check_layout_compatibility(&sbi, dsb))
61 		return ret;
62 
63 	sbi.blocks = le32_to_cpu(dsb->blocks);
64 	sbi.meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
65 	sbi.xattr_blkaddr = le32_to_cpu(dsb->xattr_blkaddr);
66 	sbi.islotbits = EROFS_ISLOTBITS;
67 	sbi.root_nid = le16_to_cpu(dsb->root_nid);
68 	sbi.inos = le64_to_cpu(dsb->inos);
69 
70 	sbi.build_time = le64_to_cpu(dsb->build_time);
71 	sbi.build_time_nsec = le32_to_cpu(dsb->build_time_nsec);
72 
73 	memcpy(&sbi.uuid, dsb->uuid, sizeof(dsb->uuid));
74 	return 0;
75 }
76 
77