aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@gmail.com>2010-11-16 06:18:12 -0500
committerJan Kara <jack@suse.cz>2011-01-06 05:52:14 -0500
commit2b543edae2d9161ae8dda1d85cbd28ef8a166cc0 (patch)
tree307deb77e93a73543b280210e02fcceca21ec29b /fs/ext3
parent99fbb1e2af5da27d3ee75c2e421712fe9d083fb6 (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')
-rw-r--r--fs/ext3/namei.c36
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) {
1825out_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);
1833out_stop: 1840out_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;