ext4: bail out from make_indexed_dir() on first error
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
This commit is contained in:
parent
d48458d4a7
commit
6050d47adc
1 changed files with 18 additions and 10 deletions
|
@ -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.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
|
||||||
hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
|
hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
|
||||||
ext4fs_dirhash(name, namelen, &hinfo);
|
ext4fs_dirhash(name, namelen, &hinfo);
|
||||||
|
memset(frames, 0, sizeof(frames));
|
||||||
frame = frames;
|
frame = frames;
|
||||||
frame->entries = entries;
|
frame->entries = entries;
|
||||||
frame->at = entries;
|
frame->at = entries;
|
||||||
frame->bh = bh;
|
frame->bh = bh;
|
||||||
bh = bh2;
|
bh = bh2;
|
||||||
|
|
||||||
ext4_handle_dirty_dx_node(handle, dir, frame->bh);
|
retval = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
|
||||||
ext4_handle_dirty_dirent_node(handle, dir, 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);
|
de = do_split(handle,dir, &bh, frame, &hinfo);
|
||||||
if (IS_ERR(de)) {
|
if (IS_ERR(de)) {
|
||||||
/*
|
retval = PTR_ERR(de);
|
||||||
* Even if the block split failed, we have to properly write
|
goto out_frames;
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
dx_release(frames);
|
dx_release(frames);
|
||||||
|
|
||||||
retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
|
retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
return retval;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue