Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/macppc correct writedisklabel() on MBR-partitioned ...



details:   https://anonhg.NetBSD.org/src/rev/93c5f21b28ed
branches:  trunk
changeset: 533013:93c5f21b28ed
user:      itojun <itojun%NetBSD.org@localhost>
date:      Wed Jun 19 03:10:56 2002 +0000

description:
correct writedisklabel() on MBR-partitioned disk.

while here, correct labelsector/offset mismatch in writedisklabel,
when readdisklabel() have found the label at nonstandard location
(due to magic number search).  a lot of other ports have the same problem.

diffstat:

 sys/arch/macppc/include/disklabel.h |   8 +++++-
 sys/arch/macppc/macppc/disksubr.c   |  43 ++++++++++++++++++++++--------------
 2 files changed, 32 insertions(+), 19 deletions(-)

diffs (181 lines):

diff -r 8dfe92604868 -r 93c5f21b28ed sys/arch/macppc/include/disklabel.h
--- a/sys/arch/macppc/include/disklabel.h       Wed Jun 19 01:54:26 2002 +0000
+++ b/sys/arch/macppc/include/disklabel.h       Wed Jun 19 03:10:56 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: disklabel.h,v 1.8 2002/03/23 01:29:35 wrstuden Exp $   */
+/*     $NetBSD: disklabel.h,v 1.9 2002/06/19 03:10:57 itojun Exp $     */
 
 /*-
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -98,11 +98,15 @@
 
 #define        LABELSECTOR     0               /* sector containing label */
 #define        LABELOFFSET     64              /* offset of label in sector */
+#define        MBR_LABELSECTOR 1               /* sector containing label - in MBR */
+#define        MBR_LABELOFFSET 0               /* offset of label in sector - in MBR */
 #define        MAXPARTITIONS   16              /* number of partitions */
 #define        RAW_PART        2               /* raw partition: XX?c */
 
 struct cpu_disklabel {
-       int cd_start;           /* Offset to NetBSD partition in blocks */
+       daddr_t cd_start;       /* Offset to NetBSD partition in blocks */
+       daddr_t cd_labelsector; /* label sector offset from cd_start */
+       int cd_labeloffset;     /* label byte offset within label sector */
 };
 
 /*
diff -r 8dfe92604868 -r 93c5f21b28ed sys/arch/macppc/macppc/disksubr.c
--- a/sys/arch/macppc/macppc/disksubr.c Wed Jun 19 01:54:26 2002 +0000
+++ b/sys/arch/macppc/macppc/disksubr.c Wed Jun 19 03:10:56 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: disksubr.c,v 1.22 2002/06/18 17:25:21 itojun Exp $     */
+/*     $NetBSD: disksubr.c,v 1.23 2002/06/19 03:10:56 itojun Exp $     */
 
 /*
  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
@@ -138,7 +138,7 @@
 static char *read_dos_label __P((dev_t, void (*)(struct buf *),
                struct disklabel *, struct cpu_disklabel *));
 static int get_netbsd_label __P((dev_t, void (*)(struct buf *),
-               struct disklabel *, daddr_t, int));
+               struct disklabel *, struct cpu_disklabel *));
 
 /*
  * Find an entry in the disk label that is unused and return it
@@ -407,7 +407,7 @@
        struct buf *bp;
        char *msg = NULL;
        int i, slot, maxslot = 0;
-       u_int32_t bsdpartoff, cyl;
+       u_int32_t bsdpartoff;
        struct mbr_partition *bsdp;
 
        /* get a buffer and initialize it */
@@ -422,7 +422,6 @@
        (*strat)(bp);
 
        bsdpartoff = 0;
-       cyl = LABELSECTOR / lp->d_secpercyl;
 
        /* if successful, wander through dos partition table */
        if (biowait(bp)) {
@@ -477,14 +476,15 @@
        } 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))
+               osdep->cd_labelsector = bsdpartoff + MBR_LABELSECTOR;
+               osdep->cd_labeloffset = MBR_LABELOFFSET;
+               if (get_netbsd_label(dev, strat, lp, osdep))
                        goto done;
                msg = "no NetBSD disk label";
        }
