diff options
Diffstat (limited to 'fs/fat/dir.c')
| -rw-r--r-- | fs/fat/dir.c | 28 | 
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 | ||
| 33 | static 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: | |||
| 635 | EODir: | 660 | EODir: | 
| 636 | filp->f_pos = cpos; | 661 | filp->f_pos = cpos; | 
| 637 | FillFailed: | 662 | FillFailed: | 
| 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); | 
| 642 | out: | 666 | out: | 
