ext4: allocate delalloc blocks before changing journal mode
authorYongqiang Yang <xiaoqiangnk@gmail.com>
Wed, 28 Dec 2011 17:02:13 +0000 (12:02 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Wed, 28 Dec 2011 17:02:13 +0000 (12:02 -0500)
delalloc blocks should be allocated before changing journal mode,
otherwise they can not be allocated and even more truncate on
delalloc blocks could triggre BUG by flushing delalloc buffers.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
fs/ext4/inode.c

index 92655fd8965737bac9aa002f173ed607ecdcfa8a..cb0ba9d77a8ecb223384a7fe4c3b8513809ffbaf 100644 (file)
@@ -4647,6 +4647,17 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
                return 0;
        if (is_journal_aborted(journal))
                return -EROFS;
+       /* We have to allocate physical blocks for delalloc blocks
+        * before flushing journal. otherwise delalloc blocks can not
+        * be allocated any more. even more truncate on delalloc blocks
+        * could trigger BUG by flushing delalloc blocks in journal.
+        * There is no delalloc block in non-journal data mode.
+        */
+       if (val && test_opt(inode->i_sb, DELALLOC)) {
+               err = ext4_alloc_da_blocks(inode);
+               if (err < 0)
+                       return err;
+       }
 
        jbd2_journal_lock_updates(journal);
        jbd2_journal_flush(journal);