| From 64cb927371cd2ec43758d8a094a003d27bc3d0dc Mon Sep 17 00:00:00 2001 |
| From: Al Viro <viro@ZenIV.linux.org.uk> |
| Date: Mon, 1 Jul 2013 08:12:38 -0400 |
| Subject: ext3,ext4: don't mess with dir_file->f_pos in htree_dirblock_to_tree() |
| |
| From: Al Viro <viro@ZenIV.linux.org.uk> |
| |
| commit 64cb927371cd2ec43758d8a094a003d27bc3d0dc upstream. |
| |
| Both ext3 and ext4 htree_dirblock_to_tree() is just filling the |
| in-core rbtree for use by call_filldir(). All updates of ->f_pos are |
| done by the latter; bumping it here (on error) is obviously wrong - we |
| might very well have it nowhere near the block we'd found an error in. |
| |
| Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> |
| Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/ext3/namei.c | 7 ++----- |
| fs/ext4/namei.c | 7 ++----- |
| 2 files changed, 4 insertions(+), 10 deletions(-) |
| |
| --- a/fs/ext3/namei.c |
| +++ b/fs/ext3/namei.c |
| @@ -576,11 +576,8 @@ static int htree_dirblock_to_tree(struct |
| if (!ext3_check_dir_entry("htree_dirblock_to_tree", dir, de, bh, |
| (block<<EXT3_BLOCK_SIZE_BITS(dir->i_sb)) |
| +((char *)de - bh->b_data))) { |
| - /* On error, skip the f_pos to the next block. */ |
| - dir_file->f_pos = (dir_file->f_pos | |
| - (dir->i_sb->s_blocksize - 1)) + 1; |
| - brelse (bh); |
| - return count; |
| + /* silently ignore the rest of the block */ |
| + break; |
| } |
| ext3fs_dirhash(de->name, de->name_len, hinfo); |
| if ((hinfo->hash < start_hash) || |
| --- a/fs/ext4/namei.c |
| +++ b/fs/ext4/namei.c |
| @@ -917,11 +917,8 @@ static int htree_dirblock_to_tree(struct |
| bh->b_data, bh->b_size, |
| (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb)) |
| + ((char *)de - bh->b_data))) { |
| - /* On error, skip the f_pos to the next block. */ |
| - dir_file->f_pos = (dir_file->f_pos | |
| - (dir->i_sb->s_blocksize - 1)) + 1; |
| - brelse(bh); |
| - return count; |
| + /* silently ignore the rest of the block */ |
| + break; |
| } |
| ext4fs_dirhash(de->name, de->name_len, hinfo); |
| if ((hinfo->hash < start_hash) || |