Source-Changes-HG archive

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

[src/trunk]: src/sys make it possible to handle/mount FDISK-partitioned disk.



details:   https://anonhg.NetBSD.org/src/rev/74ce3ee2b34a
branches:  trunk
changeset: 532881:74ce3ee2b34a
user:      itojun <itojun%NetBSD.org@localhost>
date:      Mon Jun 17 15:07:06 2002 +0000

description:
make it possible to handle/mount FDISK-partitioned disk.
extended FDISK partitions are not supported yet.
openbsd code was used as reference.

diffstat:

 sys/arch/macppc/macppc/disksubr.c |  102 ++++++++++++++++++++++++++-----------
 sys/sys/disklabel_mbr.h           |    3 +-
 2 files changed, 73 insertions(+), 32 deletions(-)

diffs (205 lines):

diff -r a057e415099b -r 74ce3ee2b34a sys/arch/macppc/macppc/disksubr.c
--- a/sys/arch/macppc/macppc/disksubr.c Mon Jun 17 14:08:25 2002 +0000
+++ b/sys/arch/macppc/macppc/disksubr.c Mon Jun 17 15:07:06 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: disksubr.c,v 1.20 2002/03/27 20:23:11 wrstuden Exp $   */
+/*     $NetBSD: disksubr.c,v 1.21 2002/06/17 15:07:06 itojun Exp $     */
 
 /*
  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
@@ -127,11 +127,6 @@
 #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 };
-
 static int getFreeLabelEntry __P((struct disklabel *));
 static int whichType __P((struct part_map_entry *, u_int8_t *, int *));
 static void setpartition __P((struct part_map_entry *,
@@ -142,8 +137,8 @@
                struct disklabel *, struct cpu_disklabel *));
 static char *read_dos_label __P((dev_t, void (*)(struct buf *),
                struct disklabel *, struct cpu_disklabel *));
-static int get_netbsd_label __P((dev_t dev, void (*strat)(struct buf *),
-               struct disklabel *lp, daddr_t bno));
+static int get_netbsd_label __P((dev_t, void (*)(struct buf *),
+               struct disklabel *, daddr_t, int));
 
 /*
  * Find an entry in the disk label that is unused and return it
@@ -409,10 +404,11 @@
        struct cpu_disklabel *osdep;
 {
        struct mbr_partition *dp;
-       struct partition *pp;
        struct buf *bp;
        char *msg = NULL;
-       int i, *ip, slot, maxslot = 0;
+       int i, slot, maxslot = 0;
+       u_int32_t bsdpartoff, cyl;
+       struct mbr_partition *bsdp;
 
        /* get a buffer and initialize it */
        bp = geteblk((int)lp->d_secsize);
@@ -425,33 +421,74 @@
        bp->b_cylinder = MBR_BBSECTOR / lp->d_secpercyl;
        (*strat)(bp);
 
+       bsdpartoff = 0;
+       cyl = LABELSECTOR / lp->d_secpercyl;
+
        /* if successful, wander through dos partition table */
        if (biowait(bp)) {
                msg = "dos partition I/O error";
                goto done;
-       } else {
-               /* XXX */
+       }
+       /* XXX */
+       dp = (struct mbr_partition *)(bp->b_data + MBR_PARTOFF);
+       bsdp = NULL;
+       for (i = 0; i < NMBRPART; i++, dp++) {
+               switch (dp->mbrp_typ) {
+               case MBR_PTYPE_NETBSD:
+                       bsdp = dp;
+                       break;
+               case MBR_PTYPE_OPENBSD:
+               case MBR_PTYPE_386BSD:
+                       if (!bsdp)
+                               bsdp = dp;
+                       break;
+               }
+       }
+       if (!bsdp) {
+               /* generate fake disklabel */
                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;
+                       if (!dp->mbrp_typ)
+                               continue;
+                       slot = getFreeLabelEntry(lp);
+                       if (slot < 0)
+                               break;
+                       if (slot > maxslot)
+                               maxslot = slot;
+
+                       lp->d_partitions[slot].p_offset = bswap32(dp->mbrp_start);
+                       lp->d_partitions[slot].p_size = bswap32(dp->mbrp_size);
 
-                               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;
-                                       }
-                               }
+                       switch (dp->mbrp_typ) {
+                       case MBR_PTYPE_FAT12:
+                       case MBR_PTYPE_FAT16S:
+                       case MBR_PTYPE_FAT16B:
+                       case MBR_PTYPE_FAT32:
+                       case MBR_PTYPE_FAT32L:
+                       case MBR_PTYPE_FAT16L:
+                               lp->d_partitions[slot].p_fstype = FS_MSDOS;
+                               break;
+                       default:
+                               lp->d_partitions[slot].p_fstype = FS_OTHER;
+                               break;
                        }
                }
