21 #include <linux/msdos_fs.h>
32 #include <asm/unaligned.h>
34 #define SYS_IND(p) get_unaligned(&p->sys_ind)
46 static inline int is_extended_partition(
struct partition *p)
48 return (
SYS_IND(p) == DOS_EXTENDED_PARTITION ||
49 SYS_IND(p) == WIN98_EXTENDED_PARTITION ||
50 SYS_IND(p) == LINUX_EXTENDED_PARTITION);
53 #define MSDOS_LABEL_MAGIC1 0x55
54 #define MSDOS_LABEL_MAGIC2 0xAA
57 msdos_magic_present(
unsigned char *p)
63 #define AIX_LABEL_MAGIC1 0xC9
64 #define AIX_LABEL_MAGIC2 0xC2
65 #define AIX_LABEL_MAGIC3 0xD4
66 #define AIX_LABEL_MAGIC4 0xC1
80 for (slot = 1; slot <= 4; slot++, pt++) {
81 if (pt->sys_ind == LINUX_SWAP_PARTITION ||
82 pt->sys_ind == LINUX_RAID_PARTITION ||
83 pt->sys_ind == LINUX_DATA_PARTITION ||
84 pt->sys_ind == LINUX_LVM_PARTITION ||
85 is_extended_partition(pt))
88 d = read_part_sector(state, 7, §);
90 if (d[0] ==
'_' && d[1] ==
'L' && d[2] ==
'V' && d[3] ==
'M')
120 this_sector = first_sector;
121 this_size = first_size;
128 data = read_part_sector(state, this_sector, §);
132 if (!msdos_magic_present(data + 510))
149 for (i=0; i<4; i++, p++) {
151 if (!nr_sects(p) || is_extended_partition(p))
158 next = this_sector +
offs;
160 if (offs + size > this_size)
162 if (next < first_sector)
164 if (next + size > first_sector + first_size)
168 put_partition(state, state->
next, next, size);
169 if (
SYS_IND(p) == LINUX_RAID_PARTITION)
170 state->
parts[state->
next].flags = ADDPART_FLAG_RAID;
183 for (i=0; i<4; i++, p++)
184 if (nr_sects(p) && is_extended_partition(p))
189 this_sector = first_sector + start_sect(p) *
sector_size;
191 put_dev_sector(sect);
194 put_dev_sector(sect);
203 #ifdef CONFIG_SOLARIS_X86_PARTITION
205 struct solaris_x86_vtoc *
v;
209 v = read_part_sector(state, offset + 1, §);
212 if (
le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) {
213 put_dev_sector(sect);
219 snprintf(tmp,
sizeof(tmp),
" %s%d: <solaris:", state->
name, origin);
225 snprintf(tmp,
sizeof(tmp),
" cannot handle version %d vtoc>\n",
228 put_dev_sector(sect);
232 max_nparts =
le16_to_cpu (v->v_nparts) > 8 ? SOLARIS_X86_NUMSLICE : 8;
233 for (i=0; i<max_nparts && state->
next<state->
limit; i++) {
234 struct solaris_x86_slice *
s = &v->v_slice[
i];
235 char tmp[3 + 10 + 1 + 1];
239 snprintf(tmp,
sizeof(tmp),
" [s%d]", i);
243 put_partition(state, state->
next++,
247 put_dev_sector(sect);
252 #if defined(CONFIG_BSD_DISKLABEL)
262 struct bsd_disklabel *
l;
263 struct bsd_partition *
p;
266 l = read_part_sector(state, offset + 1, §);
270 put_dev_sector(sect);
274 snprintf(tmp,
sizeof(tmp),
" %s%d: <%s:", state->
name, origin, flavour);
277 if (
le16_to_cpu(l->d_npartitions) < max_partitions)
279 for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) {
284 if (p->p_fstype == BSD_FS_UNUSED)
288 if (offset == bsd_start && size == bsd_size)
291 if (offset > bsd_start || offset+size < bsd_start+bsd_size) {
295 put_partition(state, state->
next++, bsd_start, bsd_size);
297 put_dev_sector(sect);
298 if (
le16_to_cpu(l->d_npartitions) > max_partitions) {
299 snprintf(tmp,
sizeof(tmp),
" (ignored %d more)",
310 #ifdef CONFIG_BSD_DISKLABEL
311 parse_bsd(state, offset, size, origin,
"bsd", BSD_MAXPARTITIONS);
318 #ifdef CONFIG_BSD_DISKLABEL
319 parse_bsd(state, offset, size, origin,
"netbsd", BSD_MAXPARTITIONS);
326 #ifdef CONFIG_BSD_DISKLABEL
327 parse_bsd(state, offset, size, origin,
"openbsd",
328 OPENBSD_MAXPARTITIONS);
339 #ifdef CONFIG_UNIXWARE_DISKLABEL
341 struct unixware_disklabel *
l;
342 struct unixware_slice *
p;
344 l = read_part_sector(state, offset + 29, §);
347 if (
le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC ||
348 le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) {
349 put_dev_sector(sect);
355 snprintf(tmp,
sizeof(tmp),
" %s%d: <unixware:", state->
name, origin);
358 p = &l->vtoc.v_slice[1];
360 while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
364 if (p->s_label != UNIXWARE_FS_UNUSED)
365 put_partition(state, state->
next++,
370 put_dev_sector(sect);
383 #ifdef CONFIG_MINIX_SUBPARTITION
389 data = read_part_sector(state, offset, §);
398 if (msdos_magic_present (data + 510) &&
399 SYS_IND(p) == MINIX_PARTITION) {
402 snprintf(tmp,
sizeof(tmp),
" %s%d: <minix:", state->
name, origin);
404 for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) {
408 if (
SYS_IND(p) == MINIX_PARTITION)
409 put_partition(state, state->
next++,
410 start_sect(p), nr_sects(p));
414 put_dev_sector(sect);
422 {FREEBSD_PARTITION, parse_freebsd},
423 {NETBSD_PARTITION, parse_netbsd},
424 {OPENBSD_PARTITION, parse_openbsd},
425 {MINIX_PARTITION, parse_minix},
426 {UNIXWARE_PARTITION, parse_unixware},
427 {SOLARIS_X86_PARTITION, parse_solaris_x86},
428 {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86},
434 sector_t sector_size = bdev_logical_block_size(state->
bdev) / 512;
441 data = read_part_sector(state, 0, §);
444 if (!msdos_magic_present(data + 510)) {
445 put_dev_sector(sect);
449 if (aix_magic_present(state, data)) {
450 put_dev_sector(sect);
462 for (slot = 1; slot <= 4; slot++, p++) {
463 if (p->boot_ind != 0 && p->boot_ind != 0x80) {
471 && fat_valid_media(fb->
media)) {
473 put_dev_sector(sect);
476 put_dev_sector(sect);
482 #ifdef CONFIG_EFI_PARTITION
484 for (slot = 1 ; slot <= 4 ; slot++, p++) {
487 put_dev_sector(sect);
501 for (slot = 1 ; slot <= 4 ; slot++, p++) {
506 if (is_extended_partition(p)) {
514 n =
min(size,
max(sector_size, n));
515 put_partition(state, slot, start, n);
518 parse_extended(state, start, size);
522 put_partition(state, slot, start, size);
523 if (
SYS_IND(p) == LINUX_RAID_PARTITION)
524 state->
parts[
slot].flags = ADDPART_FLAG_RAID;
525 if (
SYS_IND(p) == DM6_PARTITION)
527 if (
SYS_IND(p) == EZD_PARTITION)
535 for (slot = 1 ; slot <= 4 ; slot++, p++) {
542 for (n = 0; subtypes[
n].parse &&
id != subtypes[
n].id; n++)
545 if (!subtypes[n].
parse)
547 subtypes[
n].parse(state, start_sect(p) * sector_size,
548 nr_sects(p) * sector_size, slot);
550 put_dev_sector(sect);