summaryrefslogtreecommitdiff
path: root/fs/ext3
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-05-09 23:55:38 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-05-09 23:55:38 -0700
commite461abeb62ef330c4c1b1e9dae2a0a7a10213e79 (patch)
tree1531642dd5dff91d67cda4a5871760188679722d /fs/ext3
parenta7c8a1d320ff544a044f6fac5c7fda557f5ef60c (diff)
[PATCH] ext3 error handling fixes
From: Andreas Dilger <adilger@clusterfs.com> a) we don't call ext3_error() for an IO error in ext3_find_entry(), so we won't do the normal ext3 error handling (mark SB in error, remount-ro or panic if desired); b) in empty_dir() we don't continue checking for non-empty blocks after a content error (ext3_check_dir_entry() calls ext3_error() already); c) we had decided not to mark the SB in error for holes in directories to allow leway in the indexed-directory implementation, but this change incorrectly also disabled marking the SB in error for real IO errors.
Diffstat (limited to 'fs/ext3')
-rw-r--r--fs/ext3/namei.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 6ed3d4ff2bd9..4da226dd9e65 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -872,6 +872,8 @@ restart:
wait_on_buffer(bh);
if (!buffer_uptodate(bh)) {
/* read error, skip block & hope for the best */
+ ext3_error(sb, __FUNCTION__, "reading directory #%lu "
+ "offset %lu\n", dir->i_ino, block);
brelse(bh);
goto next;
}
@@ -1763,14 +1765,19 @@ static int empty_dir (struct inode * inode)
struct buffer_head * bh;
struct ext3_dir_entry_2 * de, * de1;
struct super_block * sb;
- int err;
+ int err = 0;
sb = inode->i_sb;
if (inode->i_size < EXT3_DIR_REC_LEN(1) + EXT3_DIR_REC_LEN(2) ||
!(bh = ext3_bread (NULL, inode, 0, 0, &err))) {
- ext3_warning (inode->i_sb, "empty_dir",
- "bad directory (dir #%lu) - no data block",
- inode->i_ino);
+ if (err)
+ ext3_error(inode->i_sb, __FUNCTION__,
+ "error %d reading directory #%lu offset 0",
+ err, inode->i_ino);
+ else
+ ext3_warning(inode->i_sb, __FUNCTION__,
+ "bad directory (dir #%lu) - no data block",
+ inode->i_ino);
return 1;
}
de = (struct ext3_dir_entry_2 *) bh->b_data;
@@ -1792,24 +1799,26 @@ static int empty_dir (struct inode * inode)
while (offset < inode->i_size ) {
if (!bh ||
(void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
+ err = 0;
brelse (bh);
bh = ext3_bread (NULL, inode,
offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err);
if (!bh) {
-#if 0
- ext3_error (sb, "empty_dir",
- "directory #%lu contains a hole at offset %lu",
- inode->i_ino, offset);
-#endif
+ if (err)
+ ext3_error(sb, __FUNCTION__,
+ "error %d reading directory"
+ " #%lu offset %lu",
+ err, inode->i_ino, offset);
offset += sb->s_blocksize;
continue;
}
de = (struct ext3_dir_entry_2 *) bh->b_data;
}
- if (!ext3_check_dir_entry ("empty_dir", inode, de, bh,
- offset)) {
- brelse (bh);
- return 1;
+ if (!ext3_check_dir_entry("empty_dir", inode, de, bh, offset)) {
+ de = (struct ext3_dir_entry_2 *)(bh->b_data +
+ sb->s_blocksize);
+ offset = (offset | (sb->s_blocksize - 1)) + 1;
+ continue;
}
if (le32_to_cpu(de->inode)) {
brelse (bh);