diff options
author | Mingming Cao <cmm@us.ibm.com> | 2008-07-11 19:27:31 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-07-11 19:27:31 -0400 |
commit | 61628a3f3a37af2bf25daf8e26fd6b76a78c4f76 (patch) | |
tree | 25375b739b2e3f65c8dff3d3dd2a78e0724d0f96 /fs/ext4/extents.c | |
parent | 06d6cf6959d22037fcec598f4f954db5db3d7356 (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.c | 10 |
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); |
2757 | outnew: | 2758 | outnew: |
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 | ||