Re: [PATCH] Speedup FAT filesystem directory reads

From: OGAWA Hirofumi
Date: Thu Aug 04 2005 - 09:29:03 EST


Karsten Wiese <annabellesgarden@xxxxxxxx> writes:

> Please give this a try and commit to -mm or mainline, if approved.

Looks good. Thanks. However, I tweaked the patch.

- replace __getblk() to sb_getblk()
- exclude root-dir of FAT12/FAT16 from readahead
- exclude (sec_per_clus == 1) from readahead
- move the all readahead stuff to one inline function

What do you think of the following patch?
--
OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>


Signed-off-by: Karsten Wiese <annabellesgarden@xxxxxxxx>
Signed-off-by: OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>
---

fs/fat/dir.c | 28 ++++++++++++++++++++++++++--
1 files changed, 26 insertions(+), 2 deletions(-)

diff -puN fs/fat/dir.c~fat-sb_breadahead fs/fat/dir.c
--- linux-2.6.13-rc4/fs/fat/dir.c~fat-sb_breadahead 2005-08-04 21:21:59.000000000 +0900
+++ linux-2.6.13-rc4-hirofumi/fs/fat/dir.c 2005-08-04 23:05:58.000000000 +0900
@@ -30,6 +30,29 @@ static inline loff_t fat_make_i_pos(stru
| (de - (struct msdos_dir_entry *)bh->b_data);
}

+static inline void fat_dir_readahead(struct inode *dir, sector_t iblock,
+ sector_t phys)
+{
+ struct super_block *sb = dir->i_sb;
+ struct msdos_sb_info *sbi = MSDOS_SB(sb);
+ struct buffer_head *bh;
+ int sec;
+
+ /* This is not a first sector of cluster, or sec_per_clus == 1 */
+ if ((iblock & (sbi->sec_per_clus - 1)) || sbi->sec_per_clus == 1)
+ return;
+ /* root dir of FAT12/FAT16 */
+ if ((sbi->fat_bits != 32) && (dir->i_ino == MSDOS_ROOT_INO))
+ return;
+
+ bh = sb_getblk(sb, phys);
+ if (bh && !buffer_uptodate(bh)) {
+ for (sec = 0; sec < sbi->sec_per_clus; sec++)
+ sb_breadahead(sb, phys + sec);
+ }
+ brelse(bh);
+}
+
/* Returns the inode number of the directory entry at offset pos. If bh is
non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
returned in bh.
@@ -58,6 +81,8 @@ next:
if (err || !phys)
return -1; /* beyond EOF or error */

+ fat_dir_readahead(dir, iblock, phys);
+
*bh = sb_bread(sb, phys);
if (*bh == NULL) {
printk(KERN_ERR "FAT: Directory bread(block %llu) failed\n",
@@ -635,8 +660,7 @@ RecEnd:
EODir:
filp->f_pos = cpos;
FillFailed:
- if (bh)
- brelse(bh);
+ brelse(bh);
if (unicode)
free_page((unsigned long)unicode);
out:
_
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/