PERFORCE change 123099 for review

Brian Chu chub at FreeBSD.org
Sun Jul 8 08:29:31 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=123099

Change 123099 by chub at chub-msdosfs on 2007/07/08 08:28:50

	 fsck_msdosfs's loading of the bootsector now uses the unified headers in fs/sys/msdosfs instead of hard coding offsets to variables.

Affected files ...

.. //depot/projects/soc2007/chub-msdosfs2/sbin/fsck_msdosfs/boot.c#2 edit

Differences ...

==== //depot/projects/soc2007/chub-msdosfs2/sbin/fsck_msdosfs/boot.c#2 (text+ko) ====

@@ -30,8 +30,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <sys/cdefs.h>
 
-#include <sys/cdefs.h>
 #ifndef lint
 __RCSID("$NetBSD: boot.c,v 1.9 2003/07/24 19:25:46 ws Exp $");
 static const char rcsid[] =
@@ -44,131 +44,164 @@
 #include <stdio.h>
 #include <unistd.h>
 
+#include <fs/msdosfs/bootsect.h>
+#include <fs/msdosfs/bpb.h>
 #include "ext.h"
 #include "fsutil.h"
 
 int
-readboot(dosfs, boot)
-	int dosfs;
-	struct bootblock *boot;
+readboot(int dosfs, struct bootblock *boot)
 {
-	u_char block[DOSBOOTBLOCKSIZE];
-	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
-	u_char backup[DOSBOOTBLOCKSIZE];
+  union bootsector buffer;
+  union bootsector backup;
+  struct byte_bpb50 *pfat50;
+  struct byte_bpb710 *pfat710;
+  struct byte_Extboot *pfatext;
+  struct fsinfo fsstruct;
 	int ret = FSOK;
 	
-	if (read(dosfs, block, sizeof block) < sizeof block) {
+	if (read(dosfs, &buffer, sizeof(union bootsector))
+      < sizeof(union bootsector)) {
 		perror("could not read boot block");
 		return FSFATAL;
 	}
 
-	if (block[510] != 0x55 || block[511] != 0xaa) {
-		pfatal("Invalid signature in boot block: %02x%02x", block[511], block[510]);
+	if (buffer.bs50.bsBootSectSig0 != BOOTSIG0 ||
+      buffer.bs50.bsBootSectSig1 != BOOTSIG1) {
+		pfatal("Invalid signature in boot block: %02x%02x",
+           buffer.bs50.bsBootSectSig1,
+           buffer.bs50.bsBootSectSig0);
 		return FSFATAL;
 	}
+  
+  /* set the bpb structs to the boot sector's bpb */
+  pfat50 = (struct byte_bpb50 *)&buffer.bs50.bsBPB;
+  pfat710 = (struct byte_bpb710 *)&buffer.bs710.bsBPB;
 
-	memset(boot, 0, sizeof *boot);
+	memset(boot, 0, sizeof(struct bootblock));
 	boot->ValidFat = -1;
 
-	/* decode bios parameter block */
-	boot->BytesPerSec = block[11] + (block[12] << 8);
-	boot->SecPerClust = block[13];
-	boot->ResSectors = block[14] + (block[15] << 8);
-	boot->FATs = block[16];
-	boot->RootDirEnts = block[17] + (block[18] << 8);
-	boot->Sectors = block[19] + (block[20] << 8);
-	boot->Media = block[21];
-	boot->FATsmall = block[22] + (block[23] << 8);
-	boot->SecPerTrack = block[24] + (block[25] << 8);
-	boot->Heads = block[26] + (block[27] << 8);
-	boot->HiddenSecs = block[28] + (block[29] << 8) + (block[30] << 16) + (block[31] << 24);
-	boot->HugeSectors = block[32] + (block[33] << 8) + (block[34] << 16) + (block[35] << 24);
+	/* decode bios parameter block and store in a compacted
+   * architecture independent data structure for future use
+   */
+	boot->BytesPerSec = getushort(pfat50->bpbBytesPerSec);
+	boot->SecPerClust = pfat50->bpbSecPerClust;
+	boot->ResSectors = getushort(pfat50->bpbResSectors);
+	boot->FATs = pfat50->bpbFATs;
+	boot->RootDirEnts = getushort(pfat50->bpbRootDirEnts);
+	boot->Sectors = getushort(pfat50->bpbSectors);
+	boot->Media = pfat50->bpbMedia;
+	boot->SecPerTrack = getushort(pfat50->bpbSecPerTrack);
+	boot->Heads = getushort(pfat50->bpbHeads);
+	boot->HiddenSecs = getulong(pfat50->bpbHiddenSecs);
+	boot->HugeSectors = getulong(pfat50->bpbHugeSectors);
 
-	boot->FATsecs = boot->FATsmall;
+  /* first defaulting to FAT12/FAT16 for number of FAT sectors */
+	boot->FATsecs = getushort(pfat50->bpbFATsecs);
 
-	if (!boot->RootDirEnts)
+	if (boot->RootDirEnts == 0) {
+    /* FAT32 parsing */
 		boot->flags |= FAT32;
-	if (boot->flags & FAT32) {
-		boot->FATsecs = block[36] + (block[37] << 8)
-				+ (block[38] << 16) + (block[39] << 24);
-		if (block[40] & 0x80)
-			boot->ValidFat = block[40] & 0x0f;
+		boot->FATsecs = getulong(pfat710->bpbBigFATsecs);
+		if (pfat710->bpbExtFlags[0] & 0x80) {
+			boot->ValidFat = pfat710->bpbExtFlags[0] & 0x0f;
+    }
 
 		/* check version number: */
-		if (block[42] || block[43]) {
-			/* Correct?				XXX */
+    if (pfat710->bpbFSVers[0] != 0 ||
+        pfat710->bpbFSVers[1] != 0) {
 			pfatal("Unknown file system version: %x.%x",
-			       block[43], block[42]);
+			       pfat710->bpbFSVers[1],
+             pfat710->bpbFSVers[0]);
 			return FSFATAL;
 		}
-		boot->RootCl = block[44] + (block[45] << 8)
-			       + (block[46] << 16) + (block[47] << 24);
-		boot->FSInfo = block[48] + (block[49] << 8);
-		boot->Backup = block[50] + (block[51] << 8);
+
+		boot->RootCl = getulong(pfat710->bpbRootClust);
+		boot->FSInfo = getushort(pfat710->bpbFSInfo);
+		boot->Backup = getushort(pfat710->bpbBackup);
 
 		if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
-		    != boot->FSInfo * boot->BytesPerSec
-		    || read(dosfs, fsinfo, sizeof fsinfo)
-		    != sizeof fsinfo) {
+		    != boot->FSInfo * boot->BytesPerSec) {
+      perror("could not seek to fsinfo block to read");
+      return FSFATAL;
+    }
+
+    if (read(dosfs, &fsstruct, sizeof(struct fsinfo))
+        != sizeof(struct fsinfo)) {
 			perror("could not read fsinfo block");
 			return FSFATAL;
 		}
-		if (memcmp(fsinfo, "RRaA", 4)
-		    || memcmp(fsinfo + 0x1e4, "rrAa", 4)
-		    || fsinfo[0x1fc]
-		    || fsinfo[0x1fd]
-		    || fsinfo[0x1fe] != 0x55
-		    || fsinfo[0x1ff] != 0xaa
-		    || fsinfo[0x3fc]
-		    || fsinfo[0x3fd]
-		    || fsinfo[0x3fe] != 0x55
-		    || fsinfo[0x3ff] != 0xaa) {
+
+		if (memcmp(fsstruct.fsisig1, "RRaA", 4) ||
+		    memcmp(fsstruct.fsisig2, "rrAa", 4) ||
+        memcmp(fsstruct.fsisig3, "\0\0\125\252", 4) ||
+        memcmp(fsstruct.fsisig4, "\0\0\125\252", 4)) {
 			pwarn("Invalid signature in fsinfo block");
+
 			if (ask(0, "fix")) {
-				memcpy(fsinfo, "RRaA", 4);
-				memcpy(fsinfo + 0x1e4, "rrAa", 4);
-				fsinfo[0x1fc] = fsinfo[0x1fd] = 0;
-				fsinfo[0x1fe] = 0x55;
-				fsinfo[0x1ff] = 0xaa;
-				fsinfo[0x3fc] = fsinfo[0x3fd] = 0;
-				fsinfo[0x3fe] = 0x55;
-				fsinfo[0x3ff] = 0xaa;
+        memcpy(fsstruct.fsisig1, "RRaA", 4);
+        memcpy(fsstruct.fsisig2, "rrAa", 4);
+        memcpy(fsstruct.fsisig3, "\0\0\125\252", 4);
+        memcpy(fsstruct.fsisig4, "\0\0\125\252", 4);
+
 				if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
-				    != boot->FSInfo * boot->BytesPerSec
-				    || write(dosfs, fsinfo, sizeof fsinfo)
-				    != sizeof fsinfo) {
-					perror("Unable to write FSInfo");
+				    != boot->FSInfo * boot->BytesPerSec) {
+					perror("could not seek to fsinfo block to fix/write");
+					return FSFATAL;
+				}
+
+        if (write(dosfs, &fsstruct, sizeof(struct fsinfo))
+				    != sizeof(struct fsinfo)) {
+					perror("could not write fixed fsinfo");
 					return FSFATAL;
 				}
+
 				ret = FSBOOTMOD;
-			} else
+			}
+      else {
+        /* we didn't fix the corrupted FSInfo block */
 				boot->FSInfo = 0;
+      }
 		}
-		if (boot->FSInfo) {
-			boot->FSFree = fsinfo[0x1e8] + (fsinfo[0x1e9] << 8)
-				       + (fsinfo[0x1ea] << 16)
-				       + (fsinfo[0x1eb] << 24);
-			boot->FSNext = fsinfo[0x1ec] + (fsinfo[0x1ed] << 8)
-				       + (fsinfo[0x1ee] << 16)
-				       + (fsinfo[0x1ef] << 24);
+
+		if (boot->FSInfo != 0) {
+			boot->FSFree = getulong(fsstruct.fsinfree);
+			boot->FSNext = getulong(fsstruct.fsinxtfree);
 		}
 
 		if (lseek(dosfs, boot->Backup * boot->BytesPerSec, SEEK_SET)
-		    != boot->Backup * boot->BytesPerSec
-		    || read(dosfs, backup, sizeof backup) != sizeof  backup) {
+		    != boot->Backup * boot->BytesPerSec) {
+			perror("could not seek to read backup bootblock");
+			return FSFATAL;
+		}
+
+    if (read(dosfs, &backup, sizeof(union bootsector))
+        != sizeof(union bootsector)) {
 			perror("could not read backup bootblock");
 			return FSFATAL;
 		}
-		backup[65] = block[65];				/* XXX */
-		if (memcmp(block + 11, backup + 11, 79)) {
-			/* Correct?					XXX */
+
+    // never written back to disk
+    //backup.bs710.bsExt.exReserved1 = buffer.bs710.bsExt.exReserved1;
+
+		if (memcmp(buffer.bs710.bsBPB,
+               backup.bs710.bsBPB,
+               sizeof(struct bpb710)) ||
+        memcmp(buffer.bs710.bsExt,
+               backup.bs710.bsExt,
+               sizeof(struct extboot))) {
+
 			pfatal("backup doesn't compare to primary bootblock");
 			if (alwaysno)
 				pfatal("\n");
 			else
 				return FSFATAL;
 		}
-		/* Check backup FSInfo?					XXX */
+
+    /* Unnecessary to check the backup FSInfo because there isn't
+     * an physical backup copy of the FSInfo block.  There's only a
+     * backup of the FSInfo block number, which was checked (bsBPB) above.
+     */
 	}
 
 	boot->ClusterOffset = (boot->RootDirEnts * 32 + boot->BytesPerSec - 1)
@@ -190,13 +223,14 @@
 		boot->NumSectors = boot->Sectors;
 	} else
 		boot->NumSectors = boot->HugeSectors;
-	boot->NumClusters = (boot->NumSectors - boot->ClusterOffset) / boot->SecPerClust;
+	boot->NumClusters = (boot->NumSectors - boot->ClusterOffset)
+    / boot->SecPerClust;
 
-	if (boot->flags&FAT32)
+	if (boot->flags & FAT32)
 		boot->ClustMask = CLUST32_MASK;
-	else if (boot->NumClusters < (CLUST_RSRVD&CLUST12_MASK))
+	else if (boot->NumClusters < (CLUST_RSRVD & CLUST12_MASK))
 		boot->ClustMask = CLUST12_MASK;
-	else if (boot->NumClusters < (CLUST_RSRVD&CLUST16_MASK))
+	else if (boot->NumClusters < (CLUST_RSRVD & CLUST16_MASK))
 		boot->ClustMask = CLUST16_MASK;
 	else {
 		pfatal("Filesystem too big (%u clusters) for non-FAT32 partition",
@@ -230,33 +264,38 @@
 }
 
 int
-writefsinfo(dosfs, boot)
-	int dosfs;
-	struct bootblock *boot;
+writefsinfo(int dosfs, struct bootblock *boot)
 {
+  struct fsinfo fsstruct;
 	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
 
-	if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
-	    != boot->FSInfo * boot->BytesPerSec
-	    || read(dosfs, fsinfo, sizeof fsinfo) != sizeof fsinfo) {
-		perror("could not read fsinfo block");
+  if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
+      != boot->FSInfo * boot->BytesPerSec) {
+    perror("could not seek to fsinfo block to read");
+    return FSFATAL;
+  }
+
+  if (read(dosfs, &fsstruct, sizeof(struct fsinfo))
+      != sizeof(struct fsinfo)) {
+    perror("could not read fsinfo block");
+    return FSFATAL;
+  }
+
+  putulong(&fsstruct.fsinfree, boot->FSFree);
+  putulong(&fsstruct.fsinxtfree, boot->FSNext);
+
+  if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
+      != boot->FSInfo * boot->BytesPerSec) {
+    perror("could not seek to fsinfo block to write new block");
+    return FSFATAL;
+  }
+
+	if (write(dosfs, &fsstruct, sizeof(struct fsinfo))
+	    != sizeof(struct fsinfo)) {
+    perror("could not write fixed fsinfo");
 		return FSFATAL;
 	}
-	fsinfo[0x1e8] = (u_char)boot->FSFree;
-	fsinfo[0x1e9] = (u_char)(boot->FSFree >> 8);
-	fsinfo[0x1ea] = (u_char)(boot->FSFree >> 16);
-	fsinfo[0x1eb] = (u_char)(boot->FSFree >> 24);
-	fsinfo[0x1ec] = (u_char)boot->FSNext;
-	fsinfo[0x1ed] = (u_char)(boot->FSNext >> 8);
-	fsinfo[0x1ee] = (u_char)(boot->FSNext >> 16);
-	fsinfo[0x1ef] = (u_char)(boot->FSNext >> 24);
-	if (lseek(dosfs, boot->FSInfo * boot->BytesPerSec, SEEK_SET)
-	    != boot->FSInfo * boot->BytesPerSec
-	    || write(dosfs, fsinfo, sizeof fsinfo)
-	    != sizeof fsinfo) {
-		perror("Unable to write FSInfo");
-		return FSFATAL;
-	}
+
 	/*
 	 * Technically, we should return FSBOOTMOD here.
 	 *
@@ -264,7 +303,7 @@
 	 * support for FAT32) doesn't maintain the FSINFO block
 	 * correctly, it has to be fixed pretty often.
 	 *
-	 * Therefor, we handle the FSINFO block only informally,
+	 * Therefore, we handle the FSINFO block only informally,
 	 * fixing it if necessary, but otherwise ignoring the
 	 * fact that it was incorrect.
 	 */


More information about the p4-projects mailing list