patch-2.2.0-pre1 linux/drivers/block/genhd.c
Next file: linux/drivers/block/ide-cd.c
Previous file: linux/drivers/ap1000/ddv_util.c
Back to the patch index
Back to the overall index
- Lines: 169
- Date:
Sun Dec 27 10:44:45 1998
- Orig file:
v2.1.132/linux/drivers/block/genhd.c
- Orig date:
Thu Nov 19 09:56:28 1998
diff -u --recursive --new-file v2.1.132/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
@@ -317,11 +317,50 @@
#endif
#ifdef CONFIG_BSD_DISKLABEL
+static void check_and_add_bsd_partition(struct gendisk *hd, struct bsd_partition *bsd_p)
+{
+ struct hd_struct *lin_p;
+ /* check relative position of partitions. */
+ for (lin_p = hd->part + 1; lin_p - hd->part < current_minor; lin_p++) {
+ /* no relationship -> try again */
+ if (lin_p->start_sect + lin_p->nr_sects <= bsd_p->p_offset
+ || lin_p->start_sect >= bsd_p->p_offset + bsd_p->p_size)
+ continue;
+ /* equal -> no need to add */
+ if (lin_p->start_sect == bsd_p->p_offset &&
+ lin_p->nr_sects == bsd_p->p_size)
+ return;
+ /* bsd living within dos partition */
+ if (lin_p->start_sect <= bsd_p->p_offset && lin_p->start_sect
+ + lin_p->nr_sects >= bsd_p->p_offset + bsd_p->p_size) {
+#ifdef DEBUG_BSD_DISKLABEL
+ printk("w: %d %ld+%ld,%d+%d",
+ lin_p - hd->part,
+ lin_p->start_sect, lin_p->nr_sects,
+ bsd_p->p_offset, bsd_p->p_size);
+#endif
+ break;
+ }
+ /* ouch: bsd and linux overlap. Don't even try for that partition */
+#ifdef DEBUG_BSD_DISKLABEL
+ printk("???: %d %ld+%ld,%d+%d",
+ lin_p - hd->part, lin_p->start_sect, lin_p->nr_sects,
+ bsd_p->p_offset, bsd_p->p_size);
+#endif
+ printk("???");
+ return;
+ } /* if the bsd partition is not currently known to linux, we end
+ * up here
+ */
+ add_partition(hd, current_minor, bsd_p->p_offset, bsd_p->p_size);
+ current_minor++;
+}
/*
* Create devices for BSD partitions listed in a disklabel, under a
* dos-like partition. See extended_partition() for more information.
*/
-static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev)
+static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev,
+ int max_partitions)
{
struct buffer_head *bh;
struct bsd_disklabel *l;
@@ -337,19 +376,56 @@
return;
}
- p = &l->d_partitions[0];
- while (p - &l->d_partitions[0] <= BSD_MAXPARTITIONS) {
+ if (l->d_npartitions < max_partitions)
+ max_partitions = l->d_npartitions;
+ for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) {
if ((current_minor & mask) >= (4 + hd->max_p))
break;
- if (p->p_fstype != BSD_FS_UNUSED) {
- add_partition(hd, current_minor, p->p_offset, p->p_size);
+ if (p->p_fstype != BSD_FS_UNUSED)
+ check_and_add_bsd_partition(hd, p);
+ }
+ brelse(bh);
+
+}
+#endif
+
+#ifdef CONFIG_UNIXWARE_DISKLABEL
+/*
+ * Create devices for Unixware partitions listed in a disklabel, under a
+ * dos-like partition. See extended_partition() for more information.
+ */
+static void unixware_partition(struct gendisk *hd, kdev_t dev)
+{
+ struct buffer_head *bh;
+ struct unixware_disklabel *l;
+ struct unixware_slice *p;
+ int mask = (1 << hd->minor_shift) - 1;
+
+ if (!(bh = bread(dev, 14, get_ptable_blocksize(dev))))
+ return;
+ bh->b_state = 0;
+ l = (struct unixware_disklabel *) (bh->b_data+512);
+ if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC ||
+ le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) {
+ brelse(bh);
+ return;
+ }
+ printk(" <unixware:");
+ p = &l->vtoc.v_slice[1];
+ /* I omit the 0th slice as it is the same as whole disk. */
+ while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) {
+ if ((current_minor & mask) == 0)
+ break;
+
+ if (p->s_label != UNIXWARE_FS_UNUSED) {
+ add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
current_minor++;
}
p++;
}
brelse(bh);
-
+ printk(" >");
}
#endif
@@ -360,6 +436,11 @@
struct partition *p;
unsigned char *data;
int mask = (1 << hd->minor_shift) - 1;
+#ifdef CONFIG_BSD_DISKLABEL
+ /* no bsd disklabel as a default */
+ kdev_t bsd_kdev = 0;
+ int bsd_maxpart;
+#endif
#ifdef CONFIG_BLK_DEV_IDE
int tested_for_xlate = 0;
@@ -476,12 +557,25 @@
hd->part[minor].nr_sects = 2;
}
#ifdef CONFIG_BSD_DISKLABEL
+ /* tag first disklabel for late recognition */
if (SYS_IND(p) == BSD_PARTITION) {
- printk(" <");
- bsd_disklabel_partition(hd, MKDEV(hd->major, minor));
- printk(" >");
+ printk("!");
+ if (!bsd_kdev) {
+ bsd_kdev = MKDEV(hd->major, minor);
+ bsd_maxpart = BSD_MAXPARTITIONS;
+ }
+ } else if (SYS_IND(p) == OPENBSD_PARTITION) {
+ printk("!");
+ if (!bsd_kdev) {
+ bsd_kdev = MKDEV(hd->major, minor);
+ bsd_maxpart = OPENBSD_MAXPARTITIONS;
+ }
}
#endif
+#ifdef CONFIG_UNIXWARE_DISKLABEL
+ if (SYS_IND(p) == UNIXWARE_PARTITION)
+ unixware_partition(hd, MKDEV(hd->major, minor));
+#endif
#ifdef CONFIG_SOLARIS_X86_PARTITION
/* james@bpgc.com: Solaris has a nasty indicator: 0x82
@@ -495,6 +589,13 @@
}
#endif
}
+#ifdef CONFIG_BSD_DISKLABEL
+ if (bsd_kdev) {
+ printk(" <");
+ bsd_disklabel_partition(hd, bsd_kdev, bsd_maxpart);
+ printk(" >");
+ }
+#endif
/*
* Check for old-style Disk Manager partition table
*/
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov