aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorMingming Cao <cmm@us.ibm.com>2008-07-11 19:27:31 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-07-11 19:27:31 -0400
commit61628a3f3a37af2bf25daf8e26fd6b76a78c4f76 (patch)
tree25375b739b2e3f65c8dff3d3dd2a78e0724d0f96 /fs/ext4/extents.c
parent06d6cf6959d22037fcec598f4f954db5db3d7356 (diff)
ext4: Invert lock ordering of page_lock and transaction start in delalloc
With the reverse locking, we need to start a transation before taking the page lock, so in ext4_da_writepages() we need to break the write-out into chunks, and restart the journal for each chunck to ensure the write-out fits in a single transaction. Updated patch from Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> which fixes delalloc sync hang with journal lock inversion, and address the performance regression issue. 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: Jan Kara <jack@suse.cz> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index dabc3b68d249..42c4c0c892ed 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2565,6 +2565,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2565 int err = 0, depth, ret; 2565 int err = 0, depth, ret;
2566 unsigned long allocated = 0; 2566 unsigned long allocated = 0;
2567 struct ext4_allocation_request ar; 2567 struct ext4_allocation_request ar;
2568 loff_t disksize;
2568 2569
2569 __clear_bit(BH_New, &bh_result->b_state); 2570 __clear_bit(BH_New, &bh_result->b_state);
2570 ext_debug("blocks %u/%lu requested for inode %u\n", 2571 ext_debug("blocks %u/%lu requested for inode %u\n",
@@ -2755,8 +2756,13 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2755 newblock = ext_pblock(&newex); 2756 newblock = ext_pblock(&newex);
2756 allocated = ext4_ext_get_actual_len(&newex); 2757 allocated = ext4_ext_get_actual_len(&newex);
2757outnew: 2758outnew:
2758 if (extend_disksize && inode->i_size > EXT4_I(inode)->i_disksize) 2759 if (extend_disksize) {
2759 EXT4_I(inode)->i_disksize = inode->i_size; 2760 disksize = ((loff_t) iblock + ar.len) << inode->i_blkbits;
2761 if (disksize > i_size_read(inode))
2762 disksize = i_size_read(inode);
2763 if (disksize > EXT4_I(inode)->i_disksize)
2764 EXT4_I(inode)->i_disksize = disksize;
2765 }
2760 2766
2761 set_buffer_new(bh_result); 2767 set_buffer_new(bh_result);
2762 2768