aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-07-11 19:27:31 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-07-11 19:27:31 -0400
commitcf108bca465dde0c015f32dd453b99457d31c7c7 (patch)
treeb1c9dfc1936579e4fd2a48f77f702effc39029e2 /fs/ext4/extents.c
parentc7d206b3379f7d6462e778b74f475c470ee3dcaf (diff)
ext4: Invert the locking order of page_lock and transaction start
This changes are needed to support data=ordered mode handling via inodes. This enables us to get rid of the journal heads and buffer heads for data buffers in the ordered mode. With the changes, during tranasaction commit we writeout the inode pages using the writepages()/writepage(). That implies we take page lock during transaction commit. This can cause a deadlock with the locking order page_lock -> jbd2_journal_start, since the jbd2_journal_start can wait for the journal_commit to happen and the journal_commit now needs to take the page lock. To avoid this dead lock reverse the locking order. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Mingming Cao <cmm@us.ibm.com> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c15
1 files changed, 4 insertions, 11 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index bb36a28f8ff3..b722bce7d662 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2749,7 +2749,7 @@ out2:
2749 return err ? err : allocated; 2749 return err ? err : allocated;
2750} 2750}
2751 2751
2752void ext4_ext_truncate(struct inode * inode, struct page *page) 2752void ext4_ext_truncate(struct inode *inode)
2753{ 2753{
2754 struct address_space *mapping = inode->i_mapping; 2754 struct address_space *mapping = inode->i_mapping;
2755 struct super_block *sb = inode->i_sb; 2755 struct super_block *sb = inode->i_sb;
@@ -2762,18 +2762,11 @@ void ext4_ext_truncate(struct inode * inode, struct page *page)
2762 */ 2762 */
2763 err = ext4_writepage_trans_blocks(inode) + 3; 2763 err = ext4_writepage_trans_blocks(inode) + 3;
2764 handle = ext4_journal_start(inode, err); 2764 handle = ext4_journal_start(inode, err);
2765 if (IS_ERR(handle)) { 2765 if (IS_ERR(handle))
2766 if (page) {
2767 clear_highpage(page);
2768 flush_dcache_page(page);
2769 unlock_page(page);
2770 page_cache_release(page);
2771 }
2772 return; 2766 return;
2773 }
2774 2767
2775 if (page) 2768 if (inode->i_size & (sb->s_blocksize - 1))
2776 ext4_block_truncate_page(handle, page, mapping, inode->i_size); 2769 ext4_block_truncate_page(handle, mapping, inode->i_size);
2777 2770
2778 down_write(&EXT4_I(inode)->i_data_sem); 2771 down_write(&EXT4_I(inode)->i_data_sem);
2779 ext4_ext_invalidate_cache(inode); 2772 ext4_ext_invalidate_cache(inode);