aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3')
-rw-r--r--fs/ext3/dir.c52
-rw-r--r--fs/ext3/inode.c2
2 files changed, 25 insertions, 29 deletions
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index 832867aef3dc..773459164bb2 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -95,11 +95,10 @@ static int ext3_readdir(struct file * filp,
95 void * dirent, filldir_t filldir) 95 void * dirent, filldir_t filldir)
96{ 96{
97 int error = 0; 97 int error = 0;
98 unsigned long offset, blk; 98 unsigned long offset;
99 int i, num, stored; 99 int i, stored;
100 struct buffer_head * bh, * tmp, * bha[16]; 100 struct ext3_dir_entry_2 *de;
101 struct ext3_dir_entry_2 * de; 101 struct super_block *sb;
102 struct super_block * sb;
103 int err; 102 int err;
104 struct inode *inode = filp->f_dentry->d_inode; 103 struct inode *inode = filp->f_dentry->d_inode;
105 int ret = 0; 104 int ret = 0;
@@ -124,12 +123,29 @@ static int ext3_readdir(struct file * filp,
124 } 123 }
125#endif 124#endif
126 stored = 0; 125 stored = 0;
127 bh = NULL;
128 offset = filp->f_pos & (sb->s_blocksize - 1); 126 offset = filp->f_pos & (sb->s_blocksize - 1);
129 127
130 while (!error && !stored && filp->f_pos < inode->i_size) { 128 while (!error && !stored && filp->f_pos < inode->i_size) {
131 blk = (filp->f_pos) >> EXT3_BLOCK_SIZE_BITS(sb); 129 unsigned long blk = filp->f_pos >> EXT3_BLOCK_SIZE_BITS(sb);
132 bh = ext3_bread(NULL, inode, blk, 0, &err); 130 struct buffer_head map_bh;
131 struct buffer_head *bh = NULL;
132
133 map_bh.b_state = 0;
134 err = ext3_get_block_handle(NULL, inode, blk, &map_bh, 0, 0);
135 if (!err) {
136 page_cache_readahead(sb->s_bdev->bd_inode->i_mapping,
137 &filp->f_ra,
138 filp,
139 map_bh.b_blocknr >>
140 (PAGE_CACHE_SHIFT - inode->i_blkbits),
141 1);
142 bh = ext3_bread(NULL, inode, blk, 0, &err);
143 }
144
145 /*
146 * We ignore I/O errors on directories so users have a chance
147 * of recovering data when there's a bad sector
148 */
133 if (!bh) { 149 if (!bh) {
134 ext3_error (sb, "ext3_readdir", 150 ext3_error (sb, "ext3_readdir",
135 "directory #%lu contains a hole at offset %lu", 151 "directory #%lu contains a hole at offset %lu",
@@ -138,26 +154,6 @@ static int ext3_readdir(struct file * filp,
138 continue; 154 continue;
139 } 155 }
140 156
141 /*
142 * Do the readahead
143 */
144 if (!offset) {
145 for (i = 16 >> (EXT3_BLOCK_SIZE_BITS(sb) - 9), num = 0;
146 i > 0; i--) {
147 tmp = ext3_getblk (NULL, inode, ++blk, 0, &err);
148 if (tmp && !buffer_uptodate(tmp) &&
149 !buffer_locked(tmp))
150 bha[num++] = tmp;
151 else
152 brelse (tmp);
153 }
154 if (num) {
155 ll_rw_block (READA, num, bha);
156 for (i = 0; i < num; i++)
157 brelse (bha[i]);
158 }
159 }
160
161revalidate: 157revalidate:
162 /* If the dir block has changed since the last call to 158 /* If the dir block has changed since the last call to
163 * readdir(2), then we might be pointing to an invalid 159 * readdir(2), then we might be pointing to an invalid
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 0384e539b88f..d59d5a667b0b 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -671,7 +671,7 @@ err_out:
671 * The BKL may not be held on entry here. Be sure to take it early. 671 * The BKL may not be held on entry here. Be sure to take it early.
672 */ 672 */
673 673
674static int 674int
675ext3_get_block_handle(handle_t *handle, struct inode *inode, sector_t iblock, 675ext3_get_block_handle(handle_t *handle, struct inode *inode, sector_t iblock,
676 struct buffer_head *bh_result, int create, int extend_disksize) 676 struct buffer_head *bh_result, int create, int extend_disksize)
677{ 677{