diff options
Diffstat (limited to 'fs/ext3/dir.c')
-rw-r--r-- | fs/ext3/dir.c | 55 |
1 files changed, 26 insertions, 29 deletions
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index 832867aef3dc..f37528ed222e 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -39,7 +39,7 @@ static int ext3_dx_readdir(struct file * filp, | |||
39 | static int ext3_release_dir (struct inode * inode, | 39 | static int ext3_release_dir (struct inode * inode, |
40 | struct file * filp); | 40 | struct file * filp); |
41 | 41 | ||
42 | struct file_operations ext3_dir_operations = { | 42 | const struct file_operations ext3_dir_operations = { |
43 | .llseek = generic_file_llseek, | 43 | .llseek = generic_file_llseek, |
44 | .read = generic_read_dir, | 44 | .read = generic_read_dir, |
45 | .readdir = ext3_readdir, /* we take BKL. needed?*/ | 45 | .readdir = ext3_readdir, /* we take BKL. needed?*/ |
@@ -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,30 @@ 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_blocks_handle(NULL, inode, blk, 1, | ||
135 | &map_bh, 0, 0); | ||
136 | if (err > 0) { | ||
137 | page_cache_readahead(sb->s_bdev->bd_inode->i_mapping, | ||
138 | &filp->f_ra, | ||
139 | filp, | ||
140 | map_bh.b_blocknr >> | ||
141 | (PAGE_CACHE_SHIFT - inode->i_blkbits), | ||
142 | 1); | ||
143 | bh = ext3_bread(NULL, inode, blk, 0, &err); | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * We ignore I/O errors on directories so users have a chance | ||
148 | * of recovering data when there's a bad sector | ||
149 | */ | ||
133 | if (!bh) { | 150 | if (!bh) { |
134 | ext3_error (sb, "ext3_readdir", | 151 | ext3_error (sb, "ext3_readdir", |
135 | "directory #%lu contains a hole at offset %lu", | 152 | "directory #%lu contains a hole at offset %lu", |
@@ -138,26 +155,6 @@ static int ext3_readdir(struct file * filp, | |||
138 | continue; | 155 | continue; |
139 | } | 156 | } |
140 | 157 | ||
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 | |||
161 | revalidate: | 158 | revalidate: |
162 | /* If the dir block has changed since the last call to | 159 | /* If the dir block has changed since the last call to |
163 | * readdir(2), then we might be pointing to an invalid | 160 | * readdir(2), then we might be pointing to an invalid |