summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/alloc.c15
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);