Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/mac68k/mac68k From Hauke Fath: clean up disklabel ...



details:   https://anonhg.NetBSD.org/src/rev/e53e5c3015c6
branches:  trunk
changeset: 487592:e53e5c3015c6
user:      scottr <scottr%NetBSD.org@localhost>
date:      Fri Jun 09 15:27:35 2000 +0000

description:
>From Hauke Fath:  clean up disklabel support, particularly for
native NetBSD labels.

diffstat:

 sys/arch/mac68k/mac68k/disksubr.c |  251 +++++++++++++++++++------------------
 1 files changed, 131 insertions(+), 120 deletions(-)

diffs (truncated from 389 to 300 lines):

diff -r 2d59c9b121f0 -r e53e5c3015c6 sys/arch/mac68k/mac68k/disksubr.c
--- a/sys/arch/mac68k/mac68k/disksubr.c Fri Jun 09 15:18:55 2000 +0000
+++ b/sys/arch/mac68k/mac68k/disksubr.c Fri Jun 09 15:27:35 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: disksubr.c,v 1.35 2000/05/19 18:54:25 thorpej Exp $    */
+/*     $NetBSD: disksubr.c,v 1.36 2000/06/09 15:27:35 scottr Exp $     */
 
 /*
  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
@@ -68,16 +68,6 @@
  *
  */
 
-/* rewritten, 2-5-93 MLF */
-/* its alot cleaner now, and adding support for new partition types
- * isn't a bitch anymore
- * known bugs:
- * 1) when only an HFS_PART part exists on a drive it gets assigned to "B"
- * this is because of line 623 of sd.c, I think this line should go.
- * 2) /sbin/disklabel expects the whole disk to be in "D", we put it in
- * "C" (I think) and we don't set that position in the disklabel structure
- * as used.  Again, not my fault.
- */
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/buf.h>
@@ -96,10 +86,12 @@
 #define HFS_PART 4
 #define SCRATCH_PART 5
 
-int fat_types[] = { MBR_PTYPE_FAT12, MBR_PTYPE_FAT16S,
-                   MBR_PTYPE_FAT16B, MBR_PTYPE_FAT32,
-                   MBR_PTYPE_FAT32L, MBR_PTYPE_FAT16L,
-                   -1 };
+int fat_types[] = {
+       MBR_PTYPE_FAT12, MBR_PTYPE_FAT16S,
+       MBR_PTYPE_FAT16B, MBR_PTYPE_FAT32,
+       MBR_PTYPE_FAT32L, MBR_PTYPE_FAT16L,
+       -1
+};
 
 static int getFreeLabelEntry __P((struct disklabel *));
 static int whichType __P((struct part_map_entry *));
@@ -107,10 +99,10 @@
                struct partition *, int));
 static int getNamedType __P((struct part_map_entry *, int,
                struct disklabel *, int, int, int *));
-static char *read_mac_label __P((dev_t, void (*)(struct buf *),
-               struct disklabel *, struct cpu_disklabel *));
-static char *read_dos_label __P((dev_t, void (*)(struct buf *),
-               struct disklabel *, struct cpu_disklabel *));
+static char *read_mac_label __P((char *, struct disklabel *, int *));
+static char *read_mbr_label __P((char *, struct disklabel *, int *));
+static char *read_bsd_label __P((char *, struct disklabel *, int *));
+
 
 /*
  * Find an entry in the disk label that is unused and return it
@@ -120,14 +112,13 @@
 getFreeLabelEntry(lp)
        struct disklabel *lp;
 {
-       int i = 0;
+       int i;
 
        for (i = 0; i < MAXPARTITIONS; i++) {
                if ((i != RAW_PART)
                    && (lp->d_partitions[i].p_fstype == FS_UNUSED))
                        return i;
        }
-
        return -1;
 }
 
@@ -182,6 +173,7 @@
 setpartition(part, pp, fstype)
        struct part_map_entry *part;
        struct partition *pp;
+       int fstype;
 {
        pp->p_size = part->pmPartBlkCnt;
        pp->p_offset = part->pmPyPartStart;
@@ -199,7 +191,7 @@
        int *maxslot;
 {
        struct blockzeroblock *bzb;
-       int i = 0;
+       int i;
 
        for (i = 0; i < num_parts; i++) {
                if (whichType(part + i) != type)
@@ -255,36 +247,37 @@
  *     NetBSD to live on cluster 0--regardless of the actual order on the
  *     disk.  This whole algorithm should probably be changed in the future.
  */
