ocfs2: checkpoint appending truncate log transaction before flushing
[linux-2.6-microblaze.git] / fs / ocfs2 / alloc.c
index f5d2bd1..f9baefc 100644 (file)
@@ -5993,6 +5993,7 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
        struct buffer_head *data_alloc_bh = NULL;
        struct ocfs2_dinode *di;
        struct ocfs2_truncate_log *tl;
+       struct ocfs2_journal *journal = osb->journal;
 
        BUG_ON(inode_trylock(tl_inode));
 
@@ -6013,6 +6014,20 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
                goto out;
        }
 
+       /* Appending truncate log(TA) and and flushing truncate log(TF) are
+        * two separated transactions. They can be both committed but not
+        * checkpointed. If crash occurs then, both two transaction will be
+        * replayed with several already released to global bitmap clusters.
+        * Then truncate log will be replayed resulting in cluster double free.
+        */
+       jbd2_journal_lock_updates(journal->j_journal);
+       status = jbd2_journal_flush(journal->j_journal);
+       jbd2_journal_unlock_updates(journal->j_journal);
+       if (status < 0) {
+               mlog_errno(status);
+               goto out;
+       }
+
        data_alloc_inode = ocfs2_get_system_file_inode(osb,
                                                       GLOBAL_BITMAP_SYSTEM_INODE,
                                                       OCFS2_INVALID_SLOT);