[Devel] [RH7 PATCH] ext4: move ext4_truncate_data_csum out of transaction
Dmitry Monakhov
dmonakhov at openvz.org
Mon Jul 20 09:00:39 PDT 2015
ext4_truncate_data_csum implicitly require journal transatcion so it can not be
called inside opened transaction.
BAD_CHAIN-#1:
->generic_file_buffered_write_iter
->ext4_da_write_begin
->ext4_journal_start( ,,1) : reserve 1 journal block
->ext4_write_end
->ext4_update_data_csum
->ext4_truncate_data_csum
->ext4_xattr_set
->ext4_journal_start(,,20): require 20 blocks,
but since journal already started
it use existing handle
->jbd2_journal_dirty_metadata
J_ASSERT_JH(jh, handle->h_buffer_credits > 0) -> ASSERT
BAD_CHAIN-#2
ext4_evict_inode
->ext4_journal_start_sb
->ext4_truncate
->ext4_truncate_data_csum
->ext4_close_pfcache
->close_mapping_peer
->touch_atime
->update_time
->ext4_dirty_inode
->ext4_journal_start_sb -> start journal on another FS ->BUGON
Signed-off-by: Dmitry Monakhov <dmonakhov at openvz.org>
---
fs/ext4/inode.c | 2 ++
fs/ext4/pfcache.c | 3 +++
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 2b05910..30ae6b4 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -237,6 +237,8 @@ void ext4_evict_inode(struct inode *inode)
* protection against it
*/
sb_start_intwrite(inode->i_sb);
+ if (inode->i_blocks && ext4_test_inode_state(inode, EXT4_STATE_PFCACHE_CSUM))
+ ext4_truncate_data_csum(inode, inode->i_size);
handle = ext4_journal_start(inode, EXT4_HT_TRUNCATE,
ext4_blocks_for_truncate(inode)+3);
if (IS_ERR(handle)) {
diff --git a/fs/ext4/pfcache.c b/fs/ext4/pfcache.c
index bf45504..902bc0d 100644
--- a/fs/ext4/pfcache.c
+++ b/fs/ext4/pfcache.c
@@ -446,6 +446,8 @@ static int ext4_save_data_csum(struct inode *inode, u8 *csum)
{
int ret;
+ WARN_ON(journal_current_handle());
+
if (ext4_test_inode_state(inode, EXT4_STATE_PFCACHE_CSUM) &&
EXT4_I(inode)->i_data_csum_end < 0 &&
memcmp(EXT4_I(inode)->i_data_csum, csum, EXT4_DATA_CSUM_SIZE))
@@ -501,6 +503,7 @@ int ext4_truncate_data_csum(struct inode *inode, loff_t pos)
return 0;
if (EXT4_I(inode)->i_data_csum_end < 0) {
+ WARN_ON(journal_current_handle());
ext4_xattr_set(inode, EXT4_XATTR_INDEX_TRUSTED,
EXT4_DATA_CSUM_NAME, NULL, 0, 0);
ext4_close_pfcache(inode);
--
1.7.1
More information about the Devel
mailing list