/src/util-linux/libblkid/src/superblocks/ocfs.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 1999, 2001 by Andries Brouwer |
3 | | * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o |
4 | | * Copyright (C) 2008 Karel Zak <kzak@redhat.com> |
5 | | * |
6 | | * This file may be redistributed under the terms of the |
7 | | * GNU Lesser General Public License. |
8 | | */ |
9 | | #include <stdio.h> |
10 | | #include <stdlib.h> |
11 | | #include <unistd.h> |
12 | | #include <string.h> |
13 | | #include <stdint.h> |
14 | | |
15 | | #include "superblocks.h" |
16 | | |
17 | | struct ocfs_volume_header { |
18 | | unsigned char minor_version[4]; |
19 | | unsigned char major_version[4]; |
20 | | unsigned char signature[128]; |
21 | | char mount[128]; |
22 | | unsigned char mount_len[2]; |
23 | | } __attribute__((packed)); |
24 | | |
25 | | struct ocfs_volume_label { |
26 | | unsigned char disk_lock[48]; |
27 | | char label[64]; |
28 | | unsigned char label_len[2]; |
29 | | unsigned char vol_id[16]; |
30 | | unsigned char vol_id_len[2]; |
31 | | } __attribute__((packed)); |
32 | | |
33 | 62 | #define ocfsmajor(o) ( (uint32_t) o.major_version[0] \ |
34 | 62 | + (((uint32_t) o.major_version[1]) << 8) \ |
35 | 62 | + (((uint32_t) o.major_version[2]) << 16) \ |
36 | 62 | + (((uint32_t) o.major_version[3]) << 24)) |
37 | | |
38 | 62 | #define ocfsminor(o) ( (uint32_t) o.minor_version[0] \ |
39 | 62 | + (((uint32_t) o.minor_version[1]) << 8) \ |
40 | 62 | + (((uint32_t) o.minor_version[2]) << 16) \ |
41 | 62 | + (((uint32_t) o.minor_version[3]) << 24)) |
42 | | |
43 | 79 | #define ocfslabellen(o) ((uint32_t)o.label_len[0] + (((uint32_t) o.label_len[1]) << 8)) |
44 | 90 | #define ocfsmountlen(o) ((uint32_t)o.mount_len[0] + (((uint32_t) o.mount_len[1]) << 8)) |
45 | | |
46 | | struct ocfs2_super_block { |
47 | | uint8_t i_signature[8]; |
48 | | uint32_t i_generation; |
49 | | int16_t i_suballoc_slot; |
50 | | uint16_t i_suballoc_bit; |
51 | | uint32_t i_reserved0; |
52 | | uint32_t i_clusters; |
53 | | uint32_t i_uid; |
54 | | uint32_t i_gid; |
55 | | uint64_t i_size; |
56 | | uint16_t i_mode; |
57 | | uint16_t i_links_count; |
58 | | uint32_t i_flags; |
59 | | uint64_t i_atime; |
60 | | uint64_t i_ctime; |
61 | | uint64_t i_mtime; |
62 | | uint64_t i_dtime; |
63 | | uint64_t i_blkno; |
64 | | uint64_t i_last_eb_blk; |
65 | | uint32_t i_fs_generation; |
66 | | uint32_t i_atime_nsec; |
67 | | uint32_t i_ctime_nsec; |
68 | | uint32_t i_mtime_nsec; |
69 | | uint64_t i_reserved1[9]; |
70 | | uint64_t i_pad1; |
71 | | uint16_t s_major_rev_level; |
72 | | uint16_t s_minor_rev_level; |
73 | | uint16_t s_mnt_count; |
74 | | int16_t s_max_mnt_count; |
75 | | uint16_t s_state; |
76 | | uint16_t s_errors; |
77 | | uint32_t s_checkinterval; |
78 | | uint64_t s_lastcheck; |
79 | | uint32_t s_creator_os; |
80 | | uint32_t s_feature_compat; |
81 | | uint32_t s_feature_incompat; |
82 | | uint32_t s_feature_ro_compat; |
83 | | uint64_t s_root_blkno; |
84 | | uint64_t s_system_dir_blkno; |
85 | | uint32_t s_blocksize_bits; |
86 | | uint32_t s_clustersize_bits; |
87 | | uint16_t s_max_slots; |
88 | | uint16_t s_reserved1; |
89 | | uint32_t s_reserved2; |
90 | | uint64_t s_first_cluster_group; |
91 | | uint8_t s_label[64]; |
92 | | uint8_t s_uuid[16]; |
93 | | } __attribute__((packed)); |
94 | | |
95 | | struct oracle_asm_disk_label { |
96 | | char dummy[32]; |
97 | | char dl_tag[8]; |
98 | | char dl_id[24]; |
99 | | } __attribute__((packed)); |
100 | | |
101 | | static int probe_ocfs(blkid_probe pr, const struct blkid_idmag *mag) |
102 | 62 | { |
103 | 62 | const unsigned char *buf; |
104 | 62 | struct ocfs_volume_header ovh; |
105 | 62 | struct ocfs_volume_label ovl; |
106 | 62 | uint32_t maj, min; |
107 | | |
108 | | /* header */ |
109 | 62 | buf = blkid_probe_get_buffer(pr, mag->kboff << 10, |
110 | 62 | sizeof(struct ocfs_volume_header)); |
111 | 62 | if (!buf) |
112 | 0 | return errno ? -errno : 1; |
113 | 62 | memcpy(&ovh, buf, sizeof(ovh)); |
114 | | |
115 | | /* label */ |
116 | 62 | buf = blkid_probe_get_buffer(pr, (mag->kboff << 10) + 512, |
117 | 62 | sizeof(struct ocfs_volume_label)); |
118 | 62 | if (!buf) |
119 | 0 | return errno ? -errno : 1; |
120 | 62 | memcpy(&ovl, buf, sizeof(ovl)); |
121 | | |
122 | 62 | maj = ocfsmajor(ovh); |
123 | 62 | min = ocfsminor(ovh); |
124 | | |
125 | 62 | if (maj == 1) |
126 | 0 | blkid_probe_set_value(pr, "SEC_TYPE", |
127 | 0 | (unsigned char *) "ocfs1", sizeof("ocfs1")); |
128 | 62 | else if (maj >= 9) |
129 | 62 | blkid_probe_set_value(pr, "SEC_TYPE", |
130 | 62 | (unsigned char *) "ntocfs", sizeof("ntocfs")); |
131 | | |
132 | 62 | if (ocfslabellen(ovl) < sizeof(ovl.label)) |
133 | 17 | blkid_probe_set_label(pr, (unsigned char *) ovl.label, |
134 | 17 | ocfslabellen(ovl)); |
135 | 62 | if (ocfsmountlen(ovh) < sizeof(ovh.mount)) |
136 | 28 | blkid_probe_set_value(pr, "MOUNT", (unsigned char *) ovh.mount, |
137 | 28 | ocfsmountlen(ovh)); |
138 | 62 | blkid_probe_set_uuid(pr, ovl.vol_id); |
139 | 62 | blkid_probe_sprintf_version(pr, "%u.%u", maj, min); |
140 | 62 | return 0; |
141 | 62 | } |
142 | | |
143 | | static int probe_ocfs2(blkid_probe pr, const struct blkid_idmag *mag) |
144 | 187 | { |
145 | 187 | const struct ocfs2_super_block *osb; |
146 | | |
147 | 187 | osb = blkid_probe_get_sb(pr, mag, struct ocfs2_super_block); |
148 | 187 | if (!osb) |
149 | 0 | return errno ? -errno : 1; |
150 | | |
151 | 187 | blkid_probe_set_label(pr, (unsigned char *) osb->s_label, sizeof(osb->s_label)); |
152 | 187 | blkid_probe_set_uuid(pr, osb->s_uuid); |
153 | | |
154 | 187 | blkid_probe_sprintf_version(pr, "%u.%u", |
155 | 187 | le16_to_cpu(osb->s_major_rev_level), |
156 | 187 | le16_to_cpu(osb->s_minor_rev_level)); |
157 | | |
158 | 187 | if (le32_to_cpu(osb->s_blocksize_bits) < 32){ |
159 | 68 | blkid_probe_set_fsblocksize(pr, 1U << le32_to_cpu(osb->s_blocksize_bits)); |
160 | 68 | blkid_probe_set_block_size(pr, 1U << le32_to_cpu(osb->s_blocksize_bits)); |
161 | 68 | } |
162 | | |
163 | 187 | return 0; |
164 | 187 | } |
165 | | |
166 | | static int probe_oracleasm(blkid_probe pr, const struct blkid_idmag *mag) |
167 | 157 | { |
168 | 157 | const struct oracle_asm_disk_label *dl; |
169 | | |
170 | 157 | dl = blkid_probe_get_sb(pr, mag, struct oracle_asm_disk_label); |
171 | 157 | if (!dl) |
172 | 0 | return errno ? -errno : 1; |
173 | | |
174 | 157 | blkid_probe_set_label(pr, (unsigned char *) dl->dl_id, sizeof(dl->dl_id)); |
175 | 157 | return 0; |
176 | 157 | } |
177 | | |
178 | | |
179 | | const struct blkid_idinfo ocfs_idinfo = |
180 | | { |
181 | | .name = "ocfs", |
182 | | .usage = BLKID_USAGE_FILESYSTEM, |
183 | | .probefunc = probe_ocfs, |
184 | | .minsz = 14000 * 1024, |
185 | | .magics = |
186 | | { |
187 | | { .magic = "OracleCFS", .len = 9, .kboff = 8 }, |
188 | | { NULL } |
189 | | } |
190 | | }; |
191 | | |
192 | | const struct blkid_idinfo ocfs2_idinfo = |
193 | | { |
194 | | .name = "ocfs2", |
195 | | .usage = BLKID_USAGE_FILESYSTEM, |
196 | | .probefunc = probe_ocfs2, |
197 | | .minsz = 14000 * 1024, |
198 | | .magics = |
199 | | { |
200 | | { .magic = "OCFSV2", .len = 6, .kboff = 1 }, |
201 | | { .magic = "OCFSV2", .len = 6, .kboff = 2 }, |
202 | | { .magic = "OCFSV2", .len = 6, .kboff = 4 }, |
203 | | { .magic = "OCFSV2", .len = 6, .kboff = 8 }, |
204 | | { NULL } |
205 | | } |
206 | | }; |
207 | | |
208 | | /* Oracle ASM (Automatic Storage Management) */ |
209 | | const struct blkid_idinfo oracleasm_idinfo = |
210 | | { |
211 | | .name = "oracleasm", |
212 | | .usage = BLKID_USAGE_FILESYSTEM, |
213 | | .probefunc = probe_oracleasm, |
214 | | .magics = |
215 | | { |
216 | | { .magic = "ORCLDISK", .len = 8, .sboff = 32 }, |
217 | | { NULL } |
218 | | } |
219 | | }; |
220 | | |