+               msg = "no NetBSD disk label";
+       } else {
+               /* NetBSD partition on MBR */
+               bsdpartoff = bswap32(bsdp->mbrp_start);
+               cyl = MBR_PCYL(bsdp->mbrp_scyl, bsdp->mbrp_ssect);
+
+               lp->d_partitions[2].p_size = bswap32(bsdp->mbrp_size);
+               lp->d_partitions[2].p_offset = bswap32(bsdp->mbrp_start);
+               if (2 > maxslot)
+                       maxslot = 2;
+               /* read in disklabel, blkno + 1 for DOS disklabel offset */
+               if (get_netbsd_label(dev, strat, lp, bsdpartoff + 1, 0))
+                       goto done;
+               msg = "no NetBSD disk label";
        }
+
        lp->d_npartitions = ((maxslot >= RAW_PART) ? maxslot : RAW_PART) + 1;
 
  done:
@@ -463,11 +500,12 @@
  * Get real NetBSD disk label
  */
 static int
-get_netbsd_label(dev, strat, lp, bno)
+get_netbsd_label(dev, strat, lp, bno, offset)
        dev_t dev;
        void (*strat)(struct buf *);
        struct disklabel *lp;
        daddr_t bno;
+       int offset;
 {
        struct buf *bp;
        struct disklabel *dlp;
@@ -477,7 +515,7 @@
        bp->b_dev = dev;
 
        /* Now get the label block */
-       bp->b_blkno = bno + LABELSECTOR;
+       bp->b_blkno = bno;
        bp->b_bcount = lp->d_secsize;
        bp->b_flags |= B_READ;
        bp->b_cylinder = bp->b_blkno / (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl;
@@ -486,7 +524,7 @@
        if (biowait(bp))
                goto done;
 
-       for (dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
+       for (dlp = (struct disklabel *)(bp->b_data + offset);
             dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof (*dlp));
             dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
                if (dlp->d_magic == DISKMAGIC
@@ -545,7 +583,7 @@
 
        if (biowait(bp))
                msg = "I/O error reading block zero";
-       else if (get_netbsd_label(dev, strat, lp, 0))
+       else if (get_netbsd_label(dev, strat, lp, LABELSECTOR, LABELOFFSET))
                osdep->cd_start = 0;
        else {
                u_int16_t *sbSigp;
@@ -556,6 +594,8 @@
                } else if (bswap16(*(u_int16_t *)(bp->b_data + MBR_MAGICOFF))
                           == MBR_MAGIC) {
                        msg = read_dos_label(dev, strat, lp, osdep);
+                       if (!msg)
+                               osdep->cd_start = 0;
                } else {
                        msg = "no disk label -- NetBSD or Macintosh";
                        osdep->cd_start = 0;    /* XXX for now */
diff -r a057e415099b -r 74ce3ee2b34a sys/sys/disklabel_mbr.h
--- a/sys/sys/disklabel_mbr.h   Mon Jun 17 14:08:25 2002 +0000
+++ b/sys/sys/disklabel_mbr.h   Mon Jun 17 15:07:06 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: disklabel_mbr.h,v 1.7 2002/03/02 07:04:31 matt Exp $   */
+/*     $NetBSD: disklabel_mbr.h,v 1.8 2002/06/17 15:07:06 itojun Exp $ */
 
 /*
  * Copyright (c) 1994, 1998 Christopher G. Demetriou
@@ -67,6 +67,7 @@
 
 /* Known MBR partition types: */
 #define        MBR_PTYPE_NETBSD        0xa9    /* NetBSD partition type */
+#define        MBR_PTYPE_OPENBSD       0xa6    /* OpenBSD partition type */
 #define        MBR_PTYPE_386BSD        0xa5    /* 386BSD partition type */
 #define        MBR_PTYPE_FAT12         0x01    /* 12-bit FAT */
 #define        MBR_PTYPE_FAT16S        0x04    /* 16-bit FAT, less than 32M */



Home | Main Index | Thread Index | Old Index