/src/util-linux/libblkid/src/superblocks/ubifs.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2009 Corentin Chary <corentincj@iksaif.net> |
3 | | * |
4 | | * This file may be redistributed under the terms of the |
5 | | * GNU Lesser General Public License. |
6 | | */ |
7 | | #include <inttypes.h> |
8 | | #include <stdio.h> |
9 | | #include <stdlib.h> |
10 | | #include <unistd.h> |
11 | | #include <string.h> |
12 | | #include <stdint.h> |
13 | | |
14 | | #include "superblocks.h" |
15 | | #include "crc32.h" |
16 | | |
17 | | /* |
18 | | * struct ubifs_ch - common header node. |
19 | | * @magic: UBIFS node magic number (%UBIFS_NODE_MAGIC) |
20 | | * @crc: CRC-32 checksum of the node header |
21 | | * @sqnum: sequence number |
22 | | * @len: full node length |
23 | | * @node_type: node type |
24 | | * @group_type: node group type |
25 | | * @padding: reserved for future, zeroes |
26 | | * |
27 | | * Every UBIFS node starts with this common part. If the node has a key, the |
28 | | * key always goes next. |
29 | | */ |
30 | | struct ubifs_ch { |
31 | | uint32_t magic; |
32 | | uint32_t crc; |
33 | | uint64_t sqnum; |
34 | | uint32_t len; |
35 | | uint8_t node_type; |
36 | | uint8_t group_type; |
37 | | uint8_t padding[2]; |
38 | | } __attribute__ ((packed)); |
39 | | |
40 | | /* |
41 | | * struct ubifs_sb_node - superblock node. |
42 | | * @ch: common header |
43 | | * @padding: reserved for future, zeroes |
44 | | * @key_hash: type of hash function used in keys |
45 | | * @key_fmt: format of the key |
46 | | * @flags: file-system flags (%UBIFS_FLG_BIGLPT, etc) |
47 | | * @min_io_size: minimal input/output unit size |
48 | | * @leb_size: logical eraseblock size in bytes |
49 | | * @leb_cnt: count of LEBs used by file-system |
50 | | * @max_leb_cnt: maximum count of LEBs used by file-system |
51 | | * @max_bud_bytes: maximum amount of data stored in buds |
52 | | * @log_lebs: log size in logical eraseblocks |
53 | | * @lpt_lebs: number of LEBs used for lprops table |
54 | | * @orph_lebs: number of LEBs used for recording orphans |
55 | | * @jhead_cnt: count of journal heads |
56 | | * @fanout: tree fanout (max. number of links per indexing node) |
57 | | * @lsave_cnt: number of LEB numbers in LPT's save table |
58 | | * @fmt_version: UBIFS on-flash format version |
59 | | * @default_compr: default compression algorithm (%UBIFS_COMPR_LZO, etc) |
60 | | * @padding1: reserved for future, zeroes |
61 | | * @rp_uid: reserve pool UID |
62 | | * @rp_gid: reserve pool GID |
63 | | * @rp_size: size of the reserved pool in bytes |
64 | | * @padding2: reserved for future, zeroes |
65 | | * @time_gran: time granularity in nanoseconds |
66 | | * @uuid: UUID generated when the file system image was created |
67 | | * @ro_compat_version: UBIFS R/O compatibility version |
68 | | */ |
69 | | struct ubifs_sb_node { |
70 | | struct ubifs_ch ch; |
71 | | uint8_t padding[2]; |
72 | | uint8_t key_hash; |
73 | | uint8_t key_fmt; |
74 | | uint32_t flags; |
75 | | uint32_t min_io_size; |
76 | | uint32_t leb_size; |
77 | | uint32_t leb_cnt; |
78 | | uint32_t max_leb_cnt; |
79 | | uint64_t max_bud_bytes; |
80 | | uint32_t log_lebs; |
81 | | uint32_t lpt_lebs; |
82 | | uint32_t orph_lebs; |
83 | | uint32_t jhead_cnt; |
84 | | uint32_t fanout; |
85 | | uint32_t lsave_cnt; |
86 | | uint32_t fmt_version; |
87 | | uint16_t default_compr; |
88 | | uint8_t padding1[2]; |
89 | | uint32_t rp_uid; |
90 | | uint32_t rp_gid; |
91 | | uint64_t rp_size; |
92 | | uint32_t time_gran; |
93 | | uint8_t uuid[16]; |
94 | | uint32_t ro_compat_version; |
95 | | uint8_t padding2[3968]; |
96 | | } __attribute__ ((packed)); |
97 | | |
98 | | static int ubifs_verify_csum(blkid_probe pr, const struct ubifs_sb_node *sb) |
99 | 65 | { |
100 | 65 | size_t csummed_offset = offsetof(struct ubifs_ch, sqnum); |
101 | 65 | uint32_t crc = ul_crc32(~0LL, |
102 | 65 | (unsigned char *) sb + csummed_offset, |
103 | 65 | sizeof(*sb) - csummed_offset); |
104 | 65 | return blkid_probe_verify_csum(pr, crc, le32_to_cpu(sb->ch.crc)); |
105 | 65 | } |
106 | | |
107 | | static int probe_ubifs(blkid_probe pr, const struct blkid_idmag *mag) |
108 | 65 | { |
109 | 65 | const struct ubifs_sb_node *sb; |
110 | | |
111 | 65 | sb = blkid_probe_get_sb(pr, mag, struct ubifs_sb_node); |
112 | 65 | if (!sb) |
113 | 0 | return errno ? -errno : 1; |
114 | | |
115 | 65 | if (!ubifs_verify_csum(pr, sb)) |
116 | 64 | return 1; |
117 | | |
118 | 1 | blkid_probe_set_uuid(pr, sb->uuid); |
119 | 1 | blkid_probe_sprintf_version(pr, "w%"PRIu32"r%"PRIu32, |
120 | 1 | le32_to_cpu(sb->fmt_version), |
121 | 1 | le32_to_cpu(sb->ro_compat_version)); |
122 | 1 | blkid_probe_set_fssize(pr, |
123 | 1 | (uint64_t) le32_to_cpu(sb->leb_size) |
124 | | * le32_to_cpu(sb->leb_cnt)); |
125 | 1 | return 0; |
126 | 65 | } |
127 | | |
128 | | const struct blkid_idinfo ubifs_idinfo = |
129 | | { |
130 | | .name = "ubifs", |
131 | | .usage = BLKID_USAGE_FILESYSTEM, |
132 | | .probefunc = probe_ubifs, |
133 | | .magics = |
134 | | { |
135 | | { .magic = "\x31\x18\x10\x06", .len = 4 }, |
136 | | { NULL } |
137 | | } |
138 | | }; |