aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3/dir.c')
-rw-r--r--fs/ext3/dir.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index 2eea96ec78ed..4c82531ea0a8 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * filp,
102 int err; 102 int err;
103 struct inode *inode = filp->f_path.dentry->d_inode; 103 struct inode *inode = filp->f_path.dentry->d_inode;
104 int ret = 0; 104 int ret = 0;
105 int dir_has_error = 0;
105 106
106 sb = inode->i_sb; 107 sb = inode->i_sb;
107 108
@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * filp,
148 * of recovering data when there's a bad sector 149 * of recovering data when there's a bad sector
149 */ 150 */
150 if (!bh) { 151 if (!bh) {
151 ext3_error (sb, "ext3_readdir", 152 if (!dir_has_error) {
152 "directory #%lu contains a hole at offset %lu", 153 ext3_error(sb, __func__, "directory #%lu "
153 inode->i_ino, (unsigned long)filp->f_pos); 154 "contains a hole at offset %lld",
155 inode->i_ino, filp->f_pos);
156 dir_has_error = 1;
157 }
154 /* corrupt size? Maybe no more blocks to read */ 158 /* corrupt size? Maybe no more blocks to read */
155 if (filp->f_pos > inode->i_blocks << 9) 159 if (filp->f_pos > inode->i_blocks << 9)
156 break; 160 break;
@@ -410,7 +414,7 @@ static int call_filldir(struct file * filp, void * dirent,
410 get_dtype(sb, fname->file_type)); 414 get_dtype(sb, fname->file_type));
411 if (error) { 415 if (error) {
412 filp->f_pos = curr_pos; 416 filp->f_pos = curr_pos;
413 info->extra_fname = fname->next; 417 info->extra_fname = fname;
414 return error; 418 return error;
415 } 419 }
416 fname = fname->next; 420 fname = fname->next;
@@ -449,11 +453,21 @@ static int ext3_dx_readdir(struct file * filp,
449 * If there are any leftover names on the hash collision 453 * If there are any leftover names on the hash collision
450 * chain, return them first. 454 * chain, return them first.
451 */ 455 */
452 if (info->extra_fname && 456 if (info->extra_fname) {
453 call_filldir(filp, dirent, filldir, info->extra_fname)) 457 if (call_filldir(filp, dirent, filldir, info->extra_fname))
454 goto finished; 458 goto finished;
455 459
456 if (!info->curr_node) 460 info->extra_fname = NULL;
461 info->curr_node = rb_next(info->curr_node);
462 if (!info->curr_node) {
463 if (info->next_hash == ~0) {
464 filp->f_pos = EXT3_HTREE_EOF;
465 goto finished;
466 }
467 info->curr_hash = info->next_hash;
468 info->curr_minor_hash = 0;
469 }
470 } else if (!info->curr_node)
457 info->curr_node = rb_first(&info->root); 471 info->curr_node = rb_first(&info->root);
458 472
459 while (1) { 473 while (1) {