+
+/*
+ * This uses sector zero.  If this contains what looks like a valid
+ * Macintosh boot sector, we attempt to fill in the disklabel structure
+ * with the partition data from block #1 on.
+ */
 static char *
-read_mac_label(dev, strat, lp, osdep)
-       dev_t dev;
-       void (*strat)(struct buf *);
+read_mac_label(dlbuf, lp, match)
+       char *dlbuf;
        struct disklabel *lp;
-       struct cpu_disklabel *osdep;
+       int *match;
 {
+       u_int16_t *sbSigp;
        struct part_map_entry *part;
        struct partition *pp;
-       struct buf *bp;
-       char *msg = NULL;
-       int i, slot, maxslot = 0;
+       char *msg;
+       int i, slot, maxslot;
 
-       /* get buffer and initialize it */
-       bp = geteblk((int)lp->d_secsize * NUM_PARTS);
-       bp->b_dev = dev;
+       maxslot = 0;
+       *match = 0;
+       msg = NULL;
 
-       /* read partition map */
-       bp->b_blkno = 1;        /* partition map starts at blk 1 */
-       bp->b_bcount = lp->d_secsize * NUM_PARTS;
-       bp->b_flags = B_BUSY | B_READ;
-       bp->b_cylinder = 1 / lp->d_secpercyl;
-       (*strat)(bp);
+       sbSigp = (u_int16_t *)dlbuf;
+       if (*sbSigp != DRIVER_MAP_MAGIC)
+               return msg;
 
-       if (biowait(bp)) {
-               msg = "Macintosh partition map I/O error";
-               goto done;
-       }
+       /* Found Macintosh partition magic number; set up disklabel */
+       *match = (-1);
 
-       part = (struct part_map_entry *)bp->b_data;
+       /* the Macintosh partition table starts at sector #1 */
+       part = (struct part_map_entry *)(dlbuf + lp->d_secsize);
 
        /* Fill in standard partitions */
        lp->d_npartitions = RAW_PART + 1;
@@ -328,79 +321,102 @@
                        maxslot = slot;
        }
        lp->d_npartitions = ((maxslot >= RAW_PART) ? maxslot : RAW_PART) + 1;
-
-done:
-       bp->b_flags |= B_INVAL;
-       brelse(bp);
-
        return msg;
 }
 
-/* Read MS-DOS partition table.
+/*
+ * Scan the disk buffer for a DOS style master boot record.
+ * Return if no match; otherwise, set up an in-core disklabel .
  *
- * XXX -
+ * XXX stuff like this really should be MI
+ *
  * Since FFS is endian sensitive, we pay no effort in attempting to
  * dig up *BSD/i386 disk labels that may be present on the disk.
  * Hence anything but DOS partitions is treated as unknown FS type, but
  * this should suffice to mount_msdos Zip and other removable media.
  */
 static char *
-read_dos_label(dev, strat, lp, osdep)
-       dev_t dev;
-       void (*strat)(struct buf *);
+read_mbr_label(dlbuf, lp, match)
+       char *dlbuf;
        struct disklabel *lp;
