From: Greg Kroah-Hartman Date: Wed, 3 Dec 2008 18:55:16 +0000 (-0800) Subject: lots of ext4 and some ext3 and one ext2 patch for 2.6.27 X-Git-Tag: v2.6.27.10~27 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e9e6fa2ce544aae708c3f9c16a667417714cb55f;p=thirdparty%2Fkernel%2Fstable-queue.git lots of ext4 and some ext3 and one ext2 patch for 2.6.27 --- diff --git a/queue-2.6.27/ext2-fix-ext2-block-reservation-early-enospc-issue.patch b/queue-2.6.27/ext2-fix-ext2-block-reservation-early-enospc-issue.patch new file mode 100644 index 00000000000..517c1da38fd --- /dev/null +++ b/queue-2.6.27/ext2-fix-ext2-block-reservation-early-enospc-issue.patch @@ -0,0 +1,64 @@ +From d707d31c972b657dfc2efefd0b99cc4e14223dab Mon Sep 17 00:00:00 2001 +From: Mingming Cao +Date: Wed, 15 Oct 2008 22:04:01 -0700 +Subject: ext2: fix ext2 block reservation early ENOSPC issue + +From: Mingming Cao + +commit d707d31c972b657dfc2efefd0b99cc4e14223dab upstream. + +We could run into ENOSPC error on ext2, even when there is free blocks on +the filesystem. + +The problem is triggered in the case the goal block group has 0 free +blocks , and the rest block groups are skipped due to the check of +"free_blocks < windowsz/2". Current code could fall back to non +reservation allocation to prevent early ENOSPC after examing all the block +groups with reservation on , but this code was bypassed if the reservation +window is turned off already, which is true in this case. + +This patch fixed two issues: +1) We don't need to turn off block reservation if the goal block group has +0 free blocks left and continue search for the rest of block groups. + +Current code the intention is to turn off the block reservation if the +goal allocation group has a few (some) free blocks left (not enough for +make the desired reservation window),to try to allocation in the goal +block group, to get better locality. But if the goal blocks have 0 free +blocks, it should leave the block reservation on, and continues search for +the next block groups,rather than turn off block reservation completely. + +2) we don't need to check the window size if the block reservation is off. + +The problem was originally found and fixed in ext4. + +Signed-off-by: Mingming Cao +Cc: Theodore Ts'o +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Willy Tarreau +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext2/balloc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ext2/balloc.c ++++ b/fs/ext2/balloc.c +@@ -1295,6 +1295,7 @@ retry_alloc: + * turn off reservation for this allocation + */ + if (my_rsv && (free_blocks < windowsz) ++ && (free_blocks > 0) + && (rsv_is_empty(&my_rsv->rsv_window))) + my_rsv = NULL; + +@@ -1332,7 +1333,7 @@ retry_alloc: + * free blocks is less than half of the reservation + * window size. + */ +- if (free_blocks <= (windowsz/2)) ++ if (my_rsv && (free_blocks <= (windowsz/2))) + continue; + + brelse(bitmap_bh); diff --git a/queue-2.6.27/ext3-don-t-try-to-resize-if-there-are-no-reserved-gdt-blocks-left.patch b/queue-2.6.27/ext3-don-t-try-to-resize-if-there-are-no-reserved-gdt-blocks-left.patch new file mode 100644 index 00000000000..664a1cb56ee --- /dev/null +++ b/queue-2.6.27/ext3-don-t-try-to-resize-if-there-are-no-reserved-gdt-blocks-left.patch @@ -0,0 +1,40 @@ +From 972fbf779832e5ad15effa7712789aeff9224c37 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Sat, 18 Oct 2008 20:27:55 -0700 +Subject: ext3: don't try to resize if there are no reserved gdt blocks left + +From: Josef Bacik + +commit 972fbf779832e5ad15effa7712789aeff9224c37 upstream. + +When trying to resize a ext3 fs and you run out of reserved gdt blocks, +you get an error that doesn't actually tell you what went wrong, it just +says that the gdb it picked is not correct, which is the case since you +don't have any reserved gdt blocks left. This patch adds a check to make +sure you have reserved gdt blocks to use, and if not prints out a more +relevant error. + +Signed-off-by: Josef Bacik +Cc: +Cc: Andreas Dilger +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Willy Tarreau +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext3/resize.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ext3/resize.c ++++ b/fs/ext3/resize.c +@@ -790,7 +790,8 @@ int ext3_group_add(struct super_block *s + + if (reserved_gdb || gdb_off == 0) { + if (!EXT3_HAS_COMPAT_FEATURE(sb, +- EXT3_FEATURE_COMPAT_RESIZE_INODE)){ ++ EXT3_FEATURE_COMPAT_RESIZE_INODE) ++ || !le16_to_cpu(es->s_reserved_gdt_blocks)) { + ext3_warning(sb, __func__, + "No reserved GDT blocks, can't resize"); + return -EPERM; diff --git a/queue-2.6.27/ext3-fix-duplicate-entries-returned-from-getdents-system-call.patch b/queue-2.6.27/ext3-fix-duplicate-entries-returned-from-getdents-system-call.patch new file mode 100644 index 00000000000..2124aacaa40 --- /dev/null +++ b/queue-2.6.27/ext3-fix-duplicate-entries-returned-from-getdents-system-call.patch @@ -0,0 +1,68 @@ +From 8c9fa93d51123c5540762b1a9e1919d6f9c4af7c Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sat, 25 Oct 2008 11:38:37 -0400 +Subject: ext3: Fix duplicate entries returned from getdents() system call + +From: Theodore Ts'o + +commit 8c9fa93d51123c5540762b1a9e1919d6f9c4af7c upstream. + +Fix a regression caused by commit 6a897cf4, "ext3: fix ext3_dx_readdir +hash collision handling", where deleting files in a large directory +(requiring more than one getdents system call), results in some +filenames being returned twice. This was caused by a failure to +update info->curr_hash and info->curr_minor_hash, so that if the +directory had gotten modified since the last getdents() system call +(as would be the case if the user is running "rm -r" or "git clean"), +a directory entry would get returned twice to the userspace. + +This patch fixes the bug reported by Markus Trippelsdorf at: +http://bugzilla.kernel.org/show_bug.cgi?id=11844 + +Signed-off-by: "Theodore Ts'o" +Tested-by: Markus Trippelsdorf +Cc: Willy Tarreau +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext3/dir.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +--- a/fs/ext3/dir.c ++++ b/fs/ext3/dir.c +@@ -456,17 +456,8 @@ static int ext3_dx_readdir(struct file * + if (info->extra_fname) { + if (call_filldir(filp, dirent, filldir, info->extra_fname)) + goto finished; +- + info->extra_fname = NULL; +- info->curr_node = rb_next(info->curr_node); +- if (!info->curr_node) { +- if (info->next_hash == ~0) { +- filp->f_pos = EXT3_HTREE_EOF; +- goto finished; +- } +- info->curr_hash = info->next_hash; +- info->curr_minor_hash = 0; +- } ++ goto next_node; + } else if (!info->curr_node) + info->curr_node = rb_first(&info->root); + +@@ -498,9 +489,14 @@ static int ext3_dx_readdir(struct file * + info->curr_minor_hash = fname->minor_hash; + if (call_filldir(filp, dirent, filldir, fname)) + break; +- ++ next_node: + info->curr_node = rb_next(info->curr_node); +- if (!info->curr_node) { ++ if (info->curr_node) { ++ fname = rb_entry(info->curr_node, struct fname, ++ rb_hash); ++ info->curr_hash = fname->hash; ++ info->curr_minor_hash = fname->minor_hash; ++ } else { + if (info->next_hash == ~0) { + filp->f_pos = EXT3_HTREE_EOF; + break; diff --git a/queue-2.6.27/ext3-fix-ext3-block-reservation-early-enospc-issue.patch b/queue-2.6.27/ext3-fix-ext3-block-reservation-early-enospc-issue.patch new file mode 100644 index 00000000000..7e10152c7d9 --- /dev/null +++ b/queue-2.6.27/ext3-fix-ext3-block-reservation-early-enospc-issue.patch @@ -0,0 +1,64 @@ +From 46d01a225e694f1a4343beea44f1e85105aedd7e Mon Sep 17 00:00:00 2001 +From: Mingming Cao +Date: Sat, 18 Oct 2008 20:27:56 -0700 +Subject: ext3: fix ext3 block reservation early ENOSPC issue + +From: Mingming Cao + +commit 46d01a225e694f1a4343beea44f1e85105aedd7e upstream. + +We could run into ENOSPC error on ext3, even when there is free blocks on +the filesystem. + +The problem is triggered in the case the goal block group has 0 free +blocks , and the rest block groups are skipped due to the check of +"free_blocks < windowsz/2". Current code could fall back to non +reservation allocation to prevent early ENOSPC after examing all the block +groups with reservation on , but this code was bypassed if the reservation +window is turned off already, which is true in this case. + +This patch fixed two issues: +1) We don't need to turn off block reservation if the goal block group has +0 free blocks left and continue search for the rest of block groups. + +Current code the intention is to turn off the block reservation if the +goal allocation group has a few (some) free blocks left (not enough for +make the desired reservation window),to try to allocation in the goal +block group, to get better locality. But if the goal blocks have 0 free +blocks, it should leave the block reservation on, and continues search for +the next block groups,rather than turn off block reservation completely. + +2) we don't need to check the window size if the block reservation is off. + +The problem was originally found and fixed in ext4. + +Signed-off-by: Mingming Cao +Cc: Theodore Ts'o +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Willy Tarreau +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext3/balloc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ext3/balloc.c ++++ b/fs/ext3/balloc.c +@@ -1547,6 +1547,7 @@ retry_alloc: + * turn off reservation for this allocation + */ + if (my_rsv && (free_blocks < windowsz) ++ && (free_blocks > 0) + && (rsv_is_empty(&my_rsv->rsv_window))) + my_rsv = NULL; + +@@ -1585,7 +1586,7 @@ retry_alloc: + * free blocks is less than half of the reservation + * window size. + */ +- if (free_blocks <= (windowsz/2)) ++ if (my_rsv && (free_blocks <= (windowsz/2))) + continue; + + brelse(bitmap_bh); diff --git a/queue-2.6.27/ext3-fix-ext3_dx_readdir-hash-collision-handling.patch b/queue-2.6.27/ext3-fix-ext3_dx_readdir-hash-collision-handling.patch new file mode 100644 index 00000000000..f1fa250c55e --- /dev/null +++ b/queue-2.6.27/ext3-fix-ext3_dx_readdir-hash-collision-handling.patch @@ -0,0 +1,62 @@ +From 6a897cf447a83c9c3fd1b85a1e525c02d6eada7d Mon Sep 17 00:00:00 2001 +From: Eugene Dashevsky +Date: Sat, 18 Oct 2008 20:27:59 -0700 +Subject: ext3: fix ext3_dx_readdir hash collision handling + +From: Eugene Dashevsky + +commit 6a897cf447a83c9c3fd1b85a1e525c02d6eada7d upstream. + +This fixes a bug where readdir() would return a directory entry twice +if there was a hash collision in an hash tree indexed directory. + +[akpm@linux-foundation.org: coding-style fixes] +Signed-off-by: Eugene Dashevsky +Signed-off-by: Mike Snitzer +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Willy Tarreau +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext3/dir.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +--- a/fs/ext3/dir.c ++++ b/fs/ext3/dir.c +@@ -414,7 +414,7 @@ static int call_filldir(struct file * fi + get_dtype(sb, fname->file_type)); + if (error) { + filp->f_pos = curr_pos; +- info->extra_fname = fname->next; ++ info->extra_fname = fname; + return error; + } + fname = fname->next; +@@ -453,11 +453,21 @@ static int ext3_dx_readdir(struct file * + * If there are any leftover names on the hash collision + * chain, return them first. + */ +- if (info->extra_fname && +- call_filldir(filp, dirent, filldir, info->extra_fname)) +- goto finished; ++ if (info->extra_fname) { ++ if (call_filldir(filp, dirent, filldir, info->extra_fname)) ++ goto finished; + +- if (!info->curr_node) ++ info->extra_fname = NULL; ++ info->curr_node = rb_next(info->curr_node); ++ if (!info->curr_node) { ++ if (info->next_hash == ~0) { ++ filp->f_pos = EXT3_HTREE_EOF; ++ goto finished; ++ } ++ info->curr_hash = info->next_hash; ++ info->curr_minor_hash = 0; ++ } ++ } else if (!info->curr_node) + info->curr_node = rb_first(&info->root); + + while (1) { diff --git a/queue-2.6.27/ext4-add-checksum-calculation-when-clearing-uninit-flag-in-ext4_new_inode.patch b/queue-2.6.27/ext4-add-checksum-calculation-when-clearing-uninit-flag-in-ext4_new_inode.patch new file mode 100644 index 00000000000..ce011985a13 --- /dev/null +++ b/queue-2.6.27/ext4-add-checksum-calculation-when-clearing-uninit-flag-in-ext4_new_inode.patch @@ -0,0 +1,39 @@ +From tytso@mit.edu Wed Dec 3 10:45:18 2008 +From: Frederic Bohe +Date: Sun, 16 Nov 2008 11:05:40 -0500 +Subject: ext4: add checksum calculation when clearing UNINIT flag in ext4_new_inode +To: stable@kernel.org +Cc: Frederic Bohe , Ext4 Developers List , "Theodore Ts'o" +Message-ID: <1226851540-8032-21-git-send-email-tytso@mit.edu> + +From: Frederic Bohe + +(cherry picked from commit 23712a9c28b9f80a8cf70c8490358d5f562d2465) + +When initializing an uninitialized block group in ext4_new_inode(), +its block group checksum must be re-calculated. This fixes a race +when several threads try to allocate a new inode in an UNINIT'd group. + +There is some question whether we need to be initializing the block +bitmap in ext4_new_inode() at all, but for now, if we are going to +init the block group, let's eliminate the race. + +Signed-off-by: Frederic Bohe +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ialloc.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -717,6 +717,8 @@ got: + gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); + free = ext4_free_blocks_after_init(sb, group, gdp); + gdp->bg_free_blocks_count = cpu_to_le16(free); ++ gdp->bg_checksum = ext4_group_desc_csum(sbi, group, ++ gdp); + } + spin_unlock(sb_bgl_lock(sbi, group)); + diff --git a/queue-2.6.27/ext4-add-missing-unlock-in-ext4_check_descriptors-on-error-path.patch b/queue-2.6.27/ext4-add-missing-unlock-in-ext4_check_descriptors-on-error-path.patch new file mode 100644 index 00000000000..f6bb964c55e --- /dev/null +++ b/queue-2.6.27/ext4-add-missing-unlock-in-ext4_check_descriptors-on-error-path.patch @@ -0,0 +1,39 @@ +From tytso@mit.edu Wed Dec 3 09:57:50 2008 +From: Li Zefan +Date: Sun, 16 Nov 2008 11:05:24 -0500 +Subject: ext4: add missing unlock in ext4_check_descriptors() on error path +To: stable@kernel.org +Cc: "Theodore Ts'o" , Ext4 Developers List , Li Zefan +Message-ID: <1226851540-8032-5-git-send-email-tytso@mit.edu> + + +From: Li Zefan + +(cherry picked from commit 7ee1ec4ca30c6df8e989615cdaacb75f2af4fa6b) + +If there group descriptors are corrupted we need unlock the block +group lock before returning from the function; else we will oops when +freeing a spinlock which is still being held. + +Signed-off-by: Li Zefan +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1626,8 +1626,10 @@ static int ext4_check_descriptors(struct + "Checksum for group %lu failed (%u!=%u)\n", + i, le16_to_cpu(ext4_group_desc_csum(sbi, i, + gdp)), le16_to_cpu(gdp->bg_checksum)); +- if (!(sb->s_flags & MS_RDONLY)) ++ if (!(sb->s_flags & MS_RDONLY)) { ++ spin_unlock(sb_bgl_lock(sbi, i)); + return 0; ++ } + } + spin_unlock(sb_bgl_lock(sbi, i)); + if (!flexbg_flag) diff --git a/queue-2.6.27/ext4-calculate-journal-credits-correctly.patch b/queue-2.6.27/ext4-calculate-journal-credits-correctly.patch new file mode 100644 index 00000000000..2b4be26223c --- /dev/null +++ b/queue-2.6.27/ext4-calculate-journal-credits-correctly.patch @@ -0,0 +1,46 @@ +From tytso@mit.edu Wed Dec 3 10:44:36 2008 +From: "Theodore Ts'o" +Date: Sun, 16 Nov 2008 11:05:38 -0500 +Subject: ext4: calculate journal credits correctly +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" +Message-ID: <1226851540-8032-19-git-send-email-tytso@mit.edu> + +From: "Theodore Ts'o" + +(cherry picked from commit ac51d83705c2a38c71f39cde99708b14e6212a60) + +This fixes a 2.6.27 regression which was introduced in commit a02908f1. + +We weren't passing the chunk parameter down to the two subections, +ext4_indirect_trans_blocks() and ext4_ext_index_trans_blocks(), with +the result that massively overestimate the amount of credits needed by +ext4_da_writepages, especially in the non-extents case. This causes +failures especially on /boot partitions, which tend to be small and +non-extent using since GRUB doesn't handle extents. + +This patch fixes the bug reported by Joseph Fannin at: +http://bugzilla.kernel.org/show_bug.cgi?id=11964 + +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4444,9 +4444,10 @@ static int ext4_indirect_trans_blocks(st + static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) + { + if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) +- return ext4_indirect_trans_blocks(inode, nrblocks, 0); +- return ext4_ext_index_trans_blocks(inode, nrblocks, 0); ++ return ext4_indirect_trans_blocks(inode, nrblocks, chunk); ++ return ext4_ext_index_trans_blocks(inode, nrblocks, chunk); + } ++ + /* + * Account for index blocks, block groups bitmaps and block group + * descriptor blocks if modify datablocks and index blocks diff --git a/queue-2.6.27/ext4-convert-to-host-order-before-using-the-values.patch b/queue-2.6.27/ext4-convert-to-host-order-before-using-the-values.patch new file mode 100644 index 00000000000..1e2a8fb22e8 --- /dev/null +++ b/queue-2.6.27/ext4-convert-to-host-order-before-using-the-values.patch @@ -0,0 +1,37 @@ +From tytso@mit.edu Wed Dec 3 10:43:46 2008 +From: Aneesh Kumar K.V +Date: Sun, 16 Nov 2008 11:05:36 -0500 +Subject: ext4: Convert to host order before using the values. +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" , "Aneesh Kumar K.V" +Message-ID: <1226851540-8032-17-git-send-email-tytso@mit.edu> + +From: Aneesh Kumar K.V + +(cherry picked from commit d94e99a64c3beece22dbfb2b335771a59184eb0a) + +Use le16_to_cpu to read the s_reserved_gdt_blocks values +from super block. + +Signed-off-by: Aneesh Kumar K.V +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1506,9 +1506,8 @@ static int ext4_fill_flex_info(struct su + + /* We allocate both existing and potentially added groups */ + flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + +- ((sbi->s_es->s_reserved_gdt_blocks +1 ) << +- EXT4_DESC_PER_BLOCK_BITS(sb))) / +- groups_per_flex; ++ ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << ++ EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex; + sbi->s_flex_groups = kzalloc(flex_group_count * + sizeof(struct flex_groups), GFP_KERNEL); + if (sbi->s_flex_groups == NULL) { diff --git a/queue-2.6.27/ext4-do-mballoc-init-before-doing-filesystem-recovery.patch b/queue-2.6.27/ext4-do-mballoc-init-before-doing-filesystem-recovery.patch new file mode 100644 index 00000000000..c0b3aee4677 --- /dev/null +++ b/queue-2.6.27/ext4-do-mballoc-init-before-doing-filesystem-recovery.patch @@ -0,0 +1,65 @@ +From tytso@mit.edu Wed Dec 3 10:42:48 2008 +From: Aneesh Kumar K.V +Date: Sun, 16 Nov 2008 11:05:33 -0500 +Subject: ext4: Do mballoc init before doing filesystem recovery +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" , "Aneesh Kumar K.V" +Message-ID: <1226851540-8032-14-git-send-email-tytso@mit.edu> + +From: Aneesh Kumar K.V + +(cherry picked from commit c2774d84fd6cab2bfa2a2fae0b1ca8d8ebde48a2) + +During filesystem recovery we may be doing a truncate +which expects some of the mballoc data structures to +be initialized. So do ext4_mb_init before recovery. + +Signed-off-by: Aneesh Kumar K.V +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2449,6 +2449,21 @@ static int ext4_fill_super(struct super_ + "available.\n"); + } + ++ if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { ++ printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " ++ "requested data journaling mode\n"); ++ clear_opt(sbi->s_mount_opt, DELALLOC); ++ } else if (test_opt(sb, DELALLOC)) ++ printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); ++ ++ ext4_ext_init(sb); ++ err = ext4_mb_init(sb, needs_recovery); ++ if (err) { ++ printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n", ++ err); ++ goto failed_mount4; ++ } ++ + /* + * akpm: core read_super() calls in here with the superblock locked. + * That deadlocks, because orphan cleanup needs to lock the superblock +@@ -2468,16 +2483,6 @@ static int ext4_fill_super(struct super_ + test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered": + "writeback"); + +- if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { +- printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " +- "requested data journaling mode\n"); +- clear_opt(sbi->s_mount_opt, DELALLOC); +- } else if (test_opt(sb, DELALLOC)) +- printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); +- +- ext4_ext_init(sb); +- ext4_mb_init(sb, needs_recovery); +- + lock_kernel(); + return 0; + diff --git a/queue-2.6.27/ext4-elevate-write-count-for-migrate-ioctl.patch b/queue-2.6.27/ext4-elevate-write-count-for-migrate-ioctl.patch new file mode 100644 index 00000000000..9a0ab37200e --- /dev/null +++ b/queue-2.6.27/ext4-elevate-write-count-for-migrate-ioctl.patch @@ -0,0 +1,100 @@ +From tytso@mit.edu Wed Dec 3 09:58:51 2008 +From: Aneesh Kumar K.V +Date: Sun, 16 Nov 2008 11:05:25 -0500 +Subject: ext4: elevate write count for migrate ioctl +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" , "Aneesh Kumar K.V" +Message-ID: <1226851540-8032-6-git-send-email-tytso@mit.edu> + +From: Aneesh Kumar K.V + +(cherry picked from commit 2a43a878001cc5cb7c3c7be2e8dad0a1aeb939b0) + +The migrate ioctl writes to the filsystem, so we need to elevate the +write count. + +Signed-off-by: Aneesh Kumar K.V +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4.h | 3 +-- + fs/ext4/ioctl.c | 21 ++++++++++++++++++++- + fs/ext4/migrate.c | 10 +--------- + 3 files changed, 22 insertions(+), 12 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1083,8 +1083,7 @@ extern long ext4_ioctl(struct file *, un + extern long ext4_compat_ioctl (struct file *, unsigned int, unsigned long); + + /* migrate.c */ +-extern int ext4_ext_migrate(struct inode *, struct file *, unsigned int, +- unsigned long); ++extern int ext4_ext_migrate(struct inode *); + /* namei.c */ + extern int ext4_orphan_add(handle_t *, struct inode *); + extern int ext4_orphan_del(handle_t *, struct inode *); +--- a/fs/ext4/ioctl.c ++++ b/fs/ext4/ioctl.c +@@ -267,7 +267,26 @@ setversion_out: + } + + case EXT4_IOC_MIGRATE: +- return ext4_ext_migrate(inode, filp, cmd, arg); ++ { ++ int err; ++ if (!is_owner_or_cap(inode)) ++ return -EACCES; ++ ++ err = mnt_want_write(filp->f_path.mnt); ++ if (err) ++ return err; ++ /* ++ * inode_mutex prevent write and truncate on the file. ++ * Read still goes through. We take i_data_sem in ++ * ext4_ext_swap_inode_data before we switch the ++ * inode format to prevent read. ++ */ ++ mutex_lock(&(inode->i_mutex)); ++ err = ext4_ext_migrate(inode); ++ mutex_unlock(&(inode->i_mutex)); ++ mnt_drop_write(filp->f_path.mnt); ++ return err; ++ } + + default: + return -ENOTTY; +--- a/fs/ext4/migrate.c ++++ b/fs/ext4/migrate.c +@@ -447,8 +447,7 @@ static int free_ext_block(handle_t *hand + + } + +-int ext4_ext_migrate(struct inode *inode, struct file *filp, +- unsigned int cmd, unsigned long arg) ++int ext4_ext_migrate(struct inode *inode) + { + handle_t *handle; + int retval = 0, i; +@@ -516,12 +515,6 @@ int ext4_ext_migrate(struct inode *inode + * when we add extents we extent the journal + */ + /* +- * inode_mutex prevent write and truncate on the file. Read still goes +- * through. We take i_data_sem in ext4_ext_swap_inode_data before we +- * switch the inode format to prevent read. +- */ +- mutex_lock(&(inode->i_mutex)); +- /* + * Even though we take i_mutex we can still cause block allocation + * via mmap write to holes. If we have allocated new blocks we fail + * migrate. New block allocation will clear EXT4_EXT_MIGRATE flag. +@@ -623,7 +616,6 @@ err_out: + tmp_inode->i_nlink = 0; + + ext4_journal_stop(handle); +- mutex_unlock(&(inode->i_mutex)); + + if (tmp_inode) + iput(tmp_inode); diff --git a/queue-2.6.27/ext4-fix-11321-create-proc-ext4-stats-more-carefully.patch b/queue-2.6.27/ext4-fix-11321-create-proc-ext4-stats-more-carefully.patch new file mode 100644 index 00000000000..b5122ee05a7 --- /dev/null +++ b/queue-2.6.27/ext4-fix-11321-create-proc-ext4-stats-more-carefully.patch @@ -0,0 +1,92 @@ +From tytso@mit.edu Wed Dec 3 09:56:22 2008 +From: Alexey Dobriyan +Date: Sun, 16 Nov 2008 11:05:22 -0500 +Subject: ext4: fix #11321: create /proc/ext4/*/stats more carefully +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" , Alexey Dobriyan +Message-ID: <1226851540-8032-3-git-send-email-tytso@mit.edu> + + +From: Alexey Dobriyan + +(cherry picked from commit 899fc1a4cf404747de2666534d508804597ee22f) + +ext4 creates per-suberblock directory in /proc/ext4/ . Name used as +basis is taken from bdevname, which, surprise, can contain slash. + +However, proc while allowing to use proc_create("a/b", parent) form of +PDE creation, assumes that parent/a was already created. + +bdevname in question is 'cciss/c0d0p9', directory is not created and all +this stuff goes directly into /proc (which is real bug). + +Warning comes when _second_ partition is mounted. + +http://bugzilla.kernel.org/show_bug.cgi?id=11321 + +Signed-off-by: Alexey Dobriyan +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/mballoc.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -2785,14 +2785,20 @@ static int ext4_mb_init_per_dev_proc(str + mode_t mode = S_IFREG | S_IRUGO | S_IWUSR; + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct proc_dir_entry *proc; +- char devname[64]; ++ char devname[BDEVNAME_SIZE], *p; + + if (proc_root_ext4 == NULL) { + sbi->s_mb_proc = NULL; + return -EINVAL; + } + bdevname(sb->s_bdev, devname); ++ p = devname; ++ while ((p = strchr(p, '/'))) ++ *p = '!'; ++ + sbi->s_mb_proc = proc_mkdir(devname, proc_root_ext4); ++ if (!sbi->s_mb_proc) ++ goto err_create_dir; + + MB_PROC_HANDLER(EXT4_MB_STATS_NAME, stats); + MB_PROC_HANDLER(EXT4_MB_MAX_TO_SCAN_NAME, max_to_scan); +@@ -2804,7 +2810,6 @@ static int ext4_mb_init_per_dev_proc(str + return 0; + + err_out: +- printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname); + remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc); + remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc); + remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc); +@@ -2813,6 +2818,8 @@ err_out: + remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc); + remove_proc_entry(devname, proc_root_ext4); + sbi->s_mb_proc = NULL; ++err_create_dir: ++ printk(KERN_ERR "EXT4-fs: Unable to create %s\n", devname); + + return -ENOMEM; + } +@@ -2820,12 +2827,15 @@ err_out: + static int ext4_mb_destroy_per_dev_proc(struct super_block *sb) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); +- char devname[64]; ++ char devname[BDEVNAME_SIZE], *p; + + if (sbi->s_mb_proc == NULL) + return -EINVAL; + + bdevname(sb->s_bdev, devname); ++ p = devname; ++ while ((p = strchr(p, '/'))) ++ *p = '!'; + remove_proc_entry(EXT4_MB_GROUP_PREALLOC, sbi->s_mb_proc); + remove_proc_entry(EXT4_MB_STREAM_REQ, sbi->s_mb_proc); + remove_proc_entry(EXT4_MB_ORDER2_REQ, sbi->s_mb_proc); diff --git a/queue-2.6.27/ext4-fix-duplicate-entries-returned-from-getdents-system-call.patch b/queue-2.6.27/ext4-fix-duplicate-entries-returned-from-getdents-system-call.patch new file mode 100644 index 00000000000..07cd22c7457 --- /dev/null +++ b/queue-2.6.27/ext4-fix-duplicate-entries-returned-from-getdents-system-call.patch @@ -0,0 +1,72 @@ +From tytso@mit.edu Wed Dec 3 10:43:07 2008 +From: "Theodore Ts'o" +Date: Sun, 16 Nov 2008 11:05:34 -0500 +Subject: ext4: Fix duplicate entries returned from getdents() system call +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" +Message-ID: <1226851540-8032-15-git-send-email-tytso@mit.edu> + +From: "Theodore Ts'o" + +(cherry picked from commit 3c37fc86d20fe35be656f070997d62f75c2e4874) + +Fix a regression caused by commit d0156417, "ext4: fix ext4_dx_readdir +hash collision handling", where deleting files in a large directory +(requiring more than one getdents system call), results in some +filenames being returned twice. This was caused by a failure to +update info->curr_hash and info->curr_minor_hash, so that if the +directory had gotten modified since the last getdents() system call +(as would be the case if the user is running "rm -r" or "git clean"), +a directory entry would get returned twice to the userspace. + +Signed-off-by: "Theodore Ts'o" + +This patch fixes the bug reported by Markus Trippelsdorf at: +http://bugzilla.kernel.org/show_bug.cgi?id=11844 + +Signed-off-by: "Theodore Ts'o" +Tested-by: Markus Trippelsdorf +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/dir.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +--- a/fs/ext4/dir.c ++++ b/fs/ext4/dir.c +@@ -458,17 +458,8 @@ static int ext4_dx_readdir(struct file * + if (info->extra_fname) { + if (call_filldir(filp, dirent, filldir, info->extra_fname)) + goto finished; +- + info->extra_fname = NULL; +- info->curr_node = rb_next(info->curr_node); +- if (!info->curr_node) { +- if (info->next_hash == ~0) { +- filp->f_pos = EXT4_HTREE_EOF; +- goto finished; +- } +- info->curr_hash = info->next_hash; +- info->curr_minor_hash = 0; +- } ++ goto next_node; + } else if (!info->curr_node) + info->curr_node = rb_first(&info->root); + +@@ -500,9 +491,14 @@ static int ext4_dx_readdir(struct file * + info->curr_minor_hash = fname->minor_hash; + if (call_filldir(filp, dirent, filldir, fname)) + break; +- ++ next_node: + info->curr_node = rb_next(info->curr_node); +- if (!info->curr_node) { ++ if (info->curr_node) { ++ fname = rb_entry(info->curr_node, struct fname, ++ rb_hash); ++ info->curr_hash = fname->hash; ++ info->curr_minor_hash = fname->minor_hash; ++ } else { + if (info->next_hash == ~0) { + filp->f_pos = EXT4_HTREE_EOF; + break; diff --git a/queue-2.6.27/ext4-fix-initialization-of-uninit-bitmap-blocks.patch b/queue-2.6.27/ext4-fix-initialization-of-uninit-bitmap-blocks.patch new file mode 100644 index 00000000000..bd52f8a4797 --- /dev/null +++ b/queue-2.6.27/ext4-fix-initialization-of-uninit-bitmap-blocks.patch @@ -0,0 +1,86 @@ +From tytso@mit.edu Wed Dec 3 10:03:38 2008 +From: Frederic Bohe +Date: Sun, 16 Nov 2008 11:05:28 -0500 +Subject: ext4: fix initialization of UNINIT bitmap blocks +To: stable@kernel.org +Cc: Frederic Bohe , Ext4 Developers List , "Theodore Ts'o" +Message-ID: <1226851540-8032-9-git-send-email-tytso@mit.edu> + +From: Frederic Bohe + +(cherry picked from commit c806e68f5647109350ec546fee5b526962970fd2) + +This fixes a bug which caused on-line resizing of filesystems with a +1k blocksize to fail. The root cause of this bug was the fact that if +an uninitalized bitmap block gets read in by userspace (which +e2fsprogs does try to avoid, but can happen when the blocksize is less +than the pagesize and an adjacent blocks is read into memory) +ext4_read_block_bitmap() was erroneously depending on the buffer +uptodate flag to decide whether it needed to initialize the bitmap +block in memory --- i.e., to set the standard set of blocks in use by +a block group (superblock, bitmaps, inode table, etc.). Essentially, +ext4_read_block_bitmap() assumed it was the only routine that might +try to read a block containing a block bitmap, which is simply not +true. + +To fix this, ext4_read_block_bitmap() and ext4_read_inode_bitmap() +must always initialize uninitialized bitmap blocks. Once a block or +inode is allocated out of that bitmap, it will be marked as +initialized in the block group descriptor, so in general this won't +result any extra unnecessary work. + +Signed-off-by: Frederic Bohe +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/balloc.c | 4 +++- + fs/ext4/ialloc.c | 4 +++- + fs/ext4/mballoc.c | 4 +++- + 3 files changed, 9 insertions(+), 3 deletions(-) + +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -318,9 +318,11 @@ ext4_read_block_bitmap(struct super_bloc + block_group, bitmap_blk); + return NULL; + } +- if (bh_uptodate_or_lock(bh)) ++ if (buffer_uptodate(bh) && ++ !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) + return bh; + ++ lock_buffer(bh); + spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); + if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { + ext4_init_block_bitmap(sb, bh, block_group, desc); +--- a/fs/ext4/ialloc.c ++++ b/fs/ext4/ialloc.c +@@ -115,9 +115,11 @@ ext4_read_inode_bitmap(struct super_bloc + block_group, bitmap_blk); + return NULL; + } +- if (bh_uptodate_or_lock(bh)) ++ if (buffer_uptodate(bh) && ++ !(desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) + return bh; + ++ lock_buffer(bh); + spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); + if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { + ext4_init_inode_bitmap(sb, bh, block_group, desc); +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -784,9 +784,11 @@ static int ext4_mb_init_cache(struct pag + if (bh[i] == NULL) + goto out; + +- if (bh_uptodate_or_lock(bh[i])) ++ if (buffer_uptodate(bh[i]) && ++ !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) + continue; + ++ lock_buffer(bh[i]); + spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); + if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { + ext4_init_block_bitmap(sb, bh[i], diff --git a/queue-2.6.27/ext4-fix-xattr-deadlock.patch b/queue-2.6.27/ext4-fix-xattr-deadlock.patch new file mode 100644 index 00000000000..7da443e7934 --- /dev/null +++ b/queue-2.6.27/ext4-fix-xattr-deadlock.patch @@ -0,0 +1,58 @@ +From tytso@mit.edu Wed Dec 3 10:42:04 2008 +From: Kalpak Shah +Date: Sun, 16 Nov 2008 11:05:31 -0500 +Subject: ext4: fix xattr deadlock +To: stable@kernel.org +Cc: Kalpak Shah , Ext4 Developers List , "Theodore Ts'o" +Message-ID: <1226851540-8032-12-git-send-email-tytso@mit.edu> + + +From: Kalpak Shah + +(cherry picked from commit 4d20c685fa365766a8f13584b4c8178a15ab7103) + +ext4_xattr_set_handle() eventually ends up calling +ext4_mark_inode_dirty() which tries to expand the inode by shifting +the EAs. This leads to the xattr_sem being downed again and leading +to a deadlock. + +This patch makes sure that if ext4_xattr_set_handle() is in the +call-chain, ext4_mark_inode_dirty() will not expand the inode. + +Signed-off-by: Kalpak Shah +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -959,6 +959,7 @@ ext4_xattr_set_handle(handle_t *handle, + struct ext4_xattr_block_find bs = { + .s = { .not_found = -ENODATA, }, + }; ++ unsigned long no_expand; + int error; + + if (!name) +@@ -966,6 +967,9 @@ ext4_xattr_set_handle(handle_t *handle, + if (strlen(name) > 255) + return -ERANGE; + down_write(&EXT4_I(inode)->xattr_sem); ++ no_expand = EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND; ++ EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND; ++ + error = ext4_get_inode_loc(inode, &is.iloc); + if (error) + goto cleanup; +@@ -1042,6 +1046,8 @@ ext4_xattr_set_handle(handle_t *handle, + cleanup: + brelse(is.iloc.bh); + brelse(bs.bh); ++ if (no_expand == 0) ++ EXT4_I(inode)->i_state &= ~EXT4_STATE_NO_EXPAND; + up_write(&EXT4_I(inode)->xattr_sem); + return error; + } diff --git a/queue-2.6.27/ext4-free-ext4_prealloc_space-using-kmem_cache_free.patch b/queue-2.6.27/ext4-free-ext4_prealloc_space-using-kmem_cache_free.patch new file mode 100644 index 00000000000..06d81d57185 --- /dev/null +++ b/queue-2.6.27/ext4-free-ext4_prealloc_space-using-kmem_cache_free.patch @@ -0,0 +1,34 @@ +From tytso@mit.edu Wed Dec 3 10:42:23 2008 +From: Aneesh Kumar K.V +Date: Sun, 16 Nov 2008 11:05:32 -0500 +Subject: ext4: Free ext4_prealloc_space using kmem_cache_free +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" , "Aneesh Kumar K.V" +Message-ID: <1226851540-8032-13-git-send-email-tytso@mit.edu> + +From: Aneesh Kumar K.V + +(cherry picked from commit 688f05a01983711a4e715b1d6e15a89a89c96a66) + +We should use kmem_cache_free to free memory allocated +via kmem_cache_alloc + +Signed-off-by: Aneesh Kumar K.V +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/mballoc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -2577,7 +2577,7 @@ static void ext4_mb_cleanup_pa(struct ex + pa = list_entry(cur, struct ext4_prealloc_space, pa_group_list); + list_del(&pa->pa_group_list); + count++; +- kfree(pa); ++ kmem_cache_free(ext4_pspace_cachep, pa); + } + if (count) + mb_debug("mballoc: %u PAs left\n", count); diff --git a/queue-2.6.27/ext4-jbd2-avoid-warn-messages-when-failing-to-write-to-the-superblock.patch b/queue-2.6.27/ext4-jbd2-avoid-warn-messages-when-failing-to-write-to-the-superblock.patch new file mode 100644 index 00000000000..16e6615c6df --- /dev/null +++ b/queue-2.6.27/ext4-jbd2-avoid-warn-messages-when-failing-to-write-to-the-superblock.patch @@ -0,0 +1,104 @@ +From tytso@mit.edu Wed Dec 3 10:02:23 2008 +From: "Theodore Ts'o" +Date: Sun, 16 Nov 2008 11:05:27 -0500 +Subject: ext4/jbd2: Avoid WARN() messages when failing to write to the superblock +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" +Message-ID: <1226851540-8032-8-git-send-email-tytso@mit.edu> + +From: "Theodore Ts'o" + +(cherry picked from commit 914258bf2cb22bf4336a1b1d90c551b4b11ca5aa) + +This fixes some very common warnings reported by kerneloops.org + +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 23 ++++++++++++++++++++++- + fs/jbd2/journal.c | 27 +++++++++++++++++++++++++-- + 2 files changed, 47 insertions(+), 3 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2804,13 +2804,34 @@ static void ext4_commit_super(struct sup + + if (!sbh) + return; ++ if (buffer_write_io_error(sbh)) { ++ /* ++ * Oh, dear. A previous attempt to write the ++ * superblock failed. This could happen because the ++ * USB device was yanked out. Or it could happen to ++ * be a transient write error and maybe the block will ++ * be remapped. Nothing we can do but to retry the ++ * write and hope for the best. ++ */ ++ printk(KERN_ERR "ext4: previous I/O error to " ++ "superblock detected for %s.\n", sb->s_id); ++ clear_buffer_write_io_error(sbh); ++ set_buffer_uptodate(sbh); ++ } + es->s_wtime = cpu_to_le32(get_seconds()); + ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb)); + es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb)); + BUFFER_TRACE(sbh, "marking dirty"); + mark_buffer_dirty(sbh); +- if (sync) ++ if (sync) { + sync_dirty_buffer(sbh); ++ if (buffer_write_io_error(sbh)) { ++ printk(KERN_ERR "ext4: I/O error while writing " ++ "superblock for %s.\n", sb->s_id); ++ clear_buffer_write_io_error(sbh); ++ set_buffer_uptodate(sbh); ++ } ++ } + } + + +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -1259,6 +1259,22 @@ void jbd2_journal_update_superblock(jour + goto out; + } + ++ if (buffer_write_io_error(bh)) { ++ /* ++ * Oh, dear. A previous attempt to write the journal ++ * superblock failed. This could happen because the ++ * USB device was yanked out. Or it could happen to ++ * be a transient write error and maybe the block will ++ * be remapped. Nothing we can do but to retry the ++ * write and hope for the best. ++ */ ++ printk(KERN_ERR "JBD2: previous I/O error detected " ++ "for journal superblock update for %s.\n", ++ journal->j_devname); ++ clear_buffer_write_io_error(bh); ++ set_buffer_uptodate(bh); ++ } ++ + spin_lock(&journal->j_state_lock); + jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n", + journal->j_tail, journal->j_tail_sequence, journal->j_errno); +@@ -1270,9 +1286,16 @@ void jbd2_journal_update_superblock(jour + + BUFFER_TRACE(bh, "marking dirty"); + mark_buffer_dirty(bh); +- if (wait) ++ if (wait) { + sync_dirty_buffer(bh); +- else ++ if (buffer_write_io_error(bh)) { ++ printk(KERN_ERR "JBD2: I/O error detected " ++ "when updating journal superblock for %s.\n", ++ journal->j_devname); ++ clear_buffer_write_io_error(bh); ++ set_buffer_uptodate(bh); ++ } ++ } else + ll_rw_block(SWRITE, 1, &bh); + + out: diff --git a/queue-2.6.27/ext4-mark-the-buffer_heads-as-dirty-and-uptodate-after-prepare_write.patch b/queue-2.6.27/ext4-mark-the-buffer_heads-as-dirty-and-uptodate-after-prepare_write.patch new file mode 100644 index 00000000000..792ec6cbe63 --- /dev/null +++ b/queue-2.6.27/ext4-mark-the-buffer_heads-as-dirty-and-uptodate-after-prepare_write.patch @@ -0,0 +1,36 @@ +From tytso@mit.edu Wed Dec 3 10:44:57 2008 +From: Aneesh Kumar K.V +Date: Sun, 16 Nov 2008 11:05:39 -0500 +Subject: ext4: Mark the buffer_heads as dirty and uptodate after prepare_write +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" , "Aneesh Kumar K.V" +Message-ID: <1226851540-8032-20-git-send-email-tytso@mit.edu> + +From: Aneesh Kumar K.V + +(cherry picked from commit ed9b3e3379731e9f9d2f73f3d7fd9e7d2ce3df4a) + +We need to make sure we mark the buffer_heads as dirty and uptodate +so that block_write_full_page write them correctly. + +This fixes mmap corruptions that can occur in low memory situations. + +Signed-off-by: Aneesh Kumar K.V +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -2242,6 +2242,8 @@ static int ext4_da_writepage(struct page + unlock_page(page); + return 0; + } ++ /* now mark the buffer_heads as dirty and uptodate */ ++ block_commit_write(page, 0, PAGE_CACHE_SIZE); + } + + if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) diff --git a/queue-2.6.27/ext4-renumber-ext4_ioc_migrate.patch b/queue-2.6.27/ext4-renumber-ext4_ioc_migrate.patch new file mode 100644 index 00000000000..4bbe5e6c980 --- /dev/null +++ b/queue-2.6.27/ext4-renumber-ext4_ioc_migrate.patch @@ -0,0 +1,50 @@ +From tytso@mit.edu Wed Dec 3 09:59:19 2008 +From: "Theodore Ts'o" +Date: Sun, 16 Nov 2008 11:05:26 -0500 +Subject: ext4: Renumber EXT4_IOC_MIGRATE +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" +Message-ID: <1226851540-8032-7-git-send-email-tytso@mit.edu> + +From: "Theodore Ts'o" + +(cherry picked from commit 8eea80d52b9d87cfd771055534bd2c24f73704d7) + +Pick an ioctl number for EXT4_IOC_MIGRATE that won't conflict with +other ext4 ioctl's. Since there haven't been any major userspace +users of this ioctl, we can afford to change this now, to avoid +potential problems later. + +Also, reorder the ioctl numbers in ext4.h to avoid this sort of +mistake in the future. + +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4.h | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -291,8 +291,6 @@ struct ext4_new_group_data { + #define EXT4_IOC_SETFLAGS FS_IOC_SETFLAGS + #define EXT4_IOC_GETVERSION _IOR('f', 3, long) + #define EXT4_IOC_SETVERSION _IOW('f', 4, long) +-#define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) +-#define EXT4_IOC_GROUP_ADD _IOW('f', 8,struct ext4_new_group_input) + #define EXT4_IOC_GETVERSION_OLD FS_IOC_GETVERSION + #define EXT4_IOC_SETVERSION_OLD FS_IOC_SETVERSION + #ifdef CONFIG_JBD2_DEBUG +@@ -300,7 +298,10 @@ struct ext4_new_group_data { + #endif + #define EXT4_IOC_GETRSVSZ _IOR('f', 5, long) + #define EXT4_IOC_SETRSVSZ _IOW('f', 6, long) +-#define EXT4_IOC_MIGRATE _IO('f', 7) ++#define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) ++#define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input) ++#define EXT4_IOC_MIGRATE _IO('f', 9) ++ /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */ + + /* + * ioctl commands in 32 bit emulation diff --git a/queue-2.6.27/ext4-update-flex_bg-free-blocks-and-free-inodes-counters-when-resizing.patch b/queue-2.6.27/ext4-update-flex_bg-free-blocks-and-free-inodes-counters-when-resizing.patch new file mode 100644 index 00000000000..db37c097c77 --- /dev/null +++ b/queue-2.6.27/ext4-update-flex_bg-free-blocks-and-free-inodes-counters-when-resizing.patch @@ -0,0 +1,59 @@ +From tytso@mit.edu Wed Dec 3 09:54:56 2008 +From: Frederic Bohe +Date: Sun, 16 Nov 2008 11:05:21 -0500 +Subject: ext4: Update flex_bg free blocks and free inodes counters when resizing. +To: stable@kernel.org +Cc: Frederic Bohe , Ext4 Developers List , "Theodore Ts'o" +Message-ID: <1226851540-8032-2-git-send-email-tytso@mit.edu> + + +From: Frederic Bohe + +(cherry picked from commit c62a11fd9555007b1caab83b5bcbb443a43e32bb) + +This fixes a bug which prevented the newly created inodes after a +resize from being used on filesystems with flex_bg. + +Signed-off-by: Frederic Bohe +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/resize.c | 9 +++++++++ + fs/ext4/super.c | 7 +++++-- + 2 files changed, 14 insertions(+), 2 deletions(-) + +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -929,6 +929,15 @@ int ext4_group_add(struct super_block *s + percpu_counter_add(&sbi->s_freeinodes_counter, + EXT4_INODES_PER_GROUP(sb)); + ++ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { ++ ext4_group_t flex_group; ++ flex_group = ext4_flex_group(sbi, input->group); ++ sbi->s_flex_groups[flex_group].free_blocks += ++ input->free_blocks_count; ++ sbi->s_flex_groups[flex_group].free_inodes += ++ EXT4_INODES_PER_GROUP(sb); ++ } ++ + ext4_journal_dirty_metadata(handle, sbi->s_sbh); + sb->s_dirt = 1; + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1504,8 +1504,11 @@ static int ext4_fill_flex_info(struct su + sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; + groups_per_flex = 1 << sbi->s_log_groups_per_flex; + +- flex_group_count = (sbi->s_groups_count + groups_per_flex - 1) / +- groups_per_flex; ++ /* We allocate both existing and potentially added groups */ ++ flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + ++ ((sbi->s_es->s_reserved_gdt_blocks +1 ) << ++ EXT4_DESC_PER_BLOCK_BITS(sb))) / ++ groups_per_flex; + sbi->s_flex_groups = kzalloc(flex_group_count * + sizeof(struct flex_groups), GFP_KERNEL); + if (sbi->s_flex_groups == NULL) { diff --git a/queue-2.6.27/ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch b/queue-2.6.27/ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch new file mode 100644 index 00000000000..296676afdf6 --- /dev/null +++ b/queue-2.6.27/ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch @@ -0,0 +1,75 @@ +From tytso@mit.edu Wed Dec 3 10:44:07 2008 +From: "Theodore Ts'o" +Date: Sun, 16 Nov 2008 11:05:37 -0500 +Subject: ext4: wait on all pending commits in ext4_sync_fs() +To: stable@kernel.org +Cc: Eric Sandeen , Andrew Morton , Ext4 Developers List , "Theodore Ts'o" , Arthur Jones +Message-ID: <1226851540-8032-18-git-send-email-tytso@mit.edu> + +From: "Theodore Ts'o" + +(cherry picked from commit 14ce0cb411c88681ab8f3a4c9caa7f42e97a3184) + +In ext4_sync_fs, we only wait for a commit to finish if we started it, +but there may be one already in progress which will not be synced. + +In the case of a data=ordered umount with pending long symlinks which +are delayed due to a long list of other I/O on the backing block +device, this causes the buffer associated with the long symlinks to +not be moved to the inode dirty list in the second phase of +fsync_super. Then, before they can be dirtied again, kjournald exits, +seeing the UMOUNT flag and the dirty pages are never written to the +backing block device, causing long symlink corruption and exposing new +or previously freed block data to userspace. + +To ensure all commits are synced, we flush all journal commits now +when sync_fs'ing ext4. + +Signed-off-by: Arthur Jones +Signed-off-by: Andrew Morton +Signed-off-by: "Theodore Ts'o" +Cc: Eric Sandeen +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2920,12 +2920,9 @@ int ext4_force_commit(struct super_block + /* + * Ext4 always journals updates to the superblock itself, so we don't + * have to propagate any other updates to the superblock on disk at this +- * point. Just start an async writeback to get the buffers on their way +- * to the disk. +- * +- * This implicitly triggers the writebehind on sync(). ++ * point. (We can probably nuke this function altogether, and remove ++ * any mention to sb->s_dirt in all of fs/ext4; eventual cleanup...) + */ +- + static void ext4_write_super(struct super_block *sb) + { + if (mutex_trylock(&sb->s_lock) != 0) +@@ -2935,14 +2932,14 @@ static void ext4_write_super(struct supe + + static int ext4_sync_fs(struct super_block *sb, int wait) + { +- tid_t target; ++ int ret = 0; + + sb->s_dirt = 0; +- if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { +- if (wait) +- jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target); +- } +- return 0; ++ if (wait) ++ ret = ext4_force_commit(sb); ++ else ++ jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL); ++ return ret; + } + + /* diff --git a/queue-2.6.27/jbd-ordered-data-integrity-fix.patch b/queue-2.6.27/jbd-ordered-data-integrity-fix.patch new file mode 100644 index 00000000000..db14a0e5c2c --- /dev/null +++ b/queue-2.6.27/jbd-ordered-data-integrity-fix.patch @@ -0,0 +1,71 @@ +From 960a22ae60c8a723bd17da3b929fe0bcea6d007e Mon Sep 17 00:00:00 2001 +From: Hidehiro Kawai +Date: Sat, 18 Oct 2008 20:27:58 -0700 +Subject: jbd: ordered data integrity fix + +From: Hidehiro Kawai + +commit 960a22ae60c8a723bd17da3b929fe0bcea6d007e upstream. + +In ordered mode, if a file data buffer being dirtied exists in the +committing transaction, we write the buffer to the disk, move it from the +committing transaction to the running transaction, then dirty it. But we +don't have to remove the buffer from the committing transaction when the +buffer couldn't be written out, otherwise it would miss the error and the +committing transaction would not abort. + +This patch adds an error check before removing the buffer from the +committing transaction. + +Signed-off-by: Hidehiro Kawai +Acked-by: Jan Kara +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Willy Tarreau +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jbd/transaction.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +--- a/fs/jbd/transaction.c ++++ b/fs/jbd/transaction.c +@@ -954,9 +954,10 @@ int journal_dirty_data(handle_t *handle, + journal_t *journal = handle->h_transaction->t_journal; + int need_brelse = 0; + struct journal_head *jh; ++ int ret = 0; + + if (is_handle_aborted(handle)) +- return 0; ++ return ret; + + jh = journal_add_journal_head(bh); + JBUFFER_TRACE(jh, "entry"); +@@ -1067,7 +1068,16 @@ int journal_dirty_data(handle_t *handle, + time if it is redirtied */ + } + +- /* journal_clean_data_list() may have got there first */ ++ /* ++ * We cannot remove the buffer with io error from the ++ * committing transaction, because otherwise it would ++ * miss the error and the commit would not abort. ++ */ ++ if (unlikely(!buffer_uptodate(bh))) { ++ ret = -EIO; ++ goto no_journal; ++ } ++ + if (jh->b_transaction != NULL) { + JBUFFER_TRACE(jh, "unfile from commit"); + __journal_temp_unlink_buffer(jh); +@@ -1108,7 +1118,7 @@ no_journal: + } + JBUFFER_TRACE(jh, "exit"); + journal_put_journal_head(jh); +- return 0; ++ return ret; + } + + /** diff --git a/queue-2.6.27/jbd2-abort-instead-of-waiting-for-nonexistent-transaction.patch b/queue-2.6.27/jbd2-abort-instead-of-waiting-for-nonexistent-transaction.patch new file mode 100644 index 00000000000..58b5aa91305 --- /dev/null +++ b/queue-2.6.27/jbd2-abort-instead-of-waiting-for-nonexistent-transaction.patch @@ -0,0 +1,70 @@ +From tytso@mit.edu Wed Dec 3 10:04:03 2008 +From: Duane Griffin +Date: Sun, 16 Nov 2008 11:05:29 -0500 +Subject: jbd2: abort instead of waiting for nonexistent transaction +To: stable@kernel.org +Cc: "Theodore Ts'o" , Andrew Morton , Ext4 Developers List , Sami Liedes , Duane Griffin +Message-ID: <1226851540-8032-10-git-send-email-tytso@mit.edu> + + +From: Duane Griffin + +(cherry picked from commit 23f8b79eae8a74e42a006ffa7c456e295c7e1c0d) + +The __jbd2_log_wait_for_space function sits in a loop checkpointing +transactions until there is sufficient space free in the journal. +However, if there are no transactions to be processed (e.g. because the +free space calculation is wrong due to a corrupted filesystem) it will +never progress. + +Check for space being required when no transactions are outstanding and +abort the journal instead of endlessly looping. + +This patch fixes the bug reported by Sami Liedes at: +http://bugzilla.kernel.org/show_bug.cgi?id=10976 + +Signed-off-by: Duane Griffin +Cc: Sami Liedes +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jbd2/checkpoint.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +--- a/fs/jbd2/checkpoint.c ++++ b/fs/jbd2/checkpoint.c +@@ -126,14 +126,29 @@ void __jbd2_log_wait_for_space(journal_t + + /* + * Test again, another process may have checkpointed while we +- * were waiting for the checkpoint lock ++ * were waiting for the checkpoint lock. If there are no ++ * outstanding transactions there is nothing to checkpoint and ++ * we can't make progress. Abort the journal in this case. + */ + spin_lock(&journal->j_state_lock); ++ spin_lock(&journal->j_list_lock); + nblocks = jbd_space_needed(journal); + if (__jbd2_log_space_left(journal) < nblocks) { ++ int chkpt = journal->j_checkpoint_transactions != NULL; ++ ++ spin_unlock(&journal->j_list_lock); + spin_unlock(&journal->j_state_lock); +- jbd2_log_do_checkpoint(journal); ++ if (chkpt) { ++ jbd2_log_do_checkpoint(journal); ++ } else { ++ printk(KERN_ERR "%s: no transactions\n", ++ __func__); ++ jbd2_journal_abort(journal, 0); ++ } ++ + spin_lock(&journal->j_state_lock); ++ } else { ++ spin_unlock(&journal->j_list_lock); + } + mutex_unlock(&journal->j_checkpoint_mutex); + } diff --git a/queue-2.6.27/jbd2-don-t-give-up-looking-for-space-so-easily-in-__jbd2_log_wait_for_space.patch b/queue-2.6.27/jbd2-don-t-give-up-looking-for-space-so-easily-in-__jbd2_log_wait_for_space.patch new file mode 100644 index 00000000000..fb9ddc9e2f8 --- /dev/null +++ b/queue-2.6.27/jbd2-don-t-give-up-looking-for-space-so-easily-in-__jbd2_log_wait_for_space.patch @@ -0,0 +1,98 @@ +From tytso@mit.edu Wed Dec 3 10:43:25 2008 +From: "Theodore Ts'o" +Date: Sun, 16 Nov 2008 11:05:35 -0500 +Subject: jbd2: don't give up looking for space so easily in __jbd2_log_wait_for_space +To: stable@kernel.org +Cc: Toshiyuki Okajima , Ext4 Developers List , "Theodore Ts'o" , Duane Griffin +Message-ID: <1226851540-8032-16-git-send-email-tytso@mit.edu> + +From: "Theodore Ts'o" + +(cherry picked from commit 8c3f25d8950c3e9fe6c9849f88679b3f2a071550) + +Commit 23f8b79e introducd a regression because it assumed that if +there were no transactions ready to be checkpointed, that no progress +could be made on making space available in the journal, and so the +journal should be aborted. This assumption is false; it could be the +case that simply calling jbd2_cleanup_journal_tail() will recover the +necessary space, or, for small journals, the currently committing +transaction could be responsible for chewing up the required space in +the log, so we need to wait for the currently committing transaction +to finish before trying to force a checkpoint operation. + +This patch fixes a bug reported by Mihai Harpau at: +https://bugzilla.redhat.com/show_bug.cgi?id=469582 + +This patch fixes a bug reported by François Valenduc at: +http://bugzilla.kernel.org/show_bug.cgi?id=11840 + +Signed-off-by: "Theodore Ts'o" +Cc: Duane Griffin +Cc: Toshiyuki Okajima +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jbd2/checkpoint.c | 32 +++++++++++++++++++++++++------- + 1 file changed, 25 insertions(+), 7 deletions(-) + +--- a/fs/jbd2/checkpoint.c ++++ b/fs/jbd2/checkpoint.c +@@ -114,7 +114,7 @@ static int __try_to_free_cp_buf(struct j + */ + void __jbd2_log_wait_for_space(journal_t *journal) + { +- int nblocks; ++ int nblocks, space_left; + assert_spin_locked(&journal->j_state_lock); + + nblocks = jbd_space_needed(journal); +@@ -127,25 +127,43 @@ void __jbd2_log_wait_for_space(journal_t + /* + * Test again, another process may have checkpointed while we + * were waiting for the checkpoint lock. If there are no +- * outstanding transactions there is nothing to checkpoint and +- * we can't make progress. Abort the journal in this case. ++ * transactions ready to be checkpointed, try to recover ++ * journal space by calling cleanup_journal_tail(), and if ++ * that doesn't work, by waiting for the currently committing ++ * transaction to complete. If there is absolutely no way ++ * to make progress, this is either a BUG or corrupted ++ * filesystem, so abort the journal and leave a stack ++ * trace for forensic evidence. + */ + spin_lock(&journal->j_state_lock); + spin_lock(&journal->j_list_lock); + nblocks = jbd_space_needed(journal); +- if (__jbd2_log_space_left(journal) < nblocks) { ++ space_left = __jbd2_log_space_left(journal); ++ if (space_left < nblocks) { + int chkpt = journal->j_checkpoint_transactions != NULL; ++ tid_t tid = 0; + ++ if (journal->j_committing_transaction) ++ tid = journal->j_committing_transaction->t_tid; + spin_unlock(&journal->j_list_lock); + spin_unlock(&journal->j_state_lock); + if (chkpt) { + jbd2_log_do_checkpoint(journal); ++ } else if (jbd2_cleanup_journal_tail(journal) == 0) { ++ /* We were able to recover space; yay! */ ++ ; ++ } else if (tid) { ++ jbd2_log_wait_commit(journal, tid); + } else { +- printk(KERN_ERR "%s: no transactions\n", +- __func__); ++ printk(KERN_ERR "%s: needed %d blocks and " ++ "only had %d space available\n", ++ __func__, nblocks, space_left); ++ printk(KERN_ERR "%s: no way to get more " ++ "journal space in %s\n", __func__, ++ journal->j_devname); ++ WARN_ON(1); + jbd2_journal_abort(journal, 0); + } +- + spin_lock(&journal->j_state_lock); + } else { + spin_unlock(&journal->j_list_lock); diff --git a/queue-2.6.27/jbd2-fix-buffer-head-leak-when-writing-the-commit-block.patch b/queue-2.6.27/jbd2-fix-buffer-head-leak-when-writing-the-commit-block.patch new file mode 100644 index 00000000000..595912d664c --- /dev/null +++ b/queue-2.6.27/jbd2-fix-buffer-head-leak-when-writing-the-commit-block.patch @@ -0,0 +1,45 @@ +From tytso@mit.edu Wed Dec 3 10:04:23 2008 +From: "Theodore Ts'o" +Date: Sun, 16 Nov 2008 11:05:30 -0500 +Subject: jbd2: Fix buffer head leak when writing the commit block +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" +Message-ID: <1226851540-8032-11-git-send-email-tytso@mit.edu> + +From: "Theodore Ts'o" + +(cherry picked from commit 45a90bfd90c1215bf824c0f705b409723f52361b) + +Also make sure the buffer heads are marked clean before submitting bh +for writing. The previous code was marking the buffer head dirty, +which would have forced an unneeded write (and seek) to the journal +for no good reason. + +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jbd2/commit.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/fs/jbd2/commit.c ++++ b/fs/jbd2/commit.c +@@ -126,8 +126,7 @@ static int journal_submit_commit_record( + + JBUFFER_TRACE(descriptor, "submit commit block"); + lock_buffer(bh); +- get_bh(bh); +- set_buffer_dirty(bh); ++ clear_buffer_dirty(bh); + set_buffer_uptodate(bh); + bh->b_end_io = journal_end_buffer_io_sync; + +@@ -160,7 +159,7 @@ static int journal_submit_commit_record( + /* And try again, without the barrier */ + lock_buffer(bh); + set_buffer_uptodate(bh); +- set_buffer_dirty(bh); ++ clear_buffer_dirty(bh); + ret = submit_bh(WRITE, bh); + } + *cbh = bh; diff --git a/queue-2.6.27/jbd2-fix-proc-setup-for-devices-that-contain-in-their-names.patch b/queue-2.6.27/jbd2-fix-proc-setup-for-devices-that-contain-in-their-names.patch new file mode 100644 index 00000000000..2d30dd01e36 --- /dev/null +++ b/queue-2.6.27/jbd2-fix-proc-setup-for-devices-that-contain-in-their-names.patch @@ -0,0 +1,105 @@ +From tytso@mit.edu Wed Dec 3 09:56:53 2008 +From: "Theodore Ts'o" +Date: Sun, 16 Nov 2008 11:05:23 -0500 +Subject: jbd2: fix /proc setup for devices that contain '/' in their names +To: stable@kernel.org +Cc: Ext4 Developers List , "Theodore Ts'o" +Message-ID: <1226851540-8032-4-git-send-email-tytso@mit.edu> + +From: "Theodore Ts'o" + +trimed down version of commit 05496769e5da83ce22ed97345afd9c7b71d6bd24 upstream. + +Some devices such as "cciss/c0d0p9" will cause jbd2 setup and teardown +failures when /proc filenames are created with embedded slashes. This +is a slimmed down version of commit 05496769, with the stack reduction +aspects of the patch omitted to meet the -stable criteria. + +Signed-off-by: "Theodore Ts'o" +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jbd2/journal.c | 22 ++++++++++++++-------- + include/linux/jbd2.h | 3 ++- + 2 files changed, 16 insertions(+), 9 deletions(-) + +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -901,10 +901,7 @@ static struct proc_dir_entry *proc_jbd2_ + + static void jbd2_stats_proc_init(journal_t *journal) + { +- char name[BDEVNAME_SIZE]; +- +- bdevname(journal->j_dev, name); +- journal->j_proc_entry = proc_mkdir(name, proc_jbd2_stats); ++ journal->j_proc_entry = proc_mkdir(journal->j_devname, proc_jbd2_stats); + if (journal->j_proc_entry) { + proc_create_data("history", S_IRUGO, journal->j_proc_entry, + &jbd2_seq_history_fops, journal); +@@ -915,12 +912,9 @@ static void jbd2_stats_proc_init(journal + + static void jbd2_stats_proc_exit(journal_t *journal) + { +- char name[BDEVNAME_SIZE]; +- +- bdevname(journal->j_dev, name); + remove_proc_entry("info", journal->j_proc_entry); + remove_proc_entry("history", journal->j_proc_entry); +- remove_proc_entry(name, proc_jbd2_stats); ++ remove_proc_entry(journal->j_devname, proc_jbd2_stats); + } + + static void journal_init_stats(journal_t *journal) +@@ -1018,6 +1012,7 @@ journal_t * jbd2_journal_init_dev(struct + { + journal_t *journal = journal_init_common(); + struct buffer_head *bh; ++ char *p; + int n; + + if (!journal) +@@ -1039,6 +1034,10 @@ journal_t * jbd2_journal_init_dev(struct + journal->j_fs_dev = fs_dev; + journal->j_blk_offset = start; + journal->j_maxlen = len; ++ bdevname(journal->j_dev, journal->j_devname); ++ p = journal->j_devname; ++ while ((p = strchr(p, '/'))) ++ *p = '!'; + jbd2_stats_proc_init(journal); + + bh = __getblk(journal->j_dev, start, journal->j_blocksize); +@@ -1061,6 +1060,7 @@ journal_t * jbd2_journal_init_inode (str + { + struct buffer_head *bh; + journal_t *journal = journal_init_common(); ++ char *p; + int err; + int n; + unsigned long long blocknr; +@@ -1070,6 +1070,12 @@ journal_t * jbd2_journal_init_inode (str + + journal->j_dev = journal->j_fs_dev = inode->i_sb->s_bdev; + journal->j_inode = inode; ++ bdevname(journal->j_dev, journal->j_devname); ++ p = journal->j_devname; ++ while ((p = strchr(p, '/'))) ++ *p = '!'; ++ p = journal->j_devname + strlen(journal->j_devname); ++ sprintf(p, ":%lu", journal->j_inode->i_ino); + jbd_debug(1, + "journal %p: inode %s/%ld, size %Ld, bits %d, blksize %ld\n", + journal, inode->i_sb->s_id, inode->i_ino, +--- a/include/linux/jbd2.h ++++ b/include/linux/jbd2.h +@@ -850,7 +850,8 @@ struct journal_s + */ + struct block_device *j_dev; + int j_blocksize; +- unsigned long long j_blk_offset; ++ unsigned long long j_blk_offset; ++ char j_devname[BDEVNAME_SIZE+24]; + + /* + * Device which holds the client fs. For internal journal this will be diff --git a/queue-2.6.27/series b/queue-2.6.27/series index 82b514b199a..98b89288332 100644 --- a/queue-2.6.27/series +++ b/queue-2.6.27/series @@ -76,3 +76,29 @@ cifs-fix-build-break.patch cifs-fix-check-for-tcon-seal-setting-and-fix-oops-on-failed-mount-from-earlier-patch.patch cifs-prevent-cifs_writepages-from-skipping-unwritten-pages.patch cifs-fix-check-for-dead-tcon-in-smb_init.patch +ext4-update-flex_bg-free-blocks-and-free-inodes-counters-when-resizing.patch +ext4-fix-11321-create-proc-ext4-stats-more-carefully.patch +jbd2-fix-proc-setup-for-devices-that-contain-in-their-names.patch +ext4-add-missing-unlock-in-ext4_check_descriptors-on-error-path.patch +ext4-elevate-write-count-for-migrate-ioctl.patch +ext4-renumber-ext4_ioc_migrate.patch +ext4-jbd2-avoid-warn-messages-when-failing-to-write-to-the-superblock.patch +ext4-fix-initialization-of-uninit-bitmap-blocks.patch +jbd2-abort-instead-of-waiting-for-nonexistent-transaction.patch +jbd2-fix-buffer-head-leak-when-writing-the-commit-block.patch +ext4-fix-xattr-deadlock.patch +ext4-free-ext4_prealloc_space-using-kmem_cache_free.patch +ext4-do-mballoc-init-before-doing-filesystem-recovery.patch +ext4-fix-duplicate-entries-returned-from-getdents-system-call.patch +jbd2-don-t-give-up-looking-for-space-so-easily-in-__jbd2_log_wait_for_space.patch +ext4-convert-to-host-order-before-using-the-values.patch +ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch +ext4-calculate-journal-credits-correctly.patch +ext4-mark-the-buffer_heads-as-dirty-and-uptodate-after-prepare_write.patch +ext4-add-checksum-calculation-when-clearing-uninit-flag-in-ext4_new_inode.patch +ext3-fix-ext3_dx_readdir-hash-collision-handling.patch +ext3-fix-duplicate-entries-returned-from-getdents-system-call.patch +ext3-don-t-try-to-resize-if-there-are-no-reserved-gdt-blocks-left.patch +ext2-fix-ext2-block-reservation-early-enospc-issue.patch +ext3-fix-ext3-block-reservation-early-enospc-issue.patch +jbd-ordered-data-integrity-fix.patch