From 9e1c373ba9ab942fd94fc1f5d5ff49aaad0530a9 Mon Sep 17 00:00:00 2001 From: itojun Date: Mon, 17 Jun 2002 15:07:06 +0000 Subject: [PATCH] make it possible to handle/mount FDISK-partitioned disk. extended FDISK partitions are not supported yet. openbsd code was used as reference. --- sys/arch/macppc/macppc/disksubr.c | 110 ++++++++++++++++++++---------- sys/sys/disklabel_mbr.h | 3 +- 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/sys/arch/macppc/macppc/disksubr.c b/sys/arch/macppc/macppc/disksubr.c index bf3d53f665b5..6157d5f8c8aa 100644 --- a/sys/arch/macppc/macppc/disksubr.c +++ b/sys/arch/macppc/macppc/disksubr.c @@ -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 @@ 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 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 @@ read_dos_label(dev, strat, lp, osdep) 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 @@ read_dos_label(dev, strat, lp, osdep) 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 */ - 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; - } - } - } + } + /* 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) + 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); + + 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 @@ read_dos_label(dev, strat, lp, osdep) * 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 @@ get_netbsd_label(dev, strat, lp, bno) 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 @@ get_netbsd_label(dev, strat, lp, bno) 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 @@ readdisklabel(dev, strat, lp, osdep) 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 @@ readdisklabel(dev, strat, lp, osdep) } 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 --git a/sys/sys/disklabel_mbr.h b/sys/sys/disklabel_mbr.h index d7cc1a01c4ce..45029b556704 100644 --- a/sys/sys/disklabel_mbr.h +++ b/sys/sys/disklabel_mbr.h @@ -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 @@ struct mbr_partition { /* 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 */