Skip to contentSkip to conversation

fat cluster search speedup (2.4.20, 2.5.68)

PATCH New Björn Stenberg 1 participant 1 message Apr 22, 2003

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 fat cluster search speedup (2.4.20, 2.5.68)

Hello.

This simple patch makes the linux fat filesystem driver use the next_cluster field in the fat_boot_fsinfo structure. This field is a hint where to start looking for free clusters.

Using this field makes a big difference for disks connected over slow links such as USB 1.1. Finding the first free cluster on a 40gig fat-formatted usb disk can today take several minutes. This patch cuts it down to a fraction of a second.

Please Cc me on any discussion about this patch, as I am not subscribed to the list.

The patch is cooked in two flavors, for 2.4.20 and 2.5.68:

For 2.4.20:

linux/msdos_fs.h renamed from linux.orig/msdos_fs.h +1 -2
diff -Nru include/linux.orig/msdos_fs.h include/linux/msdos_fs.h
@@ -145,8 +145,7 @@
 	__u32   reserved1[120];	/* Nothing as far as I can tell */
 	__u32   signature2;	/* 0x61417272L */
 	__u32   free_clusters;	/* Free cluster count.  -1 if unknown */
-	__u32   next_cluster;	/* Most recently allocated cluster.
-				 * Unused under Linux. */
+	__u32   next_cluster;	/* Most recently allocated cluster */
 	__u32   reserved2[4];
 };
 
fat/inode.c renamed from fat.orig/inode.c +2 -1
diff -Nru fs/fat.orig/inode.c fs/fat/inode.c
@@ -637,6 +637,7 @@
 	sbi->cluster_bits = ffs(logical_sector_size * sbi->cluster_size) - 1;
 	sbi->fats = b->fats;
 	sbi->fat_start = CF_LE_W(b->reserved);
+	sbi->prev_free = 0;
 	if (!b->fat_length && b->fat32_length) {
 		struct fat_boot_fsinfo *fsinfo;
 		struct buffer_head *fsinfo_bh;
@@ -675,6 +676,7 @@
 			       sbi->fsinfo_sector);
 		} else {
 			sbi->free_clusters = CF_LE_L(fsinfo->free_clusters);
+			sbi->prev_free = CF_LE_L(fsinfo->next_cluster);
 		}
 
 		if (fsinfo_block != 0)
@@ -754,7 +756,6 @@
 	sb->s_magic = MSDOS_SUPER_MAGIC;
 	/* set up enough so that it can read an inode */
 	init_MUTEX(&sbi->fat_lock);
-	sbi->prev_free = 0;
 
 	cp = opts.codepage ? opts.codepage : 437;
 	sprintf(buf, "cp%d", cp);
fat/misc.c renamed from fat.orig/misc.c +1 -0
diff -Nru fs/fat.orig/misc.c fs/fat/misc.c
@@ -108,6 +108,7 @@
 		return;
 	}
 	fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters);
+	fsinfo->next_cluster = CF_LE_L(MSDOS_SB(sb)->prev_free);
 	fat_mark_buffer_dirty(sb, bh);
 	fat_brelse(sb, bh);
 }

For 2.5.68:

linux/msdos_fs.h renamed from linux/msdos_fs.h.orig +1 -2
@@ -146,8 +146,7 @@
 	__u32   reserved1[120];	/* Nothing as far as I can tell */
 	__u32   signature2;	/* 0x61417272L */
 	__u32   free_clusters;	/* Free cluster count.  -1 if unknown */
-	__u32   next_cluster;	/* Most recently allocated cluster.
-				 * Unused under Linux. */
+	__u32   next_cluster;	/* Most recently allocated cluster */
 	__u32   reserved2[4];
 };
 
fat/inode.c renamed from fat/inode.c.orig +1 -0
@@ -898,6 +898,7 @@
 			       sbi->fsinfo_sector);
 		} else {
 			sbi->free_clusters = CF_LE_L(fsinfo->free_clusters);
+			sbi->prev_free = CF_LE_L(fsinfo->next_cluster);
 		}
 
 		brelse(fsinfo_bh);
fat/misc.c renamed from fat/misc.c.orig +1 -0
@@ -74,6 +74,7 @@
 		       MSDOS_SB(sb)->fsinfo_sector);
 	} else {
 		fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters);
+		fsinfo->next_cluster = CF_LE_L(MSDOS_SB(sb)->prev_free);
 		mark_buffer_dirty(bh);
 	}
 	brelse(bh);
Signature · 1 line
Björn