Skip to content

Commit

Permalink
ext4: bail out from make_indexed_dir() on first error
Browse files Browse the repository at this point in the history
When ext4_handle_dirty_dx_node() or ext4_handle_dirty_dirent_node()
fail, there's really something wrong with the fs and there's no point in
continuing further. Just return error from make_indexed_dir() in that
case. Also initialize frames array so that if we return early due to
error, dx_release() doesn't try to dereference uninitialized memory
(which could happen also due to error in do_split()).

Coverity-id: 741300
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@vger.kernel.org
  • Loading branch information
Jan Kara authored and Theodore Ts'o committed Oct 30, 2014
1 parent d48458d commit 6050d47
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions fs/ext4/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1816,31 +1816,39 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
ext4fs_dirhash(name, namelen, &hinfo);
memset(frames, 0, sizeof(frames));
frame = frames;
frame->entries = entries;
frame->at = entries;
frame->bh = bh;
bh = bh2;

ext4_handle_dirty_dx_node(handle, dir, frame->bh);
ext4_handle_dirty_dirent_node(handle, dir, bh);
retval = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
if (retval)
goto out_frames;
retval = ext4_handle_dirty_dirent_node(handle, dir, bh);
if (retval)
goto out_frames;

de = do_split(handle,dir, &bh, frame, &hinfo);
if (IS_ERR(de)) {
/*
* Even if the block split failed, we have to properly write
* out all the changes we did so far. Otherwise we can end up
* with corrupted filesystem.
*/
ext4_mark_inode_dirty(handle, dir);
dx_release(frames);
return PTR_ERR(de);
retval = PTR_ERR(de);
goto out_frames;
}
dx_release(frames);

retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
brelse(bh);
return retval;
out_frames:
/*
* Even if the block split failed, we have to properly write
* out all the changes we did so far. Otherwise we can end up
* with corrupted filesystem.
*/
ext4_mark_inode_dirty(handle, dir);
dx_release(frames);
return retval;
}

/*
Expand Down

0 comments on commit 6050d47

Please sign in to comment.