hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/block/partitions/msdos.c
....@@ -18,13 +18,18 @@
1818 * Check partition table on IDE disks for common CHS translations
1919 *
2020 * 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>
2127 */
2228 #include <linux/msdos_fs.h>
29
+#include <linux/msdos_partition.h>
2330
2431 #include "check.h"
25
-#include "msdos.h"
2632 #include "efi.h"
27
-#include "aix.h"
2833
2934 /*
3035 * Many architectures don't like unaligned accesses, while
....@@ -33,23 +38,21 @@
3338 */
3439 #include <asm/unaligned.h>
3540
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)
3942 {
4043 return (sector_t)get_unaligned_le32(&p->nr_sects);
4144 }
4245
43
-static inline sector_t start_sect(struct partition *p)
46
+static inline sector_t start_sect(struct msdos_partition *p)
4447 {
4548 return (sector_t)get_unaligned_le32(&p->start_sect);
4649 }
4750
48
-static inline int is_extended_partition(struct partition *p)
51
+static inline int is_extended_partition(struct msdos_partition *p)
4952 {
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);
5356 }
5457
5558 #define MSDOS_LABEL_MAGIC1 0x55
....@@ -68,7 +71,7 @@
6871 #define AIX_LABEL_MAGIC4 0xC1
6972 static int aix_magic_present(struct parsed_partitions *state, unsigned char *p)
7073 {
71
- struct partition *pt = (struct partition *) (p + 0x1be);
74
+ struct msdos_partition *pt = (struct msdos_partition *) (p + 0x1be);
7275 Sector sect;
7376 unsigned char *d;
7477 int slot, ret = 0;
....@@ -78,13 +81,19 @@
7881 p[2] == AIX_LABEL_MAGIC3 &&
7982 p[3] == AIX_LABEL_MAGIC4))
8083 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
+ */
8291 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))
8897 return 0;
8998 }
9099 d = read_part_sector(state, 7, &sect);
....@@ -122,7 +131,7 @@
122131 sector_t first_sector, sector_t first_size,
123132 u32 disksig)
124133 {
125
- struct partition *p;
134
+ struct msdos_partition *p;
126135 Sector sect;
127136 unsigned char *data;
128137 sector_t this_sector, this_size;
....@@ -146,7 +155,7 @@
146155 if (!msdos_magic_present(data + 510))
147156 goto done;
148157
149
- p = (struct partition *) (data + 0x1be);
158
+ p = (struct msdos_partition *) (data + 0x1be);
150159
151160 /*
152161 * Usually, the first entry is the real data partition,
....@@ -182,7 +191,7 @@
182191
183192 put_partition(state, state->next, next, size);
184193 set_info(state, state->next, disksig);
185
- if (SYS_IND(p) == LINUX_RAID_PARTITION)
194
+ if (p->sys_ind == LINUX_RAID_PARTITION)
186195 state->parts[state->next].flags = ADDPART_FLAG_RAID;
187196 loopct = 0;
188197 if (++state->next == state->limit)
....@@ -209,6 +218,30 @@
209218 done:
210219 put_dev_sector(sect);
211220 }
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
+};
212245
213246 /* james@bpgc.com: Solaris has a nasty indicator: 0x82 which also
214247 indicates linux swap. Be careful before believing this is Solaris. */
....@@ -264,6 +297,54 @@
264297 strlcat(state->pp_buf, " >\n", PAGE_SIZE);
265298 #endif
266299 }
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
+};
267348
268349 #if defined(CONFIG_BSD_DISKLABEL)
269350 /*
....@@ -349,6 +430,51 @@
349430 #endif
350431 }
351432
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
+
352478 /*
353479 * Create devices for Unixware partitions listed in a disklabel, under a
354480 * dos-like partition. See parse_extended() for more information.
....@@ -392,6 +518,8 @@
392518 #endif
393519 }
394520
521
+#define MINIX_NR_SUBPARTITIONS 4
522
+
395523 /*
396524 * Minix 2.0.0/2.0.2 subpartition support.
397525 * Anand Krishnamurthy <anandk@wiproge.med.ge.com>
....@@ -403,20 +531,20 @@
403531 #ifdef CONFIG_MINIX_SUBPARTITION
404532 Sector sect;
405533 unsigned char *data;
406
- struct partition *p;
534
+ struct msdos_partition *p;
407535 int i;
408536
409537 data = read_part_sector(state, offset, &sect);
410538 if (!data)
411539 return;
412540
413
- p = (struct partition *)(data + 0x1be);
541
+ p = (struct msdos_partition *)(data + 0x1be);
414542
415543 /* The first sector of a Minix partition can have either
416544 * a secondary MBR describing its subpartitions, or
417545 * the normal boot sector. */
418546 if (msdos_magic_present(data + 510) &&
419
- SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */
547
+ p->sys_ind == MINIX_PARTITION) { /* subpartition table present */
420548 char tmp[1 + BDEVNAME_SIZE + 10 + 9 + 1];
421549
422550 snprintf(tmp, sizeof(tmp), " %s%d: <minix:", state->name, origin);
....@@ -425,7 +553,7 @@
425553 if (state->next == state->limit)
426554 break;
427555 /* add each partition in use */
428
- if (SYS_IND(p) == MINIX_PARTITION)
556
+ if (p->sys_ind == MINIX_PARTITION)
429557 put_partition(state, state->next++,
430558 start_sect(p), nr_sects(p));
431559 }
....@@ -454,7 +582,7 @@
454582 sector_t sector_size = bdev_logical_block_size(state->bdev) / 512;
455583 Sector sect;
456584 unsigned char *data;
457
- struct partition *p;
585
+ struct msdos_partition *p;
458586 struct fat_boot_sector *fb;
459587 int slot;
460588 u32 disksig;
....@@ -488,7 +616,7 @@
488616 * partition table. Reject this in case the boot indicator
489617 * is not 0 or 0x80.
490618 */
491
- p = (struct partition *) (data + 0x1be);
619
+ p = (struct msdos_partition *) (data + 0x1be);
492620 for (slot = 1; slot <= 4; slot++, p++) {
493621 if (p->boot_ind != 0 && p->boot_ind != 0x80) {
494622 /*
....@@ -510,16 +638,16 @@
510638 }
511639
512640 #ifdef CONFIG_EFI_PARTITION
513
- p = (struct partition *) (data + 0x1be);
641
+ p = (struct msdos_partition *) (data + 0x1be);
514642 for (slot = 1 ; slot <= 4 ; slot++, p++) {
515643 /* 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) {
517645 put_dev_sector(sect);
518646 return 0;
519647 }
520648 }
521649 #endif
522
- p = (struct partition *) (data + 0x1be);
650
+ p = (struct msdos_partition *) (data + 0x1be);
523651
524652 disksig = le32_to_cpup((__le32 *)(data + 0x1b8));
525653
....@@ -555,20 +683,20 @@
555683 }
556684 put_partition(state, slot, start, size);
557685 set_info(state, slot, disksig);
558
- if (SYS_IND(p) == LINUX_RAID_PARTITION)
686
+ if (p->sys_ind == LINUX_RAID_PARTITION)
559687 state->parts[slot].flags = ADDPART_FLAG_RAID;
560
- if (SYS_IND(p) == DM6_PARTITION)
688
+ if (p->sys_ind == DM6_PARTITION)
561689 strlcat(state->pp_buf, "[DM]", PAGE_SIZE);
562
- if (SYS_IND(p) == EZD_PARTITION)
690
+ if (p->sys_ind == EZD_PARTITION)
563691 strlcat(state->pp_buf, "[EZD]", PAGE_SIZE);
564692 }
565693
566694 strlcat(state->pp_buf, "\n", PAGE_SIZE);
567695
568696 /* second pass - output for each on a separate line */
569
- p = (struct partition *) (0x1be + data);
697
+ p = (struct msdos_partition *) (0x1be + data);
570698 for (slot = 1 ; slot <= 4 ; slot++, p++) {
571
- unsigned char id = SYS_IND(p);
699
+ unsigned char id = p->sys_ind;
572700 int n;
573701
574702 if (!nr_sects(p))