Commit a3db5a33 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] fat cluster search speedup

From: Bjorn Stenberg <bjorn@haxx.se>
      OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

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.

Also, commit the next_cluster search hint toand from the superblock in
write_super/fill_super.
parent 7058e439
......@@ -897,6 +897,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
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);
......
......@@ -74,6 +74,7 @@ void fat_clusters_flush(struct super_block *sb)
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);
......@@ -130,19 +131,23 @@ int fat_add_cluster(struct inode *inode)
unlock_fat(sb);
return -ENOSPC;
}
limit = MSDOS_SB(sb)->clusters;
for (count = 0; count < limit; count++) {
nr = ((count + MSDOS_SB(sb)->prev_free) % limit) + 2;
limit = MSDOS_SB(sb)->clusters + 2;
nr = MSDOS_SB(sb)->prev_free + 1;
for (count = 0; count < MSDOS_SB(sb)->clusters; count++, nr++) {
nr = nr % limit;
if (nr < 2)
nr = 2;
if (fat_access(sb, nr, -1) == FAT_ENT_FREE)
break;
}
if (count >= limit) {
if (count >= MSDOS_SB(sb)->clusters) {
MSDOS_SB(sb)->free_clusters = 0;
unlock_fat(sb);
return -ENOSPC;
}
MSDOS_SB(sb)->prev_free = (count + MSDOS_SB(sb)->prev_free + 1) % limit;
MSDOS_SB(sb)->prev_free = nr;
fat_access(sb, nr, FAT_ENT_EOF);
if (MSDOS_SB(sb)->free_clusters != -1)
MSDOS_SB(sb)->free_clusters--;
......
......@@ -146,8 +146,7 @@ struct fat_boot_fsinfo {
__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];
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment