diff options
-rw-r--r-- | sys/arch/sparc/include/disklabel.h | 3 | ||||
-rw-r--r-- | sys/arch/sparc/include/sun_disklabel.h | 11 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/disksubr.c | 116 |
3 files changed, 124 insertions, 6 deletions
diff --git a/sys/arch/sparc/include/disklabel.h b/sys/arch/sparc/include/disklabel.h index 3b4601fb0f2..9c9b28b1e1a 100644 --- a/sys/arch/sparc/include/disklabel.h +++ b/sys/arch/sparc/include/disklabel.h @@ -1,3 +1,4 @@ +/* $OpenBSD: disklabel.h,v 1.2 1996/09/12 04:33:27 downsj Exp $ */ /* $NetBSD: disklabel.h,v 1.4 1995/09/01 17:20:31 pk Exp $ */ /* @@ -35,7 +36,7 @@ #define LABELSECTOR 0 /* sector containing label */ #define LABELOFFSET 64 /* offset of label in sector */ -#define MAXPARTITIONS 8 /* number of partitions */ +#define MAXPARTITIONS 16 /* number of partitions */ #define RAW_PART 2 /* raw partition: xx?c */ struct cpu_disklabel { diff --git a/sys/arch/sparc/include/sun_disklabel.h b/sys/arch/sparc/include/sun_disklabel.h index 8f01b84115d..7556bd4c7cd 100644 --- a/sys/arch/sparc/include/sun_disklabel.h +++ b/sys/arch/sparc/include/sun_disklabel.h @@ -1,3 +1,4 @@ +/* $OpenBSD: sun_disklabel.h,v 1.5 1996/09/12 04:33:28 downsj Exp $ */ /* $NetBSD: sun_disklabel.h,v 1.6 1996/01/07 22:03:09 thorpej Exp $ */ /* @@ -88,7 +89,17 @@ struct sun_dkpart { struct sun_disklabel { /* total size = 512 bytes */ char sl_text[128]; +#if MAXPARTITIONS > 8 +#define SUNXPART (MAXPARTITIONS-8) + u_long sl_xpsum; /* additive cksum, [sl_xpmag,sl_xxx1) */ + u_long sl_xpmag; /* "extended" magic number */ +#define SL_XPMAG (0x199d1fe2+SUNXPART) + struct sun_dkpart sl_xpart[SUNXPART]; /* "extended" partitions, i through p */ + char sl_xxx1[292-8-(8*SUNXPART)]; /* [292] including sl_x* */ +#else +#define SUNXPART 0 char sl_xxx1[292]; +#endif u_short sl_rpm; /* rotational speed */ u_short sl_pcylinders; /* number of physical cyls */ u_short sl_sparespercyl; /* spare sectors per cylinder */ diff --git a/sys/arch/sparc/sparc/disksubr.c b/sys/arch/sparc/sparc/disksubr.c index 4446fd1927f..0e4ab2f726f 100644 --- a/sys/arch/sparc/sparc/disksubr.c +++ b/sys/arch/sparc/sparc/disksubr.c @@ -1,3 +1,4 @@ +/* $OpenBSD: disksubr.c,v 1.6 1996/09/12 04:33:29 downsj Exp $ */ /* $NetBSD: disksubr.c,v 1.16 1996/04/28 20:25:59 thorpej Exp $ */ /* @@ -285,14 +286,15 @@ bounds_check_with_label(bp, lp, wlabel) #define dkpart(dev) (minor(dev) & 7) struct partition *p = lp->d_partitions + dkpart(bp->b_dev); - int labelsect = lp->d_partitions[0].p_offset; int maxsz = p->p_size; int sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; /* overwriting disk label ? */ /* XXX should also protect bootstrap in first 8K */ - if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect && - (bp->b_flags & B_READ) == 0 && wlabel == 0) { + /* XXX this assumes everything <=LABELSECTOR is label! */ + /* But since LABELSECTOR is 0, that's ok for now. */ + if ((bp->b_blkno + p->p_offset <= LABELSECTOR) && + ((bp->b_flags & B_READ) == 0) && (wlabel == 0)) { bp->b_error = EROFS; goto bad; } @@ -330,7 +332,7 @@ bad: /* What partition types to assume for Sun disklabels: */ static u_char -sun_fstypes[8] = { +sun_fstypes[16] = { FS_BSDFFS, /* a */ FS_SWAP, /* b */ FS_OTHER, /* c - whole disk */ @@ -339,9 +341,38 @@ sun_fstypes[8] = { FS_BSDFFS, /* f */ FS_BSDFFS, /* g */ FS_BSDFFS, /* h */ + FS_BSDFFS, /* i */ + FS_BSDFFS, /* j */ + FS_BSDFFS, /* k */ + FS_BSDFFS, /* l */ + FS_BSDFFS, /* m */ + FS_BSDFFS, /* n */ + FS_BSDFFS, /* o */ + FS_BSDFFS /* p */ }; /* + * Given a struct sun_disklabel, assume it has an extended partition + * table and compute the correct value for sl_xpsum. + */ +static __inline u_long +sun_extended_sum(sl) + struct sun_disklabel *sl; +{ + u_long lsum; + u_long *xp; + u_long *ep; + + xp = (u_long *) &sl->sl_xpmag; + ep = (u_long *) &sl->sl_xxx1[0]; + + lsum = 0; + for (; xp < ep; xp++) + lsum += *xp; + return(lsum); +} + +/* * Given a SunOS disk label, set lp to a BSD disk label. * Returns NULL on success, else an error string. * @@ -388,7 +419,7 @@ disklabel_sun_to_bsd(cp, lp) lp->d_rpm = sl->sl_rpm; lp->d_interleave = sl->sl_interleave; - lp->d_npartitions = 8; + lp->d_npartitions = MAXPARTITIONS; /* These are as defined in <ufs/ffs/fs.h> */ lp->d_bbsize = 8192; /* XXX */ lp->d_sbsize = 8192; /* XXX */ @@ -414,6 +445,45 @@ disklabel_sun_to_bsd(cp, lp) } } +#if SUNXPART > 0 + + /* Clear "extended" partition info, tentatively */ + for (i = 0; i < SUNXPART; i++) { + npp = &lp->d_partitions[i+8]; + npp->p_offset = 0; + npp->p_size = 0; + npp->p_fstype = FS_UNUSED; + } + + /* Check to see if there's an "extended" partition table */ + if (sl->sl_xpmag == SL_XPMAG) { /* probably... */ + if (sun_extended_sum(sl) == sl->sl_xpsum) { /* ...yes! */ + /* + * There is. Copy over the "extended" partitions. + * This code parallels the loop for partitions a-h. + * + * XXX Abstract the common code? + */ + for (i = 0; i < SUNXPART; i++) { + spp = &sl->sl_xpart[i]; + npp = &lp->d_partitions[i+8]; + npp->p_offset = spp->sdkp_cyloffset * secpercyl; + npp->p_size = spp->sdkp_nsectors; + if (npp->p_size == 0) { + npp->p_fstype = FS_UNUSED; + } else { + npp->p_fstype = sun_fstypes[i+8]; + if (npp->p_fstype == FS_BSDFFS) { + npp->p_fsize = 1024; + npp->p_frag = 8; + npp->p_cpg = 16; + } + } + } + } + } +#endif /* if SUNXPART > 0 */ + lp->d_checksum = 0; lp->d_checksum = dkcksum(lp); return (NULL); @@ -464,6 +534,42 @@ disklabel_bsd_to_sun(lp, cp) } sl->sl_magic = SUN_DKMAGIC; +#if SUNXPART > 0 + /* + * The reason we load the extended table stuff only conditionally + * is so that a label that doesn't need it will have NULs there, like + * a "traditional" Sun label. Since Suns seem to ignore everything + * between sl_text and sl_rpm, this probably doesn't matter, but it + * certainly doesn't hurt anything and it's easy to do. + */ + + /* Do we need to load the extended table? */ + for (i = 0; i < SUNXPART; i++) { + if (lp->d_partitions[i+8].p_offset || + lp->d_partitions[i+8].p_size) + break; + } + if (i < SUNXPART) { /* we do */ + sl->sl_xpmag = SL_XPMAG; + for (i = 0; i < SUNXPART; i++) { + spp = &sl->sl_xpart[i]; + npp = &lp->d_partitions[i+8]; + if (npp->p_offset % secpercyl) + return(EINVAL); + sl->sl_xpart[i].sdkp_cyloffset = npp->p_offset / secpercyl; + sl->sl_xpart[i].sdkp_nsectors = npp->p_size; + } + sl->sl_xpsum = sun_extended_sum(sl); + } else { + sl->sl_xpmag = 0; + for (i = 0; i < SUNXPART; i++) { + sl->sl_xpart[i].sdkp_cyloffset = 0; + sl->sl_xpart[i].sdkp_nsectors = 0; + } + sl->sl_xpsum = 0; + } +#endif /* if SUNXPART > 0 */ + /* Correct the XOR check. */ sp1 = (u_short *)sl; sp2 = (u_short *)(sl + 1); |