1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "volume_id_internal.h"
28
29struct mdp_super_block {
30 uint32_t md_magic;
31 uint32_t major_version;
32 uint32_t minor_version;
33 uint32_t patch_version;
34 uint32_t gvalid_words;
35 uint32_t set_uuid0;
36 uint32_t ctime;
37 uint32_t level;
38 uint32_t size;
39 uint32_t nr_disks;
40 uint32_t raid_disks;
41 uint32_t md_minor;
42 uint32_t not_persistent;
43 uint32_t set_uuid1;
44 uint32_t set_uuid2;
45 uint32_t set_uuid3;
46} PACKED;
47
48#define MD_RESERVED_BYTES 0x10000
49#define MD_MAGIC 0xa92b4efc
50
51int FAST_FUNC volume_id_probe_linux_raid(struct volume_id *id , uint64_t size)
52{
53 typedef uint32_t aliased_uint32_t FIX_ALIASING;
54#define off ((uint64_t)0)
55 uint64_t sboff;
56 uint8_t uuid[16];
57 struct mdp_super_block *mdp;
58
59 dbg("probing at offset 0x%llx, size 0x%llx",
60 (unsigned long long) off, (unsigned long long) size);
61
62 if (size < 0x10000)
63 return -1;
64
65 sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES;
66 mdp = volume_id_get_buffer(id, off + sboff, 0x800);
67 if (mdp == NULL)
68 return -1;
69
70 if (mdp->md_magic != cpu_to_le32(MD_MAGIC))
71 return -1;
72
73 *(aliased_uint32_t*)uuid = mdp->set_uuid0;
74 memcpy(&uuid[4], &mdp->set_uuid1, 12);
75 volume_id_set_uuid(id, uuid, UUID_DCE);
76
77
78
79
80
81
82 dbg("found raid signature");
83
84 IF_FEATURE_BLKID_TYPE(id->type = "linux_raid_member";)
85
86 return 0;
87}
88