.. | .. |
---|
18 | 18 | * Check partition table on IDE disks for common CHS translations |
---|
19 | 19 | * |
---|
20 | 20 | * Re-organised Feb 1998 Russell King |
---|
| 21 | + * |
---|
| 22 | + * BSD disklabel support by Yossi Gottlieb <yogo@math.tau.ac.il> |
---|
| 23 | + * updated by Marc Espie <Marc.Espie@openbsd.org> |
---|
| 24 | + * |
---|
| 25 | + * Unixware slices support by Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl> |
---|
| 26 | + * and Krzysztof G. Baranowski <kgb@knm.org.pl> |
---|
21 | 27 | */ |
---|
22 | 28 | #include <linux/msdos_fs.h> |
---|
| 29 | +#include <linux/msdos_partition.h> |
---|
23 | 30 | |
---|
24 | 31 | #include "check.h" |
---|
25 | | -#include "msdos.h" |
---|
26 | 32 | #include "efi.h" |
---|
27 | | -#include "aix.h" |
---|
28 | 33 | |
---|
29 | 34 | /* |
---|
30 | 35 | * Many architectures don't like unaligned accesses, while |
---|
.. | .. |
---|
33 | 38 | */ |
---|
34 | 39 | #include <asm/unaligned.h> |
---|
35 | 40 | |
---|
36 | | -#define SYS_IND(p) get_unaligned(&p->sys_ind) |
---|
37 | | - |
---|
38 | | -static inline sector_t nr_sects(struct partition *p) |
---|
| 41 | +static inline sector_t nr_sects(struct msdos_partition *p) |
---|
39 | 42 | { |
---|
40 | 43 | return (sector_t)get_unaligned_le32(&p->nr_sects); |
---|
41 | 44 | } |
---|
42 | 45 | |
---|
43 | | -static inline sector_t start_sect(struct partition *p) |
---|
| 46 | +static inline sector_t start_sect(struct msdos_partition *p) |
---|
44 | 47 | { |
---|
45 | 48 | return (sector_t)get_unaligned_le32(&p->start_sect); |
---|
46 | 49 | } |
---|
47 | 50 | |
---|
48 | | -static inline int is_extended_partition(struct partition *p) |
---|
| 51 | +static inline int is_extended_partition(struct msdos_partition *p) |
---|
49 | 52 | { |
---|
50 | | - return (SYS_IND(p) == DOS_EXTENDED_PARTITION || |
---|
51 | | - SYS_IND(p) == WIN98_EXTENDED_PARTITION || |
---|
52 | | - SYS_IND(p) == LINUX_EXTENDED_PARTITION); |
---|
| 53 | + return (p->sys_ind == DOS_EXTENDED_PARTITION || |
---|
| 54 | + p->sys_ind == WIN98_EXTENDED_PARTITION || |
---|
| 55 | + p->sys_ind == LINUX_EXTENDED_PARTITION); |
---|
53 | 56 | } |
---|
54 | 57 | |
---|
55 | 58 | #define MSDOS_LABEL_MAGIC1 0x55 |
---|
.. | .. |
---|
68 | 71 | #define AIX_LABEL_MAGIC4 0xC1 |
---|
69 | 72 | static int aix_magic_present(struct parsed_partitions *state, unsigned char *p) |
---|
70 | 73 | { |
---|
71 | | - struct partition *pt = (struct partition *) (p + 0x1be); |
---|
| 74 | + struct msdos_partition *pt = (struct msdos_partition *) (p + 0x1be); |
---|
72 | 75 | Sector sect; |
---|
73 | 76 | unsigned char *d; |
---|
74 | 77 | int slot, ret = 0; |
---|
.. | .. |
---|
78 | 81 | p[2] == AIX_LABEL_MAGIC3 && |
---|
79 | 82 | p[3] == AIX_LABEL_MAGIC4)) |
---|
80 | 83 | return 0; |
---|
81 | | - /* Assume the partition table is valid if Linux partitions exists */ |
---|
| 84 | + |
---|
| 85 | + /* |
---|
| 86 | + * Assume the partition table is valid if Linux partitions exists. |
---|
| 87 | + * Note that old Solaris/x86 partitions use the same indicator as |
---|
| 88 | + * Linux swap partitions, so we consider that a Linux partition as |
---|
| 89 | + * well. |
---|
| 90 | + */ |
---|
82 | 91 | for (slot = 1; slot <= 4; slot++, pt++) { |
---|
83 | | - if (pt->sys_ind == LINUX_SWAP_PARTITION || |
---|
84 | | - pt->sys_ind == LINUX_RAID_PARTITION || |
---|
85 | | - pt->sys_ind == LINUX_DATA_PARTITION || |
---|
86 | | - pt->sys_ind == LINUX_LVM_PARTITION || |
---|
87 | | - is_extended_partition(pt)) |
---|
| 92 | + if (pt->sys_ind == SOLARIS_X86_PARTITION || |
---|
| 93 | + pt->sys_ind == LINUX_RAID_PARTITION || |
---|
| 94 | + pt->sys_ind == LINUX_DATA_PARTITION || |
---|
| 95 | + pt->sys_ind == LINUX_LVM_PARTITION || |
---|
| 96 | + is_extended_partition(pt)) |
---|
88 | 97 | return 0; |
---|
89 | 98 | } |
---|
90 | 99 | d = read_part_sector(state, 7, §); |
---|
.. | .. |
---|
122 | 131 | sector_t first_sector, sector_t first_size, |
---|
123 | 132 | u32 disksig) |
---|
124 | 133 | { |
---|
125 | | - struct partition *p; |
---|
| 134 | + struct msdos_partition *p; |
---|
126 | 135 | Sector sect; |
---|
127 | 136 | unsigned char *data; |
---|
128 | 137 | sector_t this_sector, this_size; |
---|
.. | .. |
---|
146 | 155 | if (!msdos_magic_present(data + 510)) |
---|
147 | 156 | goto done; |
---|
148 | 157 | |
---|
149 | | - p = (struct partition *) (data + 0x1be); |
---|
| 158 | + p = (struct msdos_partition *) (data + 0x1be); |
---|
150 | 159 | |
---|
151 | 160 | /* |
---|
152 | 161 | * Usually, the first entry is the real data partition, |
---|
.. | .. |
---|
182 | 191 | |
---|
183 | 192 | put_partition(state, state->next, next, size); |
---|
184 | 193 | set_info(state, state->next, disksig); |
---|
185 | | - if (SYS_IND(p) == LINUX_RAID_PARTITION) |
---|
| 194 | + if (p->sys_ind == LINUX_RAID_PARTITION) |
---|
186 | 195 | state->parts[state->next].flags = ADDPART_FLAG_RAID; |
---|
187 | 196 | loopct = 0; |
---|
188 | 197 | if (++state->next == state->limit) |
---|
.. | .. |
---|
209 | 218 | done: |
---|
210 | 219 | put_dev_sector(sect); |
---|
211 | 220 | } |
---|
| 221 | + |
---|
| 222 | +#define SOLARIS_X86_NUMSLICE 16 |
---|
| 223 | +#define SOLARIS_X86_VTOC_SANE (0x600DDEEEUL) |
---|
| 224 | + |
---|
| 225 | +struct solaris_x86_slice { |
---|
| 226 | + __le16 s_tag; /* ID tag of partition */ |
---|
| 227 | + __le16 s_flag; /* permission flags */ |
---|
| 228 | + __le32 s_start; /* start sector no of partition */ |
---|
| 229 | + __le32 s_size; /* # of blocks in partition */ |
---|
| 230 | +}; |
---|
| 231 | + |
---|
| 232 | +struct solaris_x86_vtoc { |
---|
| 233 | + unsigned int v_bootinfo[3]; /* info needed by mboot */ |
---|
| 234 | + __le32 v_sanity; /* to verify vtoc sanity */ |
---|
| 235 | + __le32 v_version; /* layout version */ |
---|
| 236 | + char v_volume[8]; /* volume name */ |
---|
| 237 | + __le16 v_sectorsz; /* sector size in bytes */ |
---|
| 238 | + __le16 v_nparts; /* number of partitions */ |
---|
| 239 | + unsigned int v_reserved[10]; /* free space */ |
---|
| 240 | + struct solaris_x86_slice |
---|
| 241 | + v_slice[SOLARIS_X86_NUMSLICE]; /* slice headers */ |
---|
| 242 | + unsigned int timestamp[SOLARIS_X86_NUMSLICE]; /* timestamp */ |
---|
| 243 | + char v_asciilabel[128]; /* for compatibility */ |
---|
| 244 | +}; |
---|
212 | 245 | |
---|
213 | 246 | /* james@bpgc.com: Solaris has a nasty indicator: 0x82 which also |
---|
214 | 247 | indicates linux swap. Be careful before believing this is Solaris. */ |
---|
.. | .. |
---|
264 | 297 | strlcat(state->pp_buf, " >\n", PAGE_SIZE); |
---|
265 | 298 | #endif |
---|
266 | 299 | } |
---|
| 300 | + |
---|
| 301 | +/* check against BSD src/sys/sys/disklabel.h for consistency */ |
---|
| 302 | +#define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ |
---|
| 303 | +#define BSD_MAXPARTITIONS 16 |
---|
| 304 | +#define OPENBSD_MAXPARTITIONS 16 |
---|
| 305 | +#define BSD_FS_UNUSED 0 /* disklabel unused partition entry ID */ |
---|
| 306 | +struct bsd_disklabel { |
---|
| 307 | + __le32 d_magic; /* the magic number */ |
---|
| 308 | + __s16 d_type; /* drive type */ |
---|
| 309 | + __s16 d_subtype; /* controller/d_type specific */ |
---|
| 310 | + char d_typename[16]; /* type name, e.g. "eagle" */ |
---|
| 311 | + char d_packname[16]; /* pack identifier */ |
---|
| 312 | + __u32 d_secsize; /* # of bytes per sector */ |
---|
| 313 | + __u32 d_nsectors; /* # of data sectors per track */ |
---|
| 314 | + __u32 d_ntracks; /* # of tracks per cylinder */ |
---|
| 315 | + __u32 d_ncylinders; /* # of data cylinders per unit */ |
---|
| 316 | + __u32 d_secpercyl; /* # of data sectors per cylinder */ |
---|
| 317 | + __u32 d_secperunit; /* # of data sectors per unit */ |
---|
| 318 | + __u16 d_sparespertrack; /* # of spare sectors per track */ |
---|
| 319 | + __u16 d_sparespercyl; /* # of spare sectors per cylinder */ |
---|
| 320 | + __u32 d_acylinders; /* # of alt. cylinders per unit */ |
---|
| 321 | + __u16 d_rpm; /* rotational speed */ |
---|
| 322 | + __u16 d_interleave; /* hardware sector interleave */ |
---|
| 323 | + __u16 d_trackskew; /* sector 0 skew, per track */ |
---|
| 324 | + __u16 d_cylskew; /* sector 0 skew, per cylinder */ |
---|
| 325 | + __u32 d_headswitch; /* head switch time, usec */ |
---|
| 326 | + __u32 d_trkseek; /* track-to-track seek, usec */ |
---|
| 327 | + __u32 d_flags; /* generic flags */ |
---|
| 328 | +#define NDDATA 5 |
---|
| 329 | + __u32 d_drivedata[NDDATA]; /* drive-type specific information */ |
---|
| 330 | +#define NSPARE 5 |
---|
| 331 | + __u32 d_spare[NSPARE]; /* reserved for future use */ |
---|
| 332 | + __le32 d_magic2; /* the magic number (again) */ |
---|
| 333 | + __le16 d_checksum; /* xor of data incl. partitions */ |
---|
| 334 | + |
---|
| 335 | + /* filesystem and partition information: */ |
---|
| 336 | + __le16 d_npartitions; /* number of partitions in following */ |
---|
| 337 | + __le32 d_bbsize; /* size of boot area at sn0, bytes */ |
---|
| 338 | + __le32 d_sbsize; /* max size of fs superblock, bytes */ |
---|
| 339 | + struct bsd_partition { /* the partition table */ |
---|
| 340 | + __le32 p_size; /* number of sectors in partition */ |
---|
| 341 | + __le32 p_offset; /* starting sector */ |
---|
| 342 | + __le32 p_fsize; /* filesystem basic fragment size */ |
---|
| 343 | + __u8 p_fstype; /* filesystem type, see below */ |
---|
| 344 | + __u8 p_frag; /* filesystem fragments per block */ |
---|
| 345 | + __le16 p_cpg; /* filesystem cylinders per group */ |
---|
| 346 | + } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */ |
---|
| 347 | +}; |
---|
267 | 348 | |
---|
268 | 349 | #if defined(CONFIG_BSD_DISKLABEL) |
---|
269 | 350 | /* |
---|
.. | .. |
---|
349 | 430 | #endif |
---|
350 | 431 | } |
---|
351 | 432 | |
---|
| 433 | +#define UNIXWARE_DISKMAGIC (0xCA5E600DUL) /* The disk magic number */ |
---|
| 434 | +#define UNIXWARE_DISKMAGIC2 (0x600DDEEEUL) /* The slice table magic nr */ |
---|
| 435 | +#define UNIXWARE_NUMSLICE 16 |
---|
| 436 | +#define UNIXWARE_FS_UNUSED 0 /* Unused slice entry ID */ |
---|
| 437 | + |
---|
| 438 | +struct unixware_slice { |
---|
| 439 | + __le16 s_label; /* label */ |
---|
| 440 | + __le16 s_flags; /* permission flags */ |
---|
| 441 | + __le32 start_sect; /* starting sector */ |
---|
| 442 | + __le32 nr_sects; /* number of sectors in slice */ |
---|
| 443 | +}; |
---|
| 444 | + |
---|
| 445 | +struct unixware_disklabel { |
---|
| 446 | + __le32 d_type; /* drive type */ |
---|
| 447 | + __le32 d_magic; /* the magic number */ |
---|
| 448 | + __le32 d_version; /* version number */ |
---|
| 449 | + char d_serial[12]; /* serial number of the device */ |
---|
| 450 | + __le32 d_ncylinders; /* # of data cylinders per device */ |
---|
| 451 | + __le32 d_ntracks; /* # of tracks per cylinder */ |
---|
| 452 | + __le32 d_nsectors; /* # of data sectors per track */ |
---|
| 453 | + __le32 d_secsize; /* # of bytes per sector */ |
---|
| 454 | + __le32 d_part_start; /* # of first sector of this partition*/ |
---|
| 455 | + __le32 d_unknown1[12]; /* ? */ |
---|
| 456 | + __le32 d_alt_tbl; /* byte offset of alternate table */ |
---|
| 457 | + __le32 d_alt_len; /* byte length of alternate table */ |
---|
| 458 | + __le32 d_phys_cyl; /* # of physical cylinders per device */ |
---|
| 459 | + __le32 d_phys_trk; /* # of physical tracks per cylinder */ |
---|
| 460 | + __le32 d_phys_sec; /* # of physical sectors per track */ |
---|
| 461 | + __le32 d_phys_bytes; /* # of physical bytes per sector */ |
---|
| 462 | + __le32 d_unknown2; /* ? */ |
---|
| 463 | + __le32 d_unknown3; /* ? */ |
---|
| 464 | + __le32 d_pad[8]; /* pad */ |
---|
| 465 | + |
---|
| 466 | + struct unixware_vtoc { |
---|
| 467 | + __le32 v_magic; /* the magic number */ |
---|
| 468 | + __le32 v_version; /* version number */ |
---|
| 469 | + char v_name[8]; /* volume name */ |
---|
| 470 | + __le16 v_nslices; /* # of slices */ |
---|
| 471 | + __le16 v_unknown1; /* ? */ |
---|
| 472 | + __le32 v_reserved[10]; /* reserved */ |
---|
| 473 | + struct unixware_slice |
---|
| 474 | + v_slice[UNIXWARE_NUMSLICE]; /* slice headers */ |
---|
| 475 | + } vtoc; |
---|
| 476 | +}; /* 408 */ |
---|
| 477 | + |
---|
352 | 478 | /* |
---|
353 | 479 | * Create devices for Unixware partitions listed in a disklabel, under a |
---|
354 | 480 | * dos-like partition. See parse_extended() for more information. |
---|
.. | .. |
---|
392 | 518 | #endif |
---|
393 | 519 | } |
---|
394 | 520 | |
---|
| 521 | +#define MINIX_NR_SUBPARTITIONS 4 |
---|
| 522 | + |
---|
395 | 523 | /* |
---|
396 | 524 | * Minix 2.0.0/2.0.2 subpartition support. |
---|
397 | 525 | * Anand Krishnamurthy <anandk@wiproge.med.ge.com> |
---|
.. | .. |
---|
403 | 531 | #ifdef CONFIG_MINIX_SUBPARTITION |
---|
404 | 532 | Sector sect; |
---|
405 | 533 | unsigned char *data; |
---|
406 | | - struct partition *p; |
---|
| 534 | + struct msdos_partition *p; |
---|
407 | 535 | int i; |
---|
408 | 536 | |
---|
409 | 537 | data = read_part_sector(state, offset, §); |
---|
410 | 538 | if (!data) |
---|
411 | 539 | return; |
---|
412 | 540 | |
---|
413 | | - p = (struct partition *)(data + 0x1be); |
---|
| 541 | + p = (struct msdos_partition *)(data + 0x1be); |
---|
414 | 542 | |
---|
415 | 543 | /* The first sector of a Minix partition can have either |
---|
416 | 544 | * a secondary MBR describing its subpartitions, or |
---|
417 | 545 | * the normal boot sector. */ |
---|
418 | 546 | if (msdos_magic_present(data + 510) && |
---|
419 | | - SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */ |
---|
| 547 | + p->sys_ind == MINIX_PARTITION) { /* subpartition table present */ |
---|
420 | 548 | char tmp[1 + BDEVNAME_SIZE + 10 + 9 + 1]; |
---|
421 | 549 | |
---|
422 | 550 | snprintf(tmp, sizeof(tmp), " %s%d: <minix:", state->name, origin); |
---|
.. | .. |
---|
425 | 553 | if (state->next == state->limit) |
---|
426 | 554 | break; |
---|
427 | 555 | /* add each partition in use */ |
---|
428 | | - if (SYS_IND(p) == MINIX_PARTITION) |
---|
| 556 | + if (p->sys_ind == MINIX_PARTITION) |
---|
429 | 557 | put_partition(state, state->next++, |
---|
430 | 558 | start_sect(p), nr_sects(p)); |
---|
431 | 559 | } |
---|
.. | .. |
---|
454 | 582 | sector_t sector_size = bdev_logical_block_size(state->bdev) / 512; |
---|
455 | 583 | Sector sect; |
---|
456 | 584 | unsigned char *data; |
---|
457 | | - struct partition *p; |
---|
| 585 | + struct msdos_partition *p; |
---|
458 | 586 | struct fat_boot_sector *fb; |
---|
459 | 587 | int slot; |
---|
460 | 588 | u32 disksig; |
---|
.. | .. |
---|
488 | 616 | * partition table. Reject this in case the boot indicator |
---|
489 | 617 | * is not 0 or 0x80. |
---|
490 | 618 | */ |
---|
491 | | - p = (struct partition *) (data + 0x1be); |
---|
| 619 | + p = (struct msdos_partition *) (data + 0x1be); |
---|
492 | 620 | for (slot = 1; slot <= 4; slot++, p++) { |
---|
493 | 621 | if (p->boot_ind != 0 && p->boot_ind != 0x80) { |
---|
494 | 622 | /* |
---|
.. | .. |
---|
510 | 638 | } |
---|
511 | 639 | |
---|
512 | 640 | #ifdef CONFIG_EFI_PARTITION |
---|
513 | | - p = (struct partition *) (data + 0x1be); |
---|
| 641 | + p = (struct msdos_partition *) (data + 0x1be); |
---|
514 | 642 | for (slot = 1 ; slot <= 4 ; slot++, p++) { |
---|
515 | 643 | /* If this is an EFI GPT disk, msdos should ignore it. */ |
---|
516 | | - if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) { |
---|
| 644 | + if (p->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT) { |
---|
517 | 645 | put_dev_sector(sect); |
---|
518 | 646 | return 0; |
---|
519 | 647 | } |
---|
520 | 648 | } |
---|
521 | 649 | #endif |
---|
522 | | - p = (struct partition *) (data + 0x1be); |
---|
| 650 | + p = (struct msdos_partition *) (data + 0x1be); |
---|
523 | 651 | |
---|
524 | 652 | disksig = le32_to_cpup((__le32 *)(data + 0x1b8)); |
---|
525 | 653 | |
---|
.. | .. |
---|
555 | 683 | } |
---|
556 | 684 | put_partition(state, slot, start, size); |
---|
557 | 685 | set_info(state, slot, disksig); |
---|
558 | | - if (SYS_IND(p) == LINUX_RAID_PARTITION) |
---|
| 686 | + if (p->sys_ind == LINUX_RAID_PARTITION) |
---|
559 | 687 | state->parts[slot].flags = ADDPART_FLAG_RAID; |
---|
560 | | - if (SYS_IND(p) == DM6_PARTITION) |
---|
| 688 | + if (p->sys_ind == DM6_PARTITION) |
---|
561 | 689 | strlcat(state->pp_buf, "[DM]", PAGE_SIZE); |
---|
562 | | - if (SYS_IND(p) == EZD_PARTITION) |
---|
| 690 | + if (p->sys_ind == EZD_PARTITION) |
---|
563 | 691 | strlcat(state->pp_buf, "[EZD]", PAGE_SIZE); |
---|
564 | 692 | } |
---|
565 | 693 | |
---|
566 | 694 | strlcat(state->pp_buf, "\n", PAGE_SIZE); |
---|
567 | 695 | |
---|
568 | 696 | /* second pass - output for each on a separate line */ |
---|
569 | | - p = (struct partition *) (0x1be + data); |
---|
| 697 | + p = (struct msdos_partition *) (0x1be + data); |
---|
570 | 698 | for (slot = 1 ; slot <= 4 ; slot++, p++) { |
---|
571 | | - unsigned char id = SYS_IND(p); |
---|
| 699 | + unsigned char id = p->sys_ind; |
---|
572 | 700 | int n; |
---|
573 | 701 | |
---|
574 | 702 | if (!nr_sects(p)) |
---|