diff options
author | Namhyung Kim <namhyung@gmail.com> | 2010-11-16 06:18:12 -0500 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2011-01-06 05:52:14 -0500 |
commit | 2b543edae2d9161ae8dda1d85cbd28ef8a166cc0 (patch) | |
tree | 307deb77e93a73543b280210e02fcceca21ec29b /fs/ext3/namei.c | |
parent | 99fbb1e2af5da27d3ee75c2e421712fe9d083fb6 (diff) |
ext3: Add error check in ext3_mkdir()
Check return value of ext3_journal_get_write_access, ext3_journal_dirty_metadata
and ext3_mark_inode_dirty. Consolidate error path under new label 'out_clear_inode'
and adjust bh releasing appropriately.
Signed-off-by: Namhyung Kim <namhyung@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext3/namei.c')
-rw-r--r-- | fs/ext3/namei.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index bce9dce639b8..03fccc573333 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -1762,7 +1762,7 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
1762 | { | 1762 | { |
1763 | handle_t *handle; | 1763 | handle_t *handle; |
1764 | struct inode * inode; | 1764 | struct inode * inode; |
1765 | struct buffer_head * dir_block; | 1765 | struct buffer_head * dir_block = NULL; |
1766 | struct ext3_dir_entry_2 * de; | 1766 | struct ext3_dir_entry_2 * de; |
1767 | int err, retries = 0; | 1767 | int err, retries = 0; |
1768 | 1768 | ||
@@ -1790,15 +1790,14 @@ retry: | |||
1790 | inode->i_fop = &ext3_dir_operations; | 1790 | inode->i_fop = &ext3_dir_operations; |
1791 | inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; | 1791 | inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; |
1792 | dir_block = ext3_bread (handle, inode, 0, 1, &err); | 1792 | dir_block = ext3_bread (handle, inode, 0, 1, &err); |
1793 | if (!dir_block) { | 1793 | if (!dir_block) |
1794 | drop_nlink(inode); /* is this nlink == 0? */ | 1794 | goto out_clear_inode; |
1795 | unlock_new_inode(inode); | 1795 | |
1796 | ext3_mark_inode_dirty(handle, inode); | ||
1797 | iput (inode); | ||
1798 | goto out_stop; | ||
1799 | } | ||
1800 | BUFFER_TRACE(dir_block, "get_write_access"); | 1796 | BUFFER_TRACE(dir_block, "get_write_access"); |
1801 | ext3_journal_get_write_access(handle, dir_block); | 1797 | err = ext3_journal_get_write_access(handle, dir_block); |
1798 | if (err) | ||
1799 | goto out_clear_inode; | ||
1800 | |||
1802 | de = (struct ext3_dir_entry_2 *) dir_block->b_data; | 1801 | de = (struct ext3_dir_entry_2 *) dir_block->b_data; |
1803 | de->inode = cpu_to_le32(inode->i_ino); | 1802 | de->inode = cpu_to_le32(inode->i_ino); |
1804 | de->name_len = 1; | 1803 | de->name_len = 1; |
@@ -1814,11 +1813,16 @@ retry: | |||
1814 | ext3_set_de_type(dir->i_sb, de, S_IFDIR); | 1813 | ext3_set_de_type(dir->i_sb, de, S_IFDIR); |
1815 | inode->i_nlink = 2; | 1814 | inode->i_nlink = 2; |
1816 | BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); | 1815 | BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); |
1817 | ext3_journal_dirty_metadata(handle, dir_block); | 1816 | err = ext3_journal_dirty_metadata(handle, dir_block); |
1818 | brelse (dir_block); | 1817 | if (err) |
1819 | ext3_mark_inode_dirty(handle, inode); | 1818 | goto out_clear_inode; |
1820 | err = ext3_add_entry (handle, dentry, inode); | 1819 | |
1820 | err = ext3_mark_inode_dirty(handle, inode); | ||
1821 | if (!err) | ||
1822 | err = ext3_add_entry (handle, dentry, inode); | ||
1823 | |||
1821 | if (err) { | 1824 | if (err) { |
1825 | out_clear_inode: | ||
1822 | inode->i_nlink = 0; | 1826 | inode->i_nlink = 0; |
1823 | unlock_new_inode(inode); | 1827 | unlock_new_inode(inode); |
1824 | ext3_mark_inode_dirty(handle, inode); | 1828 | ext3_mark_inode_dirty(handle, inode); |
@@ -1827,10 +1831,14 @@ retry: | |||
1827 | } | 1831 | } |
1828 | inc_nlink(dir); | 1832 | inc_nlink(dir); |
1829 | ext3_update_dx_flag(dir); | 1833 | ext3_update_dx_flag(dir); |
1830 | ext3_mark_inode_dirty(handle, dir); | 1834 | err = ext3_mark_inode_dirty(handle, dir); |
1835 | if (err) | ||
1836 | goto out_clear_inode; | ||
1837 | |||
1831 | d_instantiate(dentry, inode); | 1838 | d_instantiate(dentry, inode); |
1832 | unlock_new_inode(inode); | 1839 | unlock_new_inode(inode); |
1833 | out_stop: | 1840 | out_stop: |
1841 | brelse(dir_block); | ||
1834 | ext3_journal_stop(handle); | 1842 | ext3_journal_stop(handle); |
1835 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) | 1843 | if (err == -ENOSPC && ext3_should_retry_alloc(dir->i_sb, &retries)) |
1836 | goto retry; | 1844 | goto retry; |