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