aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fat/dir.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index e5ae1b720dde..895049b2ac9c 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -30,6 +30,29 @@ static inline loff_t fat_make_i_pos(struct super_block *sb,
30 | (de - (struct msdos_dir_entry *)bh->b_data); 30 | (de - (struct msdos_dir_entry *)bh->b_data);
31} 31}
32 32
33static inline void fat_dir_readahead(struct inode *dir, sector_t iblock,
34 sector_t phys)
35{
36 struct super_block *sb = dir->i_sb;
37 struct msdos_sb_info *sbi = MSDOS_SB(sb);
38 struct buffer_head *bh;
39 int sec;
40
41 /* This is not a first sector of cluster, or sec_per_clus == 1 */
42 if ((iblock & (sbi->sec_per_clus - 1)) || sbi->sec_per_clus == 1)
43 return;
44 /* root dir of FAT12/FAT16 */
45 if ((sbi->fat_bits != 32) && (dir->i_ino == MSDOS_ROOT_INO))
46 return;
47
48 bh = sb_getblk(sb, phys);
49 if (bh && !buffer_uptodate(bh)) {
50 for (sec = 0; sec < sbi->sec_per_clus; sec++)
51 sb_breadahead(sb, phys + sec);
52 }
53 brelse(bh);
54}
55
33/* Returns the inode number of the directory entry at offset pos. If bh is 56/* Returns the inode number of the directory entry at offset pos. If bh is
34 non-NULL, it is brelse'd before. Pos is incremented. The buffer header is 57 non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
35 returned in bh. 58 returned in bh.
@@ -58,6 +81,8 @@ next:
58 if (err || !phys) 81 if (err || !phys)
59 return -1; /* beyond EOF or error */ 82 return -1; /* beyond EOF or error */
60 83
84 fat_dir_readahead(dir, iblock, phys);
85
61 *bh = sb_bread(sb, phys); 86 *bh = sb_bread(sb, phys);
62 if (*bh == NULL) { 87 if (*bh == NULL) {
63 printk(KERN_ERR "FAT: Directory bread(block %llu) failed\n", 88 printk(KERN_ERR "FAT: Directory bread(block %llu) failed\n",
@@ -635,8 +660,7 @@ RecEnd:
635EODir: 660EODir:
636 filp->f_pos = cpos; 661 filp->f_pos = cpos;
637FillFailed: 662FillFailed:
638 if (bh) 663 brelse(bh);
639 brelse(bh);
640 if (unicode) 664 if (unicode)
641 free_page((unsigned long)unicode); 665 free_page((unsigned long)unicode);
642out: 666out: