diff options
-rw-r--r-- | fs/ocfs2/alloc.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index f5d2bd15e0ca..f9baefc76cf9 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -5993,6 +5993,7 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
5993 | struct buffer_head *data_alloc_bh = NULL; | 5993 | struct buffer_head *data_alloc_bh = NULL; |
5994 | struct ocfs2_dinode *di; | 5994 | struct ocfs2_dinode *di; |
5995 | struct ocfs2_truncate_log *tl; | 5995 | struct ocfs2_truncate_log *tl; |
5996 | struct ocfs2_journal *journal = osb->journal; | ||
5996 | 5997 | ||
5997 | BUG_ON(inode_trylock(tl_inode)); | 5998 | BUG_ON(inode_trylock(tl_inode)); |
5998 | 5999 | ||
@@ -6013,6 +6014,20 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
6013 | goto out; | 6014 | goto out; |
6014 | } | 6015 | } |
6015 | 6016 | ||
6017 | /* Appending truncate log(TA) and and flushing truncate log(TF) are | ||
6018 | * two separated transactions. They can be both committed but not | ||
6019 | * checkpointed. If crash occurs then, both two transaction will be | ||
6020 | * replayed with several already released to global bitmap clusters. | ||
6021 | * Then truncate log will be replayed resulting in cluster double free. | ||
6022 | */ | ||
6023 | jbd2_journal_lock_updates(journal->j_journal); | ||
6024 | status = jbd2_journal_flush(journal->j_journal); | ||
6025 | jbd2_journal_unlock_updates(journal->j_journal); | ||
6026 | if (status < 0) { | ||
6027 | mlog_errno(status); | ||
6028 | goto out; | ||
6029 | } | ||
6030 | |||
6016 | data_alloc_inode = ocfs2_get_system_file_inode(osb, | 6031 | data_alloc_inode = ocfs2_get_system_file_inode(osb, |
6017 | GLOBAL_BITMAP_SYSTEM_INODE, | 6032 | GLOBAL_BITMAP_SYSTEM_INODE, |
6018 | OCFS2_INVALID_SLOT); | 6033 | OCFS2_INVALID_SLOT); |