aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2014-10-30 10:53:17 -0400
committerTheodore Ts'o <tytso@mit.edu>2014-10-30 10:53:17 -0400
commit6050d47adcadbb53582434d919ed7f038d936712 (patch)
tree25fdc7507203649d82fdd1c943b1e70ac2cb6722 /fs
parentd48458d4a768cece43f80a081a26cf912877da9c (diff)
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
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/namei.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 123798c5ac31..426211882f72 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1816,31 +1816,39 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
1816 hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned; 1816 hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
1817 hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; 1817 hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
1818 ext4fs_dirhash(name, namelen, &hinfo); 1818 ext4fs_dirhash(name, namelen, &hinfo);
1819 memset(frames, 0, sizeof(frames));
1819 frame = frames; 1820 frame = frames;
1820 frame->entries = entries; 1821 frame->entries = entries;
1821 frame->at = entries; 1822 frame->at = entries;
1822 frame->bh = bh; 1823 frame->bh = bh;
1823 bh = bh2; 1824 bh = bh2;
1824 1825
1825 ext4_handle_dirty_dx_node(handle, dir, frame->bh); 1826 retval = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
1826 ext4_handle_dirty_dirent_node(handle, dir, bh); 1827 if (retval)
1828 goto out_frames;
1829 retval = ext4_handle_dirty_dirent_node(handle, dir, bh);
1830 if (retval)
1831 goto out_frames;
1827 1832
1828 de = do_split(handle,dir, &bh, frame, &hinfo); 1833 de = do_split(handle,dir, &bh, frame, &hinfo);
1829 if (IS_ERR(de)) { 1834 if (IS_ERR(de)) {
1830 /* 1835 retval = PTR_ERR(de);
1831 * Even if the block split failed, we have to properly write 1836 goto out_frames;
1832 * out all the changes we did so far. Otherwise we can end up
1833 * with corrupted filesystem.
1834 */
1835 ext4_mark_inode_dirty(handle, dir);
1836 dx_release(frames);
1837 return PTR_ERR(de);
1838 } 1837 }
1839 dx_release(frames); 1838 dx_release(frames);
1840 1839
1841 retval = add_dirent_to_buf(handle, dentry, inode, de, bh); 1840 retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
1842 brelse(bh); 1841 brelse(bh);
1843 return retval; 1842 return retval;
1843out_frames:
1844 /*
1845 * Even if the block split failed, we have to properly write
1846 * out all the changes we did so far. Otherwise we can end up
1847 * with corrupted filesystem.
1848 */
1849 ext4_mark_inode_dirty(handle, dir);
1850 dx_release(frames);
1851 return retval;
1844} 1852}
1845 1853
1846/* 1854/*