*BSD News Article 34852


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!constellation!convex!hermes.oc.com!news.kei.com!uhog.mit.edu!europa.eng.gtefsd.com!library.ucla.edu!agate!tfs.com!julian
From: julian@tfs.com (Julian Elischer)
Subject: YES.. this time it works! (mounting DOS)
Message-ID: <Cv0zFo.8Iq@tfs.com>
Organization: TRW Financial Systems
Date: Wed, 24 Aug 1994 06:02:12 GMT
Lines: 321

Thanks to the several people who helped me debug this..

I eventually found a machine I could test on..
and found the silly bugs..

here is a version that I have seen working with my
own eyes...

This will make a 'virtual' disklabel if none is found..
BIOS style partitions are found and set into
partitions e,f,g and h. As well, if a 386bsd partition
is found but no disklabel, then partitions a and c are set
up correctly as well. (it should be possible to put 
a Filesystem on a raw 386bsd partition using this).
Whether  it then allows you to update the partitions without
rebooting is a whole different question.

There is work going on in several places to supersede
this patch, but this should keep the wolves from the door 
in the mean-while.

julian
-------------------cut here--------------------
*** ufs_disksubr.c.orig	Mon Jun  6 18:21:39 1994
--- ufs_disksubr.c	Tue Aug 23 22:53:30 1994
***************
*** 177,190 ****
  	struct disklabel *dlp;
  	char *msg = NULL;
  	int cyl, dospartoff, i;
  
  	/* minimal requirements for archtypal disk label */
  	if (lp->d_secperunit == 0)
  		lp->d_secperunit = 0x1fffffff;
! 	lp->d_npartitions = 1;
! 	if (lp->d_partitions[0].p_size == 0)
! 		lp->d_partitions[0].p_size = 0x1fffffff;
  	lp->d_partitions[0].p_offset = 0;
  
  	/* obtain buffer to probe drive with */
  	bp = geteblk((int)lp->d_secsize);
--- 177,198 ----
  	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)
  		lp->d_secperunit = 0x1fffffff;
! 	lp->d_npartitions = 4;
! 	lp->d_partitions[0].p_size = 0;
  	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;
+ 	if(lp->d_partitions[3].p_size == 0)
+ 		lp->d_partitions[3].p_size = DOSBBSECTOR + 1; /* start low */
+ 	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,356 ----
  		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) != (char) 0x55)
! 		  ||(*(bp->b_un.b_addr + 511) != (char) 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;
+ 
+ 			/*
+ 			 * make sure the D part can hold it all 
+ 			 */
+ 			if((dp->dp_start + dp->dp_size) 
+ 			   > lp->d_partitions[3].p_size) {
+ 				lp->d_partitions[3].p_size
+ 					= (dp->dp_start + dp->dp_size);
+ 			}
  			
+ 			/*
+ 			 * 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) {
+ 				switch(dp->dp_typ) {
+ 				case DOSPTYP_386BSD:
+ 					/*
+ 					 * at a pinch we could throw
+ 					 * a FFS on here
+ 					 */
+ 					lp->d_partitions[pseudopart].p_fstype
+ 							= FS_BSDFFS;
+ 					/*
+ 					 * Only get a disklabel from the 
+ 					 * first one we see..
+ 					 */
+ 					if (seenBSD == 0) {
+ 						/*
+ 					 	* 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;
+ 						lp->d_partitions[2].p_size =
+ 							dp->dp_size;
+ 						lp->d_partitions[2].p_offset = 
+ 							dp->dp_start;
+ 					}
+ 					break;
+ 				case 0xB7: /* BSDI (?)*//* doubtful */
+ 					lp->d_partitions[pseudopart].p_fstype
+ 							= FS_BSDFFS;
+ 					break;
+ 				case 1:
+ 				case 4:
+ 				case 6:
+ 				case 0xF2:
+ 					lp->d_partitions[pseudopart].p_fstype
+ 							= FS_MSDOS;
+ 					break;
+ 				}
+ 					
+ 				/*
+ 			 	 * 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.
+ 				 * If we've seen a 386bsd part, 
+ 				 * believe it and check no further.
+ 			 	 */
+ 				if (seenBSD) continue;
+ 				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)) {
--- 359,388 ----
  
  	/* 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)) {
-------------------end patch-------------------

+----------------------------------+       ______ _  __
|   __--_|\  Julian Elischer       |       \     U \/ / On assignment
|  /       \ julian@tfs.com        +------>x   USA    \ in a very strange
| (   OZ    ) 300 lakeside Dr. oakland CA. \___   ___ | country !
+- X_.---._/  USA+(510) 645-3137(wk)           \_/   \\            
          v