Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fix reading FAT32 root dirs that span >1 cluster

Unlike FAT12/16, FAT32 does not guarantee that root directories will
occupy consecutive clusters. To get each cluster after the first you
must access the FAT as with any other directory. This patch implements
this and bumps up the largest valid cluster number to support large
e.g. 64MB partitions.
  • Loading branch information...
commit f98f7fe36d1878669f319e63e1ff0b7260dc88dd 1 parent 1dac1a7
Nick Gasson authored November 13, 2010

Showing 1 changed file with 15 additions and 5 deletions. Show diff stats Hide diff stats

  1. 20  fs/fat/fat.c
20  fs/fat/fat.c
@@ -384,7 +384,7 @@ get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
384 384
 			newclust = get_fatent(mydata, endclust);
385 385
 			if((newclust -1)!=endclust)
386 386
 				goto getit;
387  
-			if (newclust <= 0x0001 || newclust >= 0xfff0) {
  387
+			if (newclust <= 0x0001 || newclust >= 0xfffff0) {
388 388
 				FAT_DPRINT("curclust: 0x%x\n", newclust);
389 389
 				FAT_DPRINT("Invalid FAT entry\n");
390 390
 				return gotsize;
@@ -419,7 +419,7 @@ get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,
419 419
 		filesize -= actsize;
420 420
 		buffer += actsize;
421 421
 		curclust = get_fatent(mydata, endclust);
422  
-		if (curclust <= 0x0001 || curclust >= 0xfff0) {
  422
+		if (curclust <= 0x0001 || curclust >= 0xfffff0) {
423 423
 			FAT_DPRINT("curclust: 0x%x\n", curclust);
424 424
 			FAT_ERROR("Invalid FAT entry\n");
425 425
 			return gotsize;
@@ -580,7 +580,7 @@ static dir_entry *get_dentfromdir (fsdata * mydata, int startsect,
580 580
 	    return retdent;
581 581
 	}
582 582
 	curclust = get_fatent (mydata, curclust);
583  
-	if (curclust <= 0x0001 || curclust >= 0xfff0) {
  583
+	if (curclust <= 0x0001 || curclust >= 0xfffff0) {
584 584
 	    FAT_DPRINT ("curclust: 0x%x\n", curclust);
585 585
 	    FAT_ERROR ("Invalid FAT entry\n");
586 586
 	    return NULL;
@@ -679,7 +679,7 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize,
679 679
     dir_entry *dentptr;
680 680
     __u16 prevcksum = 0xffff;
681 681
     char *subname = "";
682  
-    int rootdir_size, cursect;
  682
+    int rootdir_size, cursect, curclus;
683 683
     int idx, isdir = 0;
684 684
     int files = 0, dirs = 0;
685 685
     long ret = 0;
@@ -697,6 +697,7 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize,
697 697
     mydata->fat_sect = bs.reserved;
698 698
     cursect = mydata->rootdir_sect
699 699
 	    = mydata->fat_sect + mydata->fatlength * bs.fats;
  700
+    curclus = bs.root_cluster;   // For FAT32 only
700 701
     mydata->clust_size = bs.cluster_size;
701 702
     if (mydata->fatsize == 32) {
702 703
 	rootdir_size = mydata->clust_size;
@@ -818,7 +819,16 @@ do_fat_read(const char *filename, void *buffer, unsigned long maxsize,
818 819
 
819 820
 	    goto rootdir_done;  /* We got a match */
820 821
 	}
821  
-	cursect++;
  822
+
  823
+	if (mydata->fatsize != 32)
  824
+	   cursect++;
  825
+	else {
  826
+	   // FAT32 does not guarantee contiguous root directory
  827
+	   curclus = get_fatent (mydata, curclus);
  828
+	   cursect = (curclus * mydata->clust_size) + mydata->data_begin;
  829
+
  830
+	   FAT_DPRINT ("root clus %d sector %d\n", curclus, cursect);
  831
+	}
822 832
     }
823 833
   rootdir_done:
824 834
 

0 notes on commit f98f7fe

Please sign in to comment.
Something went wrong with that request. Please try again.