aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3/inode.c')
-rw-r--r--fs/ext3/inode.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index b49908a167ae..acf1b1423327 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -172,10 +172,21 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
172 * so before we call here everything must be consistently dirtied against 172 * so before we call here everything must be consistently dirtied against
173 * this transaction. 173 * this transaction.
174 */ 174 */
175static int ext3_journal_test_restart(handle_t *handle, struct inode *inode) 175static int truncate_restart_transaction(handle_t *handle, struct inode *inode)
176{ 176{
177 int ret;
178
177 jbd_debug(2, "restarting handle %p\n", handle); 179 jbd_debug(2, "restarting handle %p\n", handle);
178 return ext3_journal_restart(handle, blocks_for_truncate(inode)); 180 /*
181 * Drop truncate_mutex to avoid deadlock with ext3_get_blocks_handle
182 * At this moment, get_block can be called only for blocks inside
183 * i_size since page cache has been already dropped and writes are
184 * blocked by i_mutex. So we can safely drop the truncate_mutex.
185 */
186 mutex_unlock(&EXT3_I(inode)->truncate_mutex);
187 ret = ext3_journal_restart(handle, blocks_for_truncate(inode));
188 mutex_lock(&EXT3_I(inode)->truncate_mutex);
189 return ret;
179} 190}
180 191
181/* 192/*
@@ -1819,6 +1830,7 @@ static const struct address_space_operations ext3_ordered_aops = {
1819 .direct_IO = ext3_direct_IO, 1830 .direct_IO = ext3_direct_IO,
1820 .migratepage = buffer_migrate_page, 1831 .migratepage = buffer_migrate_page,
1821 .is_partially_uptodate = block_is_partially_uptodate, 1832 .is_partially_uptodate = block_is_partially_uptodate,
1833 .error_remove_page = generic_error_remove_page,
1822}; 1834};
1823 1835
1824static const struct address_space_operations ext3_writeback_aops = { 1836static const struct address_space_operations ext3_writeback_aops = {
@@ -1834,6 +1846,7 @@ static const struct address_space_operations ext3_writeback_aops = {
1834 .direct_IO = ext3_direct_IO, 1846 .direct_IO = ext3_direct_IO,
1835 .migratepage = buffer_migrate_page, 1847 .migratepage = buffer_migrate_page,
1836 .is_partially_uptodate = block_is_partially_uptodate, 1848 .is_partially_uptodate = block_is_partially_uptodate,
1849 .error_remove_page = generic_error_remove_page,
1837}; 1850};
1838 1851
1839static const struct address_space_operations ext3_journalled_aops = { 1852static const struct address_space_operations ext3_journalled_aops = {
@@ -1848,6 +1861,7 @@ static const struct address_space_operations ext3_journalled_aops = {
1848 .invalidatepage = ext3_invalidatepage, 1861 .invalidatepage = ext3_invalidatepage,
1849 .releasepage = ext3_releasepage, 1862 .releasepage = ext3_releasepage,
1850 .is_partially_uptodate = block_is_partially_uptodate, 1863 .is_partially_uptodate = block_is_partially_uptodate,
1864 .error_remove_page = generic_error_remove_page,
1851}; 1865};
1852 1866
1853void ext3_set_aops(struct inode *inode) 1867void ext3_set_aops(struct inode *inode)
@@ -2072,7 +2086,7 @@ static void ext3_clear_blocks(handle_t *handle, struct inode *inode,
2072 ext3_journal_dirty_metadata(handle, bh); 2086 ext3_journal_dirty_metadata(handle, bh);
2073 } 2087 }
2074 ext3_mark_inode_dirty(handle, inode); 2088 ext3_mark_inode_dirty(handle, inode);
2075 ext3_journal_test_restart(handle, inode); 2089 truncate_restart_transaction(handle, inode);
2076 if (bh) { 2090 if (bh) {
2077 BUFFER_TRACE(bh, "retaking write access"); 2091 BUFFER_TRACE(bh, "retaking write access");
2078 ext3_journal_get_write_access(handle, bh); 2092 ext3_journal_get_write_access(handle, bh);
@@ -2282,7 +2296,7 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode,
2282 return; 2296 return;
2283 if (try_to_extend_transaction(handle, inode)) { 2297 if (try_to_extend_transaction(handle, inode)) {
2284 ext3_mark_inode_dirty(handle, inode); 2298 ext3_mark_inode_dirty(handle, inode);
2285 ext3_journal_test_restart(handle, inode); 2299 truncate_restart_transaction(handle, inode);
2286 } 2300 }
2287 2301
2288 ext3_free_blocks(handle, inode, nr, 1); 2302 ext3_free_blocks(handle, inode, nr, 1);
@@ -2892,6 +2906,10 @@ static int ext3_do_update_inode(handle_t *handle,
2892 struct buffer_head *bh = iloc->bh; 2906 struct buffer_head *bh = iloc->bh;
2893 int err = 0, rc, block; 2907 int err = 0, rc, block;
2894 2908
2909again:
2910 /* we can't allow multiple procs in here at once, its a bit racey */
2911 lock_buffer(bh);
2912
2895 /* For fields not not tracking in the in-memory inode, 2913 /* For fields not not tracking in the in-memory inode,
2896 * initialise them to zero for new inodes. */ 2914 * initialise them to zero for new inodes. */
2897 if (ei->i_state & EXT3_STATE_NEW) 2915 if (ei->i_state & EXT3_STATE_NEW)
@@ -2951,16 +2969,20 @@ static int ext3_do_update_inode(handle_t *handle,
2951 /* If this is the first large file 2969 /* If this is the first large file
2952 * created, add a flag to the superblock. 2970 * created, add a flag to the superblock.
2953 */ 2971 */
2972 unlock_buffer(bh);
2954 err = ext3_journal_get_write_access(handle, 2973 err = ext3_journal_get_write_access(handle,
2955 EXT3_SB(sb)->s_sbh); 2974 EXT3_SB(sb)->s_sbh);
2956 if (err) 2975 if (err)
2957 goto out_brelse; 2976 goto out_brelse;
2977
2958 ext3_update_dynamic_rev(sb); 2978 ext3_update_dynamic_rev(sb);
2959 EXT3_SET_RO_COMPAT_FEATURE(sb, 2979 EXT3_SET_RO_COMPAT_FEATURE(sb,
2960 EXT3_FEATURE_RO_COMPAT_LARGE_FILE); 2980 EXT3_FEATURE_RO_COMPAT_LARGE_FILE);
2961 handle->h_sync = 1; 2981 handle->h_sync = 1;
2962 err = ext3_journal_dirty_metadata(handle, 2982 err = ext3_journal_dirty_metadata(handle,
2963 EXT3_SB(sb)->s_sbh); 2983 EXT3_SB(sb)->s_sbh);
2984 /* get our lock and start over */
2985 goto again;
2964 } 2986 }
2965 } 2987 }
2966 } 2988 }
@@ -2983,6 +3005,7 @@ static int ext3_do_update_inode(handle_t *handle,
2983 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); 3005 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
2984 3006
2985 BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); 3007 BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
3008 unlock_buffer(bh);
2986 rc = ext3_journal_dirty_metadata(handle, bh); 3009 rc = ext3_journal_dirty_metadata(handle, bh);
2987 if (!err) 3010 if (!err)
2988 err = rc; 3011 err = rc;