/src/util-linux/libblkid/src/superblocks/jmicron_raid.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2008 Karel Zak <kzak@redhat.com> |
3 | | * |
4 | | * Inspired by libvolume_id by |
5 | | * Kay Sievers <kay.sievers@vrfy.org> |
6 | | * |
7 | | * This file may be redistributed under the terms of the |
8 | | * GNU Lesser General Public License. |
9 | | */ |
10 | | |
11 | | #include <stdio.h> |
12 | | #include <stdlib.h> |
13 | | #include <unistd.h> |
14 | | #include <string.h> |
15 | | #include <stdint.h> |
16 | | |
17 | | #include "superblocks.h" |
18 | | |
19 | 11.4k | #define JM_SIGNATURE "JM" |
20 | 0 | #define JM_MINOR_VERSION(_x) (le16_to_cpu((_x)->version) & 0xFF) |
21 | 0 | #define JM_MAJOR_VERSION(_x) (le16_to_cpu((_x)->version) >> 8) |
22 | | #define JM_SPARES 2 |
23 | | #define JM_MEMBERS 8 |
24 | | |
25 | | struct jm_metadata { |
26 | | int8_t signature[2]; /* 0x0 - 0x01 */ |
27 | | |
28 | | uint16_t version; /* 0x03 - 0x04 JMicron version */ |
29 | | |
30 | | uint16_t checksum; /* 0x04 - 0x05 */ |
31 | | uint8_t filler[10]; |
32 | | |
33 | | uint32_t identity; /* 0x10 - 0x13 */ |
34 | | |
35 | | struct { |
36 | | uint32_t base; /* 0x14 - 0x17 */ |
37 | | uint32_t range; /* 0x18 - 0x1B range */ |
38 | | uint16_t range2; /* 0x1C - 0x1D range2 */ |
39 | | } segment; |
40 | | |
41 | | int8_t name[16]; /* 0x20 - 0x2F */ |
42 | | |
43 | | uint8_t mode; /* 0x30 RAID level */ |
44 | | uint8_t block; /* 0x31 stride size (2=4K, 3=8K, ...) */ |
45 | | uint16_t attribute; /* 0x32 - 0x33 */ |
46 | | uint8_t filler1[4]; |
47 | | |
48 | | uint32_t spare[JM_SPARES]; /* 0x38 - 0x3F */ |
49 | | uint32_t member[JM_MEMBERS]; /* 0x40 - 0x5F */ |
50 | | |
51 | | uint8_t filler2[0x20]; |
52 | | } __attribute__ ((packed)); |
53 | | |
54 | | static int jm_checksum(blkid_probe pr, const struct jm_metadata *jm) |
55 | 0 | { |
56 | 0 | size_t count = sizeof(*jm) / sizeof(uint16_t); |
57 | 0 | uint16_t sum = 0; |
58 | 0 | unsigned char *ptr = (unsigned char *) jm; |
59 | |
|
60 | 0 | while (count--) { |
61 | 0 | uint16_t val; |
62 | |
|
63 | 0 | memcpy(&val, ptr, sizeof(uint16_t)); |
64 | 0 | sum += le16_to_cpu(val); |
65 | |
|
66 | 0 | ptr += sizeof(uint16_t); |
67 | 0 | } |
68 | |
|
69 | 0 | return blkid_probe_verify_csum(pr, sum == 0 || sum == 1, 1); |
70 | 0 | } |
71 | | |
72 | | static int probe_jmraid(blkid_probe pr, |
73 | | const struct blkid_idmag *mag __attribute__((__unused__))) |
74 | 5.73k | { |
75 | 5.73k | uint64_t off; |
76 | 5.73k | const struct jm_metadata *jm; |
77 | | |
78 | 5.73k | if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) |
79 | 0 | return 1; |
80 | | |
81 | 5.73k | off = ((pr->size / 0x200) - 1) * 0x200; |
82 | 5.73k | jm = (struct jm_metadata *) |
83 | 5.73k | blkid_probe_get_buffer(pr, |
84 | 5.73k | off, |
85 | 5.73k | sizeof(struct jm_metadata)); |
86 | 5.73k | if (!jm) |
87 | 0 | return errno ? -errno : 1; |
88 | | |
89 | 5.73k | if (memcmp(jm->signature, JM_SIGNATURE, sizeof(JM_SIGNATURE) - 1) != 0) |
90 | 5.73k | return 1; |
91 | | |
92 | 0 | if (!jm_checksum(pr, jm)) |
93 | 0 | return 1; |
94 | | |
95 | 0 | if (jm->mode > 5) |
96 | 0 | return 1; |
97 | | |
98 | 0 | if (blkid_probe_sprintf_version(pr, "%u.%u", |
99 | 0 | JM_MAJOR_VERSION(jm), JM_MINOR_VERSION(jm)) != 0) |
100 | 0 | return 1; |
101 | 0 | if (blkid_probe_set_magic(pr, off, sizeof(jm->signature), |
102 | 0 | (unsigned char *) jm->signature)) |
103 | 0 | return 1; |
104 | 0 | return 0; |
105 | 0 | } |
106 | | |
107 | | const struct blkid_idinfo jmraid_idinfo = { |
108 | | .name = "jmicron_raid_member", |
109 | | .usage = BLKID_USAGE_RAID, |
110 | | .minsz = 0x10000, |
111 | | .probefunc = probe_jmraid, |
112 | | .magics = BLKID_NONE_MAGIC |
113 | | }; |