aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-30 18:35:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-30 18:35:16 -0400
commit8c673cbc7682b3f2862fe42f8069cac20c09e160 (patch)
treef20de69903a1c3d95f92098e24139c69c2d6a894 /fs
parent4476c0eead051ae6ff8abbc358763b00790d1635 (diff)
parentffb5387e85d528fb6d0d924abfa3fbf0fc484071 (diff)
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 bugfix from Ted Ts'o: "This fixes the root cause of the ext4 data corruption bug which raised a ruckus on LWN, Phoronix, and Slashdot. This bug only showed up when non-standard mount options (journal_async_commit and/or journal_checksum) were enabled, and when the file system was not cleanly unmounted, but the root cause was the inode bitmap modifications was not being properly journaled. This could potentially lead to minor file system corruptions (pass 5 complaints with the inode allocation bitmap) after an unclean shutdown under the wrong/unlucky workloads, but it turned into major failure if the journal_checksum and/or jouaral_async_commit was enabled." * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: fix unjournaled inode bitmap modification
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/ialloc.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 4facdd29a350..3a100e7a62a8 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -725,6 +725,10 @@ repeat_in_this_group:
725 "inode=%lu", ino + 1); 725 "inode=%lu", ino + 1);
726 continue; 726 continue;
727 } 727 }
728 BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
729 err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
730 if (err)
731 goto fail;
728 ext4_lock_group(sb, group); 732 ext4_lock_group(sb, group);
729 ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data); 733 ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data);
730 ext4_unlock_group(sb, group); 734 ext4_unlock_group(sb, group);
@@ -738,6 +742,11 @@ repeat_in_this_group:
738 goto out; 742 goto out;
739 743
740got: 744got:
745 BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata");
746 err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh);
747 if (err)
748 goto fail;
749
741 /* We may have to initialize the block bitmap if it isn't already */ 750 /* We may have to initialize the block bitmap if it isn't already */
742 if (ext4_has_group_desc_csum(sb) && 751 if (ext4_has_group_desc_csum(sb) &&
743 gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 752 gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
@@ -771,11 +780,6 @@ got:
771 goto fail; 780 goto fail;
772 } 781 }
773 782
774 BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
775 err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
776 if (err)
777 goto fail;
778
779 BUFFER_TRACE(group_desc_bh, "get_write_access"); 783 BUFFER_TRACE(group_desc_bh, "get_write_access");
780 err = ext4_journal_get_write_access(handle, group_desc_bh); 784 err = ext4_journal_get_write_access(handle, group_desc_bh);
781 if (err) 785 if (err)
@@ -823,11 +827,6 @@ got:
823 } 827 }
824 ext4_unlock_group(sb, group); 828 ext4_unlock_group(sb, group);
825 829
826 BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata");
827 err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh);
828 if (err)
829 goto fail;
830
831 BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata"); 830 BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata");
832 err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh); 831 err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh);
833 if (err) 832 if (err)