| .. | .. |
|---|
| 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)) |
|---|