chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
ab7430c
)
volume_id: better DDF raid detection
author
Kay Sievers
<kay.sievers@vrfy.org>
Fri, 3 Oct 2008 13:01:39 +0000
(15:01 +0200)
committer
Kay Sievers
<kay.sievers@vrfy.org>
Fri, 3 Oct 2008 13:01:39 +0000
(15:01 +0200)
extras/volume_id/lib/ddf_raid.c
patch
|
blob
|
history
diff --git
a/extras/volume_id/lib/ddf_raid.c
b/extras/volume_id/lib/ddf_raid.c
index bf24fe016857ac3cbec738b2575cd08ca8566aaa..53d309b8c0f63d76a679a8aaa05181d9489a8a41 100644
(file)
--- a/
extras/volume_id/lib/ddf_raid.c
+++ b/
extras/volume_id/lib/ddf_raid.c
@@
-34,12
+34,11
@@
/* http://www.snia.org/standards/home */
/* http://www.snia.org/standards/home */
-#define DDF_HEADER 0xDE11DE11
#define DDF_GUID_LENGTH 24
#define DDF_REV_LENGTH 8
struct ddf_header {
#define DDF_GUID_LENGTH 24
#define DDF_REV_LENGTH 8
struct ddf_header {
- uint
32_t signature
;
+ uint
8_t signature[4]
;
uint32_t crc;
uint8_t guid[DDF_GUID_LENGTH];
uint8_t ddf_rev[DDF_REV_LENGTH];
uint32_t crc;
uint8_t guid[DDF_GUID_LENGTH];
uint8_t ddf_rev[DDF_REV_LENGTH];
@@
-47,23
+46,47
@@
struct ddf_header {
int volume_id_probe_ddf_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
int volume_id_probe_ddf_raid(struct volume_id *id, uint64_t off, uint64_t size)
{
- uint64_t ddf_off
= ((size / 0x200)-1) * 0x200
;
+ uint64_t ddf_off;
const uint8_t *buf;
struct ddf_header *ddf;
info("probing at offset 0x%llx, size 0x%llx\n",
const uint8_t *buf;
struct ddf_header *ddf;
info("probing at offset 0x%llx, size 0x%llx\n",
-
(unsigned long long) off, (unsigned long long)
size);
- if (size < 0x
1
0000)
+
(unsigned long long)off, (unsigned long long)
size);
+ if (size < 0x
3
0000)
return -1;
return -1;
+ /* header at last sector */
+ ddf_off = ((size / 0x200)-1) * 0x200;
buf = volume_id_get_buffer(id, off + ddf_off, 0x200);
if (buf == NULL)
return -1;
ddf = (struct ddf_header *) buf;
buf = volume_id_get_buffer(id, off + ddf_off, 0x200);
if (buf == NULL)
return -1;
ddf = (struct ddf_header *) buf;
+ if (memcmp(ddf->signature, "\x11\xde\x11\xde", 4) == 0) {
+ info("header (little endian) found at %llu\n", (unsigned long long)(off + ddf_off));
+ goto found;
+ }
+ if (memcmp(ddf->signature, "\xde\x11\xde\x11", 4) == 0) {
+ info("header (big endian) found at %llu\n", (unsigned long long)(off + ddf_off));
+ goto found;
+ }
- if (ddf->signature != cpu_to_be32(DDF_HEADER))
+ /* adaptec non-standard header location */
+ ddf_off = ((size / 0x200)-257) * 0x200;
+ buf = volume_id_get_buffer(id, off + ddf_off, 0x200);
+ if (buf == NULL)
return -1;
return -1;
+ ddf = (struct ddf_header *) buf;
+ if (memcmp(ddf->signature, "\x11\xde\x11\xde", 4) == 0) {
+ info("header adaptec (little endian) found at %llu\n", (unsigned long long)(off + ddf_off));
+ goto found;
+ }
+ if (memcmp(ddf->signature, "\xde\x11\xde\x11", 4) == 0) {
+ info("header adaptec (big endian) found at %llu\n", (unsigned long long)(off + ddf_off));
+ goto found;
+ }
+ return -1;
+found:
volume_id_set_uuid(id, ddf->guid, DDF_GUID_LENGTH, UUID_STRING);
snprintf(id->type_version, DDF_REV_LENGTH, "%s", ddf->ddf_rev);
volume_id_set_usage(id, VOLUME_ID_RAID);
volume_id_set_uuid(id, ddf->guid, DDF_GUID_LENGTH, UUID_STRING);
snprintf(id->type_version, DDF_REV_LENGTH, "%s", ddf->ddf_rev);
volume_id_set_usage(id, VOLUME_ID_RAID);