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 | |
| 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>
| -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; |
