ext4: Fix potential truncate BUG due to i_prealloc_list being non-empty
authorTheodore Ts'o <tytso@mit.edu>
Thu, 14 Aug 2008 01:44:34 +0000 (21:44 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 14 Aug 2008 01:44:34 +0000 (21:44 -0400)
We need to call ext4_discard_reservation() earlier in ext4_truncate(),
to avoid a BUG() in ext4_mb_return_to_preallocation(), which is called
(ultimately) by ext4_free_blocks().  So we must ditch the blocks on
i_prealloc_list before we start freeing the data blocks.

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

index a1c7d7623213ee9dd680c810a2668ea54c158200..2d54c822c4c3f65b09b7caec7bccd336fd0a3faf 100644 (file)
@@ -3494,6 +3494,9 @@ void ext4_truncate(struct inode *inode)
         * modify the block allocation tree.
         */
        down_write(&ei->i_data_sem);
+
+       ext4_discard_reservation(inode);
+
        /*
         * The orphan list entry will now protect us from any crash which
         * occurs before the truncate completes, so it is now safe to propagate
@@ -3563,8 +3566,6 @@ do_indirects:
                ;
        }
 
-       ext4_discard_reservation(inode);
-
        up_write(&ei->i_data_sem);
        inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
        ext4_mark_inode_dirty(handle, inode);