-       struct cpu_disklabel *osdep;
+       int *match;
 {
        struct mbr_partition *dp;
        struct partition *pp;
-       struct buf *bp;
-       char *msg = NULL;
-       int i, *ip, slot, maxslot = 0;
+       char *msg;
+       size_t mbr_lbl_off;
+       int i, *ip, slot, maxslot;
 
-       /* get a buffer and initialize it */
-       bp = geteblk((int)lp->d_secsize);
-       bp->b_dev = dev;
+       maxslot = 0;
+       *match = 0;
+       msg = NULL;
 
-       /* read master boot record */
-       bp->b_blkno = MBR_BBSECTOR;
-       bp->b_bcount = lp->d_secsize;
-       bp->b_flags = B_BUSY | B_READ;
-       bp->b_cylinder = MBR_BBSECTOR / lp->d_secpercyl;
-       (*strat)(bp);
+       if (MBR_MAGIC != bswap16(*(u_int16_t *)(dlbuf + MBR_MAGICOFF)))
+               return msg;
 
-       /* if successful, wander through dos partition table */
-       if (biowait(bp)) {
-               msg = "dos partition I/O error";
-               goto done;
-       } else {
-               /* XXX */
-               dp = (struct mbr_partition *)(bp->b_data + MBR_PARTOFF);
-               for (i = 0; i < NMBRPART; i++, dp++) {
-                       if (dp->mbrp_typ != 0) {
-                               slot = getFreeLabelEntry(lp);
-                               if (slot > maxslot)
-                                       maxslot = slot;
-
-                               pp = &lp->d_partitions[slot];
-                               pp->p_fstype = FS_OTHER;
-                               pp->p_offset = bswap32(dp->mbrp_start);
-                               pp->p_size = bswap32(dp->mbrp_size);
-
-                               for (ip = fat_types; *ip != -1; ip++) {
-                                       if (dp->mbrp_typ == *ip) {
-                                               pp->p_fstype = FS_MSDOS;
-                                               break;
-                                       }
-                               }
+       /* Found MBR magic number; set up disklabel */
+       *match = (-1);
+       mbr_lbl_off = MBR_BBSECTOR * lp->d_secsize + MBR_PARTOFF;
+       
+       dp = (struct mbr_partition *)(dlbuf + mbr_lbl_off);
+       for (i = 0; i < NMBRPART; i++, dp++) {
+               if (dp->mbrp_typ == 0)
+                       continue;
+               
+               slot = getFreeLabelEntry(lp);
+               maxslot = (slot > maxslot) ? maxslot : slot;
+               
+               pp = &lp->d_partitions[slot];
+               pp->p_fstype = FS_OTHER;
+               pp->p_offset = bswap32(dp->mbrp_start);
+               pp->p_size = bswap32(dp->mbrp_size);
+               
+               for (ip = fat_types; *ip != -1; ip++) {
+                       if (dp->mbrp_typ == *ip) {
+                               pp->p_fstype = FS_MSDOS;
+                               break;
                        }
                }
        }
        lp->d_npartitions = ((maxslot >= RAW_PART) ? maxslot : RAW_PART) + 1;
+       return msg;
+}
 
- done:
-       bp->b_flags |= B_INVAL;
-       brelse(bp);
-       return (msg);
+/*
+ * Scan the disk buffer in four byte steps for a native BSD disklabel
+ * (different ports have variable-sized bootcode before the label)
+ */
+static char *
+read_bsd_label(dlbuf, lp, match)
+       char *dlbuf;
+       struct disklabel *lp;
+       int *match;
+{
+       struct disklabel *dlp;
+       char *msg;
+       struct disklabel *blk_start, *blk_end;
+       
+       *match = 0;
+       msg = NULL;
+
+       blk_start = (struct disklabel *)dlbuf;
+       blk_end = (struct disklabel *)(dlbuf + NUM_PARTS * 
+           lp->d_secsize - sizeof(struct disklabel));
+
+       for (dlp = blk_start; dlp <= blk_end; 
+            dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
+               if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC) {
+                       /* Sanity check */
+                       if (dlp->d_npartitions <= MAXPARTITIONS && 
+                           dkcksum(dlp) == 0) {
+                               *lp = *dlp;
+                               *match = (-1);
+                       } else
+                               msg = "Disk label corrupted";
+                       break;
+               }
+       }



Home | Main Index | Thread Index | Old Index