2 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
4 * Inspired by libvolume_id by
5 * Kay Sievers <kay.sievers@vrfy.org>
7 * This file may be redistributed under the terms of the
8 * GNU Lesser General Public License.
18 struct mdp0_super_block {
20 uint32_t major_version;
21 uint32_t minor_version;
22 uint32_t patch_version;
23 uint32_t gvalid_words;
31 uint32_t not_persistent;
37 struct mdp1_super_block {
39 uint32_t major_version;
46 #define MD_RESERVED_BYTES 0x10000
47 #define MD_SB_MAGIC 0xa92b4efc
49 static int probe_raid0(blkid_probe pr, off_t off)
51 struct mdp0_super_block *mdp0;
57 if (pr->size < 0x10000)
59 mdp0 = (struct mdp0_super_block *)
60 blkid_probe_get_buffer(pr,
62 sizeof(struct mdp0_super_block));
66 memset(uuid.ints, 0, sizeof(uuid.ints));
68 if (le32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) {
69 uuid.ints[0] = swab32(mdp0->set_uuid0);
70 if (le32_to_cpu(mdp0->minor_version >= 90)) {
71 uuid.ints[1] = swab32(mdp0->set_uuid1);
72 uuid.ints[2] = swab32(mdp0->set_uuid2);
73 uuid.ints[3] = swab32(mdp0->set_uuid3);
75 if (blkid_probe_sprintf_version(pr, "%u.%u.%u",
76 le32_to_cpu(mdp0->major_version),
77 le32_to_cpu(mdp0->minor_version),
78 le32_to_cpu(mdp0->patch_version)) != 0)
81 } else if (be32_to_cpu(mdp0->md_magic) == MD_SB_MAGIC) {
82 uuid.ints[0] = mdp0->set_uuid0;
83 if (be32_to_cpu(mdp0->minor_version >= 90)) {
84 uuid.ints[1] = mdp0->set_uuid1;
85 uuid.ints[2] = mdp0->set_uuid2;
86 uuid.ints[3] = mdp0->set_uuid3;
88 if (blkid_probe_sprintf_version(pr, "%u.%u.%u",
89 be32_to_cpu(mdp0->major_version),
90 be32_to_cpu(mdp0->minor_version),
91 be32_to_cpu(mdp0->patch_version)) != 0)
96 if (blkid_probe_set_uuid(pr, (unsigned char *) uuid.bytes) != 0)
102 static int probe_raid1(blkid_probe pr, off_t off)
104 struct mdp1_super_block *mdp1;
106 mdp1 = (struct mdp1_super_block *)
107 blkid_probe_get_buffer(pr,
109 sizeof(struct mdp1_super_block));
112 if (le32_to_cpu(mdp1->magic) != MD_SB_MAGIC)
114 if (le32_to_cpu(mdp1->major_version) != 1)
116 if (blkid_probe_set_uuid(pr, (unsigned char *) mdp1->set_uuid) != 0)
118 if (blkid_probe_set_label(pr, mdp1->set_name,
119 sizeof(mdp1->set_name)) != 0)
125 int probe_raid(blkid_probe pr, const struct blkid_idmag *mag)
127 const char *ver = NULL;
129 if (pr->size > MD_RESERVED_BYTES) {
130 /* version 0 at the end of the device */
131 uint64_t sboff = (pr->size & ~(MD_RESERVED_BYTES - 1))
133 if (probe_raid0(pr, sboff) == 0)
136 /* version 1.0 at the end of the device */
137 sboff = (pr->size & ~(0x1000 - 1)) - 0x2000;
138 if (probe_raid1(pr, sboff) == 0)
143 /* version 1.1 at the start of the device */
144 if (probe_raid1(pr, 0) == 0)
147 /* version 1.2 at 4k offset from the start */
148 else if (probe_raid1(pr, 0x1000) == 0)
153 blkid_probe_set_version(pr, ver);
160 const struct blkid_idinfo linuxraid_idinfo = {
161 .name = "linux_raid_member",
162 .usage = BLKID_USAGE_RAID,
163 .probefunc = probe_raid,
164 .magics = BLKID_NONE_MAGIC