Return to BSD News archive
Newsgroups: comp.os.386bsd.misc Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!bunyip.cc.uq.oz.au!munnari.oz.au!spool.mu.edu!agate!tfs.com!julian From: julian@tfs.com (Julian Elischer) Subject: Re: Mounting unlabelled (DOS) hard disks Message-ID: <Cuyp4D.88@tfs.com> Organization: TRW Financial Systems, Oakland, CA References: <CuyHsn.C1x@tfs.com> Date: Tue, 23 Aug 1994 00:24:13 GMT Lines: 257 In article <CuyHsn.C1x@tfs.com>, Julian Elischer <julian@tfs.com> wrote: >Yesterday I posted a patch (which Icouldn't fully test, >and last night I suddenly woke up realising that there was >a logical flaw in it, and that the patch needed to be >extended. > > >here is the new patch: > >if you have an unlabelled DOS hard-disk, >please try this out.. >the four BIOS partitions should appear as partitions >e,f,g and h. NO, NO, NO, I just saw a typo going past!.. [bad patch deleted] here is the fixed one. an electronic packet of m&ms (smarties in some countries) to anyone who spots the typo BY EYE.. :-) julian ----------cut here----- *** ufs_disksubr.c.orig Sun Aug 21 22:51:21 1994 --- ufs_disksubr.c Mon Aug 22 14:04:07 1994 *************** *** 177,182 **** --- 177,184 ---- struct disklabel *dlp; char *msg = NULL; int cyl, dospartoff, i; + int pseudopart = 4; /* we fill in pseudoparts from e through h*/ + int seenBSD = 0; /* minimal requirements for archtypal disk label */ if (lp->d_secperunit == 0) *************** *** 185,190 **** --- 187,198 ---- if (lp->d_partitions[0].p_size == 0) lp->d_partitions[0].p_size = 0x1fffffff; lp->d_partitions[0].p_offset = 0; + lp->d_partitions[1].p_size = 0; + lp->d_partitions[1].p_offset = 0; + lp->d_partitions[2].p_size = 0; + lp->d_partitions[2].p_offset = 0; + lp->d_partitions[3].p_size = 0; + lp->d_partitions[3].p_offset = 0; /* obtain buffer to probe drive with */ bp = geteblk((int)lp->d_secsize); *************** *** 205,246 **** bp->b_cylin = DOSBBSECTOR / lp->d_secpercyl; (*strat)(bp); ! /* if successful, wander through dos partition table */ if (biowait(bp)) { msg = "dos partition I/O error"; goto done; ! } else { ! /* XXX how do we check veracity/bounds of this? */ ! bcopy(bp->b_un.b_addr + DOSPARTOFF, dp, ! NDOSPART * sizeof(*dp)); ! for (i = 0; i < NDOSPART; i++, dp++) ! /* is this ours? */ ! if (dp->dp_size && ! dp->dp_typ == DOSPTYP_386BSD ! && dospartoff == 0) { ! /* need sector address for SCSI/IDE, ! cylinder for ESDI/ST506/RLL */ dospartoff = dp->dp_start; ! cyl = DPCYL(dp->dp_scyl, dp->dp_ssect); ! ! /* update disklabel with details */ lp->d_partitions[0].p_size = dp->dp_size; lp->d_partitions[0].p_offset = dp->dp_start; - lp->d_ntracks = dp->dp_ehd + 1; - lp->d_nsectors = DPSECT(dp->dp_esect); - lp->d_subtype |= (lp->d_subtype & 3) - + i | DSTYPE_INDOSPART; - lp->d_secpercyl = lp->d_ntracks * - lp->d_nsectors; } } ! } ! /* next, dig out disk label */ bp->b_blkno = dospartoff + LABELSECTOR; bp->b_cylin = cyl; bp->b_bcount = lp->d_secsize; --- 213,313 ---- bp->b_cylin = DOSBBSECTOR / lp->d_secpercyl; (*strat)(bp); ! /* ! * if we failed in the read, give up. ! */ if (biowait(bp)) { msg = "dos partition I/O error"; goto done; ! } ! /* ! * If there seems to be BIOS bootblock and partition table ! * in that block, then try interpret it, otherwise ! * give up and use whatever we have synthesised so far ! */ ! if ((bp->b_un.b_addr[510] != 0x55) ! ||(bp->b_un.b_addr[511] != 0xaa)) { ! msg = "Disk has no Fdisk partitions"; ! goto done; ! } ! /* XXX how do we check veracity/bounds of this? */ ! bcopy(bp->b_un.b_addr + DOSPARTOFF, dp, ! NDOSPART * sizeof(*dp)); ! /* ! * We set up the last 4 partitions in the ! * disklabel to reflect the DOS partitions ! * In case we never find a disklabel, in which ! * case this information will be all we have ! * but it might be all we need to access a DOS ! * partition. ! */ ! for (i = 0; i < NDOSPART; i++, dp++,pseudopart++) { ! ! /* ! * Set this DOS part into the disklabel ! */ ! lp->d_partitions[pseudopart].p_size = ! dp->dp_size; ! lp->d_partitions[pseudopart].p_offset = ! dp->dp_start; ! /* ! * If we haven't seen a *BSD partition then ! * check if this is a valid part.. ! * if it is it may be the best we are going to ! * to see, so take note of it to deduce a ! * geometry in case we never find a disklabel. ! */ ! if (dp->dp_size && (seenBSD == 0)) { ! if( dp->dp_typ == DOSPTYP_386BSD) { ! /* ! * If it IS our part, then we ! * need sector address for ! * SCSI/IDE, cylinder for ! * ESDI/ST506/RLL ! */ dospartoff = dp->dp_start; ! seenBSD = 1; ! cyl = DPCYL(dp->dp_scyl, ! dp->dp_ssect); ! ! /* ! * update disklabel with ! * details for reading the REAL ! * disklabel it it exists ! */ lp->d_partitions[0].p_size = dp->dp_size; lp->d_partitions[0].p_offset = dp->dp_start; } + /* + * Try deduce the geometry, working + * on the principle that this + * partition PROBABLY ends on a + * cylinder boundary. + * This is really a kludge, but we are + * forced into it by the PC's design. + */ + lp->d_ntracks = dp->dp_ehd + 1; + lp->d_nsectors = DPSECT(dp->dp_esect); + lp->d_subtype |= (lp->d_subtype & 3) + + i | DSTYPE_INDOSPART; + lp->d_secpercyl = lp->d_ntracks * + lp->d_nsectors; + } } ! lp->d_npartitions = 8; } ! /* ! * If we haven't seen a BSD partition, give up, use the dos version ! */ ! if(!seenBSD) goto done; ! ! /* ! * next, dig out disk label ! */ bp->b_blkno = dospartoff + LABELSECTOR; bp->b_cylin = cyl; bp->b_bcount = lp->d_secsize; *************** *** 249,274 **** /* if successful, locate disk label within block and validate */ if (biowait(bp)) { ! msg = "disk label I/O error"; goto done; ! } else for (dlp = (struct disklabel *)bp->b_un.b_addr; dlp <= (struct disklabel *)(bp->b_un.b_addr+DEV_BSIZE-sizeof(*dlp)); dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { ! if (msg == NULL) ! msg = "no disk label"; ! } else if (dlp->d_npartitions > MAXPARTITIONS || ! dkcksum(dlp) != 0) ! msg = "disk label corrupted"; ! else { ! *lp = *dlp; ! msg = NULL; ! break; } } ! ! if (msg) goto done; /* obtain bad sector table if requested and present */ if (bdp && (lp->d_flags & D_BADSECT)) { --- 316,345 ---- /* if successful, locate disk label within block and validate */ if (biowait(bp)) { ! printf("disk label I/O error\n"); goto done; ! /* leave us at least with the dos partitions */ ! } ! for (dlp = (struct disklabel *)bp->b_un.b_addr; dlp <= (struct disklabel *)(bp->b_un.b_addr+DEV_BSIZE-sizeof(*dlp)); dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { ! continue; } + if (dlp->d_npartitions > MAXPARTITIONS || + dkcksum(dlp) != 0) { + printf("disk label corrupted\n"); + goto done; + /* leave us at least with the dos partitions */ + } + *lp = *dlp; + msg = NULL; + break; } ! if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { ! printf("No disklabel found\n"); goto done; + } /* obtain bad sector table if requested and present */ if (bdp && (lp->d_flags & D_BADSECT)) { ---------------------