Skip to content

Commit

Permalink
dir_index: error out instead of BUG on corrupt dx dirs
Browse files Browse the repository at this point in the history
Convert asserts (BUGs) in dx_probe from bad on-disk data to recoverable
errors with helpful warnings.  With help catching other asserts from Duane
Griffin <[email protected]>

Signed-off-by: Eric Sandeen <[email protected]>
Acked-by: Duane Griffin <[email protected]>
Acked-by: Theodore Ts'o <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Eric Sandeen authored and Linus Torvalds committed Sep 19, 2007
1 parent e67aa27 commit 3d82aba
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 8 deletions.
34 changes: 30 additions & 4 deletions fs/ext3/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,13 +379,28 @@ dx_probe(struct dentry *dentry, struct inode *dir,

entries = (struct dx_entry *) (((char *)&root->info) +
root->info.info_length);
assert(dx_get_limit(entries) == dx_root_limit(dir,
root->info.info_length));

if (dx_get_limit(entries) != dx_root_limit(dir,
root->info.info_length)) {
ext3_warning(dir->i_sb, __FUNCTION__,
"dx entry: limit != root limit");
brelse(bh);
*err = ERR_BAD_DX_DIR;
goto fail;
}

dxtrace (printk("Look up %x", hash));
while (1)
{
count = dx_get_count(entries);
assert (count && count <= dx_get_limit(entries));
if (!count || count > dx_get_limit(entries)) {
ext3_warning(dir->i_sb, __FUNCTION__,
"dx entry: no count or count > limit");
brelse(bh);
*err = ERR_BAD_DX_DIR;
goto fail2;
}

p = entries + 1;
q = entries + count - 1;
while (p <= q)
Expand Down Expand Up @@ -423,15 +438,26 @@ dx_probe(struct dentry *dentry, struct inode *dir,
if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err)))
goto fail2;
at = entries = ((struct dx_node *) bh->b_data)->entries;
assert (dx_get_limit(entries) == dx_node_limit (dir));
if (dx_get_limit(entries) != dx_node_limit (dir)) {
ext3_warning(dir->i_sb, __FUNCTION__,
"dx entry: limit != node limit");
brelse(bh);
*err = ERR_BAD_DX_DIR;
goto fail2;
}
frame++;
frame->bh = NULL;
}
fail2:
while (frame >= frame_in) {
brelse(frame->bh);
frame--;
}
fail:
if (*err == ERR_BAD_DX_DIR)
ext3_warning(dir->i_sb, __FUNCTION__,
"Corrupt dir inode %ld, running e2fsck is "
"recommended.", dir->i_ino);
return NULL;
}

Expand Down
34 changes: 30 additions & 4 deletions fs/ext4/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,13 +379,28 @@ dx_probe(struct dentry *dentry, struct inode *dir,

entries = (struct dx_entry *) (((char *)&root->info) +
root->info.info_length);
assert(dx_get_limit(entries) == dx_root_limit(dir,
root->info.info_length));

if (dx_get_limit(entries) != dx_root_limit(dir,
root->info.info_length)) {
ext4_warning(dir->i_sb, __FUNCTION__,
"dx entry: limit != root limit");
brelse(bh);
*err = ERR_BAD_DX_DIR;
goto fail;
}

dxtrace (printk("Look up %x", hash));
while (1)
{
count = dx_get_count(entries);
assert (count && count <= dx_get_limit(entries));
if (!count || count > dx_get_limit(entries)) {
ext4_warning(dir->i_sb, __FUNCTION__,
"dx entry: no count or count > limit");
brelse(bh);
*err = ERR_BAD_DX_DIR;
goto fail2;
}

p = entries + 1;
q = entries + count - 1;
while (p <= q)
Expand Down Expand Up @@ -423,15 +438,26 @@ dx_probe(struct dentry *dentry, struct inode *dir,
if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err)))
goto fail2;
at = entries = ((struct dx_node *) bh->b_data)->entries;
assert (dx_get_limit(entries) == dx_node_limit (dir));
if (dx_get_limit(entries) != dx_node_limit (dir)) {
ext4_warning(dir->i_sb, __FUNCTION__,
"dx entry: limit != node limit");
brelse(bh);
*err = ERR_BAD_DX_DIR;
goto fail2;
}
frame++;
frame->bh = NULL;
}
fail2:
while (frame >= frame_in) {
brelse(frame->bh);
frame--;
}
fail:
if (*err == ERR_BAD_DX_DIR)
ext4_warning(dir->i_sb, __FUNCTION__,
"Corrupt dir inode %ld, running e2fsck is "
"recommended.", dir->i_ino);
return NULL;
}

Expand Down

0 comments on commit 3d82aba

Please sign in to comment.