Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9f966be8996f2829406324c68e4c67c2d64d864b
Commit:     9f966be8996f2829406324c68e4c67c2d64d864b
Parent:     d52df2e2ea2d881b1439bbdec7f67c27e0f47941
Author:     OGAWA Hirofumi <[EMAIL PROTECTED]>
AuthorDate: Tue Jan 8 15:32:41 2008 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Tue Jan 8 16:10:35 2008 -0800

    fat: optimize fat_count_free_clusters()
    
    On large partition, scanning the free clusters is very slow if users
    doesn't use "usefree" option.
    
    For optimizing it, this patch uses sb_breadahead() to read of FAT
    sectors. On some user's 15GB partition, this patch improved it very
    much (1min => 600ms).
    
    The following is the result of 2GB partition on my machine.
    
    without patch:
        [EMAIL PROTECTED] (/)# time df -h > /dev/null
    
        real    0m1.202s
        user    0m0.000s
        sys     0m0.440s
    
    with patch:
        [EMAIL PROTECTED] (/)# time df -h > /dev/null
    
        real    0m0.378s
        user    0m0.012s
        sys     0m0.168s
    
    Signed-off-by: OGAWA Hirofumi <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 fs/fat/fatent.c |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
index 2c1b73f..5fb3669 100644
--- a/fs/fat/fatent.c
+++ b/fs/fat/fatent.c
@@ -590,21 +590,49 @@ error:
 
 EXPORT_SYMBOL_GPL(fat_free_clusters);
 
+/* 128kb is the whole sectors for FAT12 and FAT16 */
+#define FAT_READA_SIZE         (128 * 1024)
+
+static void fat_ent_reada(struct super_block *sb, struct fat_entry *fatent,
+                         unsigned long reada_blocks)
+{
+       struct fatent_operations *ops = MSDOS_SB(sb)->fatent_ops;
+       sector_t blocknr;
+       int i, offset;
+
+       ops->ent_blocknr(sb, fatent->entry, &offset, &blocknr);
+
+       for (i = 0; i < reada_blocks; i++)
+               sb_breadahead(sb, blocknr + i);
+}
+
 int fat_count_free_clusters(struct super_block *sb)
 {
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
        struct fatent_operations *ops = sbi->fatent_ops;
        struct fat_entry fatent;
+       unsigned long reada_blocks, reada_mask, cur_block;
        int err = 0, free;
 
        lock_fat(sbi);
        if (sbi->free_clusters != -1)
                goto out;
 
+       reada_blocks = FAT_READA_SIZE >> sb->s_blocksize_bits;
+       reada_mask = reada_blocks - 1;
+       cur_block = 0;
+
        free = 0;
        fatent_init(&fatent);
        fatent_set_entry(&fatent, FAT_START_ENT);
        while (fatent.entry < sbi->max_cluster) {
+               /* readahead of fat blocks */
+               if ((cur_block & reada_mask) == 0) {
+                       unsigned long rest = sbi->fat_length - cur_block;
+                       fat_ent_reada(sb, &fatent, min(reada_blocks, rest));
+               }
+               cur_block++;
+
                err = fat_ent_read_block(sb, &fatent);
                if (err)
                        goto out;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to