@@ -500,12 +500,11 @@
  * Get real NetBSD disk label
  */
 static int
-get_netbsd_label(dev, strat, lp, bno, offset)
+get_netbsd_label(dev, strat, lp, osdep)
        dev_t dev;
        void (*strat)(struct buf *);
        struct disklabel *lp;
-       daddr_t bno;
-       int offset;
+       struct cpu_disklabel *osdep;
 {
        struct buf *bp;
        struct disklabel *dlp;
@@ -515,7 +514,7 @@
        bp->b_dev = dev;
 
        /* Now get the label block */
-       bp->b_blkno = bno;
+       bp->b_blkno = osdep->cd_labelsector;
        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;
@@ -524,7 +523,7 @@
        if (biowait(bp))
                goto done;
 
-       for (dlp = (struct disklabel *)(bp->b_data + offset);
+       for (dlp = (struct disklabel *)(bp->b_data + osdep->cd_labeloffset);
             dlp <= (struct disklabel *)(bp->b_data + lp->d_secsize - sizeof (*dlp));
             dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
                if (dlp->d_magic == DISKMAGIC
@@ -532,6 +531,7 @@
                    && dlp->d_npartitions <= MAXPARTITIONS
                    && dkcksum(dlp) == 0) {
                        *lp = *dlp;
+                       osdep->cd_labeloffset = (caddr_t)dlp - bp->b_data;
                        brelse(bp);
                        return 1;
                }
@@ -581,29 +581,37 @@
 
        osdep->cd_start = -1;
 
-       if (biowait(bp))
+       /* XXX cd_start is abused as a flag for fictious disklabel */
+
+       if (biowait(bp)) {
                msg = "I/O error reading block zero";
-       else if (get_netbsd_label(dev, strat, lp, LABELSECTOR, LABELOFFSET))
+               goto done;
+       }
+       osdep->cd_labelsector = LABELSECTOR;
+       osdep->cd_labeloffset = LABELOFFSET;
+       if (get_netbsd_label(dev, strat, lp, osdep))
                osdep->cd_start = 0;
        else {
                u_int16_t *sbSigp;
 
                sbSigp = (u_int16_t *)bp->b_data;
                if (*sbSigp == 0x4552) {
+                       /* it ignores labelsector/offset */
                        msg = read_mac_label(dev, strat, lp, osdep);
+                       /* the disklabel is fictious */
                } else if (bswap16(*(u_int16_t *)(bp->b_data + MBR_MAGICOFF))
                           == MBR_MAGIC) {
+                       /* read_dos_label figures out labelsector/offset */
                        msg = read_dos_label(dev, strat, lp, osdep);
-#if 0
                        if (!msg)
                                osdep->cd_start = 0;
-#endif
                } else {
                        msg = "no disk label -- NetBSD or Macintosh";
                        osdep->cd_start = 0;    /* XXX for now */
                }
        }
 
+done:
        brelse(bp);
        return (msg);
 }
@@ -664,7 +672,7 @@
        bp = geteblk(lp->d_secsize);
        bp->b_dev = dev;
 
-       bp->b_blkno = osdep->cd_start + LABELSECTOR;
+       bp->b_blkno = osdep->cd_start + osdep->cd_labelsector;
        bp->b_cylinder = bp->b_blkno / (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl;
        bp->b_bcount = lp->d_secsize;
 
@@ -677,7 +685,8 @@
        bp->b_flags &= ~(B_READ|B_DONE);
        bp->b_flags |= B_WRITE;
 
-       memcpy((caddr_t)bp->b_data + LABELOFFSET, (caddr_t)lp, sizeof *lp);
+       memcpy((caddr_t)bp->b_data + osdep->cd_labeloffset, (caddr_t)lp,
+           sizeof *lp);
 
        (*strat)(bp);
        error = biowait(bp);



Home | Main Index | Thread Index | Old Index