26 #include <linux/slab.h>
29 #include <linux/kernel.h>
42 #ifndef CONFIG_LDM_DEBUG
43 #define ldm_debug(...) do {} while (0)
45 #define ldm_debug(f, a...) _ldm_printk (KERN_DEBUG, __func__, f, ##a)
48 #define ldm_crit(f, a...) _ldm_printk (KERN_CRIT, __func__, f, ##a)
49 #define ldm_error(f, a...) _ldm_printk (KERN_ERR, __func__, f, ##a)
50 #define ldm_info(f, a...) _ldm_printk (KERN_INFO, __func__, f, ##a)
63 printk(
"%s%s(): %pV\n", level,
function, &vaf);
77 static int ldm_parse_hexbyte (
const u8 *
src)
105 static bool ldm_parse_guid (
const u8 *src,
u8 *
dest)
107 static const int size[] = { 4, 2, 2, 2, 6 };
110 if (src[8] !=
'-' || src[13] !=
'-' ||
111 src[18] !=
'-' || src[23] !=
'-')
114 for (j = 0; j < 5; j++, src++)
115 for (i = 0; i < size[
j]; i++, src+=2, *dest++ =
v)
116 if ((v = ldm_parse_hexbyte (src)) < 0)
135 bool is_vista =
false;
139 ldm_error(
"Cannot find PRIVHEAD structure. LDM database is"
140 " corrupt. Aborting.");
143 ph->
ver_major = get_unaligned_be16(data + 0x000C);
144 ph->
ver_minor = get_unaligned_be16(data + 0x000E);
153 ldm_error(
"Expected PRIVHEAD version 2.11 or 2.12, got %d.%d."
158 ph->
ver_minor, is_vista ?
"Vista" :
"2000/XP");
161 ldm_info(
"Database is normally %u bytes, it claims to "
167 ldm_error(
"PRIVHEAD disk size doesn't match real disk size");
170 if (!ldm_parse_guid(data + 0x0030, ph->
disk_id)) {
171 ldm_error(
"PRIVHEAD contains an invalid GUID.");
174 ldm_debug(
"Parsed PRIVHEAD successfully.");
192 static bool ldm_parse_tocblock (
const u8 *data,
struct tocblock *toc)
197 ldm_crit (
"Cannot find TOCBLOCK, database may be corrupt.");
207 ldm_crit (
"TOCBLOCK's first bitmap is '%s', should be '%s'.",
217 ldm_crit (
"TOCBLOCK's second bitmap is '%s', should be '%s'.",
221 ldm_debug (
"Parsed TOCBLOCK successfully.");
238 static bool ldm_parse_vmdb (
const u8 *data,
struct vmdb *
vm)
243 ldm_crit (
"Cannot find the VMDB, database may be corrupt.");
247 vm->
ver_major = get_unaligned_be16(data + 0x12);
248 vm->
ver_minor = get_unaligned_be16(data + 0x14);
250 ldm_error (
"Expected VMDB version %d.%d, got %d.%d. "
278 static bool ldm_compare_privheads (
const struct privhead *ph1,
302 static bool ldm_compare_tocblocks (
const struct tocblock *toc1,
346 if (!ph[1] || !ph[2]) {
355 for (i = 0; i < 3; i++) {
356 data = read_part_sector(state, ph[0]->
config_start + off[i],
362 result = ldm_parse_privhead (data, ph[i]);
363 put_dev_sector (sect);
365 ldm_error (
"Cannot find PRIVHEAD %d.", i+1);
373 num_sects = state->
bdev->bd_inode->i_size >> 9;
377 ldm_crit (
"Database extends beyond the end of the disk.");
384 ldm_crit (
"Disk and database overlap.");
388 if (!ldm_compare_privheads (ph[0], ph[1])) {
389 ldm_crit (
"Primary and backup PRIVHEADs don't match.");
397 ldm_debug (
"Validated PRIVHEADs successfully.");
420 unsigned long base,
struct ldmdb *ldb)
438 tb[2] = (
struct tocblock*)((
u8*)tb[1] +
sizeof(*tb[1]));
439 tb[3] = (
struct tocblock*)((
u8*)tb[2] +
sizeof(*tb[2]));
446 for (nr_tbs = i = 0; i < 4; i++) {
447 data = read_part_sector(state, base + off[i], §);
449 ldm_error(
"Disk read failed for TOCBLOCK %d.", i);
452 if (ldm_parse_tocblock(data, tb[nr_tbs]))
454 put_dev_sector(sect);
457 ldm_crit(
"Failed to find a valid TOCBLOCK.");
464 ldm_crit(
"The bitmaps are out of range. Giving up.");
468 for (i = 1; i < nr_tbs; i++) {
469 if (!ldm_compare_tocblocks(tb[0], tb[i])) {
470 ldm_crit(
"TOCBLOCKs 0 and %d do not match.", i);
474 ldm_debug(
"Validated %d TOCBLOCKs successfully.", nr_tbs);
494 unsigned long base,
struct ldmdb *ldb)
507 data = read_part_sector(state, base +
OFF_VMDB, §);
513 if (!ldm_parse_vmdb (data, vm))
517 if (get_unaligned_be16(data + 0x10) != 0x01) {
518 ldm_crit (
"Database is not in a consistent state. Aborting.");
530 ldm_crit (
"VMDB exceeds allowed size specified by TOCBLOCK. "
531 "Database is corrupt. Aborting.");
537 put_dev_sector (sect);
568 data = read_part_sector(state, 0, §);
578 for (i = 0; i < 4; i++, p++)
585 ldm_debug (
"Found W2K dynamic disk partition type.");
588 put_dev_sector (sect);
604 static struct vblk * ldm_get_disk_objid (
const struct ldmdb *ldb)
637 const struct ldmdb *ldb)
647 disk = ldm_get_disk_objid (ldb);
649 ldm_crit (
"Can't find the ID of this disk in the database.");
663 put_partition (pp, part_num, ldb->
ph.logical_disk_start +
697 ldm_error(
"base (%d) > buflen (%d)", base, buflen);
700 if (base + buffer[base] >= buflen) {
701 ldm_error(
"base (%d) + buffer[base] (%d) >= buflen (%d)", base,
702 buffer[base], buflen);
705 return buffer[base] + offset + 1;
732 if (length && length <= 8)
734 tmp = (tmp << 8) | *block++;
736 ldm_error (
"Illegal length %d.", length);
758 static int ldm_get_vstr (
const u8 *block,
u8 *buffer,
int buflen)
762 BUG_ON (!block || !buffer);
765 if (length >= buflen) {
766 ldm_error (
"Truncating string %d -> %d.", length, buflen);
769 memcpy (buffer, block + 1, length);
786 static bool ldm_parse_cmp3 (
const u8 *buffer,
int buflen,
struct vblk *vb)
788 int r_objid, r_name, r_vstate, r_child, r_parent, r_stripe, r_cols,
len;
793 r_objid = ldm_relative (buffer, buflen, 0x18, 0);
794 r_name = ldm_relative (buffer, buflen, 0x18, r_objid);
795 r_vstate = ldm_relative (buffer, buflen, 0x18, r_name);
796 r_child = ldm_relative (buffer, buflen, 0x1D, r_vstate);
797 r_parent = ldm_relative (buffer, buflen, 0x2D, r_child);
800 r_stripe = ldm_relative (buffer, buflen, 0x2E, r_parent);
801 r_cols = ldm_relative (buffer, buflen, 0x2E, r_stripe);
816 ldm_get_vstr (buffer + 0x18 + r_name, comp->
state,
818 comp->
type = buffer[0x18 + r_vstate];
819 comp->
children = ldm_get_vnum (buffer + 0x1D + r_vstate);
820 comp->
parent_id = ldm_get_vnum (buffer + 0x2D + r_child);
821 comp->
chunksize = r_stripe ? ldm_get_vnum (buffer+r_parent+0x2E) : 0;
837 static int ldm_parse_dgr3 (
const u8 *buffer,
int buflen,
struct vblk *vb)
839 int r_objid, r_name, r_diskid, r_id1, r_id2, len;
844 r_objid = ldm_relative (buffer, buflen, 0x18, 0);
845 r_name = ldm_relative (buffer, buflen, 0x18, r_objid);
846 r_diskid = ldm_relative (buffer, buflen, 0x18, r_name);
849 r_id1 = ldm_relative (buffer, buflen, 0x24, r_diskid);
850 r_id2 = ldm_relative (buffer, buflen, 0x24, r_id1);
865 ldm_get_vstr (buffer + 0x18 + r_name, dgrp->
disk_id,
881 static bool ldm_parse_dgr4 (
const u8 *buffer,
int buflen,
struct vblk *vb)
884 int r_objid, r_name, r_id1, r_id2, len;
889 r_objid = ldm_relative (buffer, buflen, 0x18, 0);
890 r_name = ldm_relative (buffer, buflen, 0x18, r_objid);
893 r_id1 = ldm_relative (buffer, buflen, 0x44, r_name);
894 r_id2 = ldm_relative (buffer, buflen, 0x44, r_id1);
910 ldm_get_vstr (buffer + 0x18 + r_objid, buf,
sizeof (buf));
925 static bool ldm_parse_dsk3 (
const u8 *buffer,
int buflen,
struct vblk *vb)
927 int r_objid, r_name, r_diskid, r_altname, len;
932 r_objid = ldm_relative (buffer, buflen, 0x18, 0);
933 r_name = ldm_relative (buffer, buflen, 0x18, r_objid);
934 r_diskid = ldm_relative (buffer, buflen, 0x18, r_name);
935 r_altname = ldm_relative (buffer, buflen, 0x18, r_diskid);
945 ldm_get_vstr (buffer + 0x18 + r_diskid, disk->
alt_name,
947 if (!ldm_parse_guid (buffer + 0x19 + r_name, disk->
disk_id))
964 static bool ldm_parse_dsk4 (
const u8 *buffer,
int buflen,
struct vblk *vb)
966 int r_objid, r_name, len;
971 r_objid = ldm_relative (buffer, buflen, 0x18, 0);
972 r_name = ldm_relative (buffer, buflen, 0x18, r_objid);
997 static bool ldm_parse_prt3(
const u8 *buffer,
int buflen,
struct vblk *vb)
999 int r_objid, r_name, r_size, r_parent, r_diskid, r_index, len;
1003 r_objid = ldm_relative(buffer, buflen, 0x18, 0);
1008 r_name = ldm_relative(buffer, buflen, 0x18, r_objid);
1013 r_size = ldm_relative(buffer, buflen, 0x34, r_name);
1018 r_parent = ldm_relative(buffer, buflen, 0x34, r_size);
1023 r_diskid = ldm_relative(buffer, buflen, 0x34, r_parent);
1029 r_index = ldm_relative(buffer, buflen, 0x34, r_diskid);
1045 ldm_error(
"len %d > BE32(buffer + 0x14) %d", len,
1052 part->
size = ldm_get_vnum(buffer + 0x34 + r_name);
1053 part->
parent_id = ldm_get_vnum(buffer + 0x34 + r_size);
1054 part->
disk_id = ldm_get_vnum(buffer + 0x34 + r_parent);
1055 if (vb->
flags & VBLK_FLAG_PART_INDEX)
1056 part->
partnum = buffer[0x35 + r_diskid];
1073 static bool ldm_parse_vol5(
const u8 *buffer,
int buflen,
struct vblk *vb)
1075 int r_objid, r_name, r_vtype, r_disable_drive_letter, r_child, r_size;
1076 int r_id1, r_id2, r_size2, r_drive, len;
1080 r_objid = ldm_relative(buffer, buflen, 0x18, 0);
1085 r_name = ldm_relative(buffer, buflen, 0x18, r_objid);
1090 r_vtype = ldm_relative(buffer, buflen, 0x18, r_name);
1095 r_disable_drive_letter = ldm_relative(buffer, buflen, 0x18, r_vtype);
1096 if (r_disable_drive_letter < 0) {
1097 ldm_error(
"r_disable_drive_letter %d < 0",
1098 r_disable_drive_letter);
1101 r_child = ldm_relative(buffer, buflen, 0x2D, r_disable_drive_letter);
1106 r_size = ldm_relative(buffer, buflen, 0x3D, r_child);
1112 r_id1 = ldm_relative(buffer, buflen, 0x52, r_size);
1120 r_id2 = ldm_relative(buffer, buflen, 0x52, r_id1);
1128 r_size2 = ldm_relative(buffer, buflen, 0x52, r_id2);
1136 r_drive = ldm_relative(buffer, buflen, 0x52, r_size2);
1150 ldm_error(
"len %d > BE32(buffer + 0x14) %d", len,
1155 ldm_get_vstr(buffer + 0x18 + r_name, volu->
volume_type,
1159 volu->
size = ldm_get_vnum(buffer + 0x3D + r_child);
1162 if (buffer[0x12] & VBLK_FLAG_VOLU_DRIVE) {
1163 ldm_get_vstr(buffer + 0x52 + r_size, volu->
drive_hint,
1182 static bool ldm_parse_vblk (
const u8 *buf,
int len,
struct vblk *vb)
1184 bool result =
false;
1189 r_objid = ldm_relative (buf, len, 0x18, 0);
1195 vb->
flags = buf[0x12];
1196 vb->
type = buf[0x13];
1197 vb->
obj_id = ldm_get_vnum (buf + 0x18);
1201 case VBLK_CMP3: result = ldm_parse_cmp3 (buf, len, vb);
break;
1202 case VBLK_DSK3: result = ldm_parse_dsk3 (buf, len, vb);
break;
1203 case VBLK_DSK4: result = ldm_parse_dsk4 (buf, len, vb);
break;
1204 case VBLK_DGR3: result = ldm_parse_dgr3 (buf, len, vb);
break;
1205 case VBLK_DGR4: result = ldm_parse_dgr4 (buf, len, vb);
break;
1206 case VBLK_PRT3: result = ldm_parse_prt3 (buf, len, vb);
break;
1207 case VBLK_VOL5: result = ldm_parse_vol5 (buf, len, vb);
break;
1211 ldm_debug (
"Parsed VBLK 0x%llx (type: 0x%02x) ok.",
1214 ldm_error (
"Failed to parse VBLK 0x%llx (type: 0x%02x).",
1234 static bool ldm_ldmdb_add (
u8 *data,
int len,
struct ldmdb *ldb)
1247 if (!ldm_parse_vblk (data, len, vb)) {
1296 static bool ldm_frag_add (
const u8 *data,
int size,
struct list_head *frags)
1302 BUG_ON (!data || !frags);
1305 ldm_error(
"Value of size is to small.");
1310 rec = get_unaligned_be16(data + 0x0C);
1311 num = get_unaligned_be16(data + 0x0E);
1312 if ((num < 1) || (num > 4)) {
1313 ldm_error (
"A VBLK claims to have %d parts.", num);
1317 ldm_error(
"REC value (%d) exceeds NUM value (%d)", rec, num);
1323 if (f->
group == group)
1336 f->
map = 0xFF << num;
1340 if (rec >= f->
num) {
1341 ldm_error(
"REC value (%d) exceeds NUM value (%d)", rec, f->
num);
1344 if (f->
map & (1 << rec)) {
1345 ldm_error (
"Duplicate VBLK, part %d.", rec);
1349 f->
map |= (1 << rec);
1397 if (f->
map != 0xFF) {
1398 ldm_error (
"VBLK group %d is incomplete (0x%02x).",
1403 if (!ldm_ldmdb_add (f->
data, f->
num*ldb->vm.vblk_size, ldb))
1427 bool result =
false;
1432 size = ldb->
vm.vblk_size;
1433 perbuf = 512 /
size;
1434 skip = ldb->
vm.vblk_offset >> 9;
1435 finish = (size * ldb->
vm.last_vblk_seq) >> 9;
1437 for (s = skip; s < finish; s++) {
1438 data = read_part_sector(state, base +
OFF_VMDB + s, §);
1444 for (v = 0; v < perbuf; v++, data+=
size) {
1450 recs = get_unaligned_be16(data + 0x0E);
1452 if (!ldm_ldmdb_add (data, size, ldb))
1454 }
else if (recs > 1) {
1455 if (!ldm_frag_add (data, size, &frags))
1460 put_dev_sector (sect);
1464 result = ldm_frag_commit (&frags, ldb);
1467 put_dev_sector (sect);
1468 ldm_frag_free (&frags);
1481 static void ldm_free_vblks (
struct list_head *lh)
1518 if (!ldm_validate_partition_table(state))
1528 if (!ldm_validate_privheads(state, &ldb->
ph))
1532 base = ldb->
ph.config_start;
1535 if (!ldm_validate_tocblocks(state, base, ldb) ||
1536 !ldm_validate_vmdb(state, base, ldb))
1540 INIT_LIST_HEAD (&ldb->
v_dgrp);
1541 INIT_LIST_HEAD (&ldb->
v_disk);
1542 INIT_LIST_HEAD (&ldb->
v_volu);
1543 INIT_LIST_HEAD (&ldb->
v_comp);
1544 INIT_LIST_HEAD (&ldb->
v_part);
1546 if (!ldm_get_vblks(state, base, ldb)) {
1547 ldm_crit (
"Failed to read the VBLKs from the database.");
1552 if (ldm_create_data_partitions(state, ldb)) {
1553 ldm_debug (
"Parsed LDM database successfully.");
1559 ldm_free_vblks (&ldb->
v_dgrp);
1560 ldm_free_vblks (&ldb->
v_disk);
1561 ldm_free_vblks (&ldb->
v_volu);
1562 ldm_free_vblks (&ldb->
v_comp);
1563 ldm_free_vblks (&ldb->
v_part);