rpms/kernel/F-9 linux-2.6.27-ext4-fix-bb-prealloc-list-corruption.patch, NONE, 1.1.2.1 linux-2.6.27-ext4-fix-bogus-bug-ons-in-mballoc.patch, NONE, 1.1.2.1 linux-2.6.27-ext4-fix-header-check.patch, NONE, 1.1.2.1 linux-2.6.27-ext4-print-warning-once.patch, NONE, 1.1.2.1 kernel.spec, 1.891.2.36, 1.891.2.37

Chuck Ebbert cebbert at fedoraproject.org
Wed Mar 18 21:10:11 UTC 2009


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/F-9
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv29998

Modified Files:
      Tag: private-fedora-9-2_6_27-branch
	kernel.spec 
Added Files:
      Tag: private-fedora-9-2_6_27-branch
	linux-2.6.27-ext4-fix-bb-prealloc-list-corruption.patch 
	linux-2.6.27-ext4-fix-bogus-bug-ons-in-mballoc.patch 
	linux-2.6.27-ext4-fix-header-check.patch 
	linux-2.6.27-ext4-print-warning-once.patch 
Log Message:
Copy ext4 fixes from F-10 2.6.27 kernel.

linux-2.6.27-ext4-fix-bb-prealloc-list-corruption.patch:

--- NEW FILE linux-2.6.27-ext4-fix-bb-prealloc-list-corruption.patch ---
From: Eric Sandeen <sandeen at redhat.com>
Date: Tue, 17 Mar 2009 03:25:40 +0000 (-0400)
Subject: ext4: fix bb_prealloc_list corruption due to wrong group locking
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=d33a1976fbee1ee321d6f014333d8f03a39d526c

ext4: fix bb_prealloc_list corruption due to wrong group locking

This is for Red Hat bug 490026: EXT4 panic, list corruption in
ext4_mb_new_inode_pa

ext4_lock_group(sb, group) is supposed to protect this list for
each group, and a common code flow to remove an album is like
this:

    ext4_get_group_no_and_offset(sb, pa->pa_pstart, &grp, NULL);
    ext4_lock_group(sb, grp);
    list_del(&pa->pa_group_list);
    ext4_unlock_group(sb, grp);

so it's critical that we get the right group number back for
this prealloc context, to lock the right group (the one
associated with this pa) and prevent concurrent list manipulation.

however, ext4_mb_put_pa() passes in (pa->pa_pstart - 1) with a
comment, "-1 is to protect from crossing allocation group".

This makes sense for the group_pa, where pa_pstart is advanced
by the length which has been used (in ext4_mb_release_context()),
and when the entire length has been used, pa_pstart has been
advanced to the first block of the next group.

However, for inode_pa, pa_pstart is never advanced; it's just
set once to the first block in the group and not moved after
that.  So in this case, if we subtract one in ext4_mb_put_pa(),
we are actually locking the *previous* group, and opening the
race with the other threads which do not subtract off the extra
block.

Signed-off-by: Eric Sandeen <sandeen at redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
---
cebbert: trivial backport

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 41f4348..9f61e62 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -3589,6 +3589,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
 			struct super_block *sb, struct ext4_prealloc_space *pa)
 {
 	unsigned long grp;
+	ext4_fsblk_t grp_blk;
 
 	if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0)
 		return;
@@ -3603,8 +3604,12 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
 	pa->pa_deleted = 1;
 	spin_unlock(&pa->pa_lock);
 
-	/* -1 is to protect from crossing allocation group */
-	ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL);
+	grp_blk = pa->pa_pstart;
+	/* If linear, pa_pstart may be in the next group when pa is used up */
+	if (pa->pa_linear)
+		grp_blk--;
+
+	ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL);
 
 	/*
 	 * possible race:

linux-2.6.27-ext4-fix-bogus-bug-ons-in-mballoc.patch:

--- NEW FILE linux-2.6.27-ext4-fix-bogus-bug-ons-in-mballoc.patch ---
From: Eric Sandeen <sandeen at redhat.com>
Date: Sat, 14 Mar 2009 15:51:46 +0000 (-0400)
Subject: ext4: fix bogus BUG_ONs in in mballoc code
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8d03c7a0c550e7ab24cadcef5e66656bfadec8b9

ext4: fix bogus BUG_ONs in in mballoc code

Thiemo Nagel reported that:

# dd if=/dev/zero of=image.ext4 bs=1M count=2
# mkfs.ext4 -v -F -b 1024 -m 0 -g 512 -G 4 -I 128 -N 1 \
  -O large_file,dir_index,flex_bg,extent,sparse_super image.ext4
# mount -o loop image.ext4 mnt/
# dd if=/dev/zero of=mnt/file

oopsed, with a BUG_ON in ext4_mb_normalize_request because
size == EXT4_BLOCKS_PER_GROUP

It appears to me (esp. after talking to Andreas) that the BUG_ON
is bogus; a request of exactly EXT4_BLOCKS_PER_GROUP should
be allowed, though larger sizes do indicate a problem.

Fix that an another (apparently rare) codepath with a similar check.

Reported-by: Thiemo Nagel <thiemo.nagel at ph.tum.de>
Signed-off-by: Eric Sandeen <sandeen at redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
---

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 4415bee..41f4348 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -1447,7 +1447,7 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac,
 	struct ext4_free_extent *gex = &ac->ac_g_ex;
 
 	BUG_ON(ex->fe_len <= 0);
-	BUG_ON(ex->fe_len >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
+	BUG_ON(ex->fe_len > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
 	BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
 	BUG_ON(ac->ac_status != AC_STATUS_CONTINUE);
 
@@ -3292,7 +3292,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
 	}
 	BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&
 			start > ac->ac_o_ex.fe_logical);
-	BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
+	BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));
 
 	/* now prepare goal request */
 

linux-2.6.27-ext4-fix-header-check.patch:

--- NEW FILE linux-2.6.27-ext4-fix-header-check.patch ---
From: Eric Sandeen <sandeen at redhat.com>
Date: Tue, 10 Mar 2009 22:18:47 +0000 (-0400)
Subject: ext4: fix header check in ext4_ext_search_right() for deep extent trees.
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftytso%2Fext4.git;a=commitdiff_plain;h=402af9e0b37a46e1dfb552e761b76c84df089c5a

ext4: fix header check in ext4_ext_search_right() for deep extent trees.

The ext4_ext_search_right() function is confusing; it uses a
"depth" variable which is 0 at the root and maximum at the leaves,
but the on-disk metadata uses a "depth" (actually eh_depth) which
is opposite: maximum at the root, and 0 at the leaves.

The ext4_ext_check_header() function is given a depth and checks
the header agaisnt that depth; it expects the on-disk semantics,
but we are giving it the opposite in the while loop in this
function.  We should be giving it the on-disk notion of "depth"
which we can get from (p_depth - depth) - and if you look, the last
(more commonly hit) call to ext4_ext_check_header() does just this.

Sending in the wrong depth results in (incorrect) messages
about corruption:

EXT4-fs error (device sdb1): ext4_ext_search_right: bad header
in inode #2621457: unexpected eh_depth - magic f30a, entries 340,
max 340(0), depth 1(2)

http://bugzilla.kernel.org/show_bug.cgi?id=12821

Reported-by: David Dindorp <ddi at dubex.dk>
Signed-off-by: Eric Sandeen <sandeen at redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
---

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index e2eab19..e0aa4fe 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1122,7 +1122,8 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
 	struct ext4_extent_idx *ix;
 	struct ext4_extent *ex;
 	ext4_fsblk_t block;
-	int depth, ee_len;
+	int depth;	/* Note, NOT eh_depth; depth from top of tree */
+	int ee_len;
 
 	BUG_ON(path == NULL);
 	depth = path->p_depth;
@@ -1179,7 +1180,8 @@ got_index:
 		if (bh == NULL)
 			return -EIO;
 		eh = ext_block_hdr(bh);
-		if (ext4_ext_check_header(inode, eh, depth)) {
+		/* subtract from p_depth to get proper eh_depth */
+		if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) {
 			put_bh(bh);
 			return -EIO;
 		}

linux-2.6.27-ext4-print-warning-once.patch:

--- NEW FILE linux-2.6.27-ext4-print-warning-once.patch ---
From: Theodore Ts'o <tytso at mit.edu>
Date: Thu, 12 Mar 2009 16:20:01 +0000 (-0400)
Subject: ext4: Print the find_group_flex() warning only once
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftytso%2Fext4.git;a=commitdiff_plain;h=e8eb6f8319eb2536d292fc18fe14e745c970049a

ext4: Print the find_group_flex() warning only once

This is a short-term warning, and even printk_ratelimit() can result
in too much noise in system logs.  So only print it once as a warning.

Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
---

diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 627f8c3..2d2b358 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -698,6 +698,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
 	struct inode *ret;
 	ext4_group_t i;
 	int free = 0;
+	static int once = 1;
 	ext4_group_t flex_group;
 
 	/* Cannot create files in a deleted directory */
@@ -719,7 +720,8 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode)
 		ret2 = find_group_flex(sb, dir, &group);
 		if (ret2 == -1) {
 			ret2 = find_group_other(sb, dir, &group);
-			if (ret2 == 0 && printk_ratelimit())
+			if (ret2 == 0 && once)
+				once = 0;
 				printk(KERN_NOTICE "ext4: find_group_flex "
 				       "failed, fallback succeeded dir %lu\n",
 				       dir->i_ino);


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-9/kernel.spec,v
retrieving revision 1.891.2.36
retrieving revision 1.891.2.37
diff -u -r1.891.2.36 -r1.891.2.37
--- kernel.spec	17 Mar 2009 19:19:44 -0000	1.891.2.36
+++ kernel.spec	18 Mar 2009 21:10:08 -0000	1.891.2.37
@@ -733,10 +733,16 @@
 # get rid of imacfb and make efifb work everywhere it was used
 Patch2600: linux-2.6-merge-efifb-imacfb.patch
 
-Patch2902: linux-2.6.27-ext4-rename-ext4dev-to-ext4.patch
-Patch2903: linux-2.6.27.9-ext4-cap-check-delay.patch
-
-# next round of ext4 patches for -stable
+# ext4
+Patch2900: linux-2.6.27-ext4-rename-ext4dev-to-ext4.patch
+Patch2901: linux-2.6.27.9-ext4-cap-check-delay.patch
+# don't spew warnings when using fallback allocator
+Patch2902: linux-2.6.27-ext4-print-warning-once.patch
+# fix extent header checking
+Patch2903: linux-2.6.27-ext4-fix-header-check.patch
+# from 2.6.29-rc, 18 mar 2009
+Patch2904: linux-2.6.27-ext4-fix-bb-prealloc-list-corruption.patch
+Patch2905: linux-2.6.27-ext4-fix-bogus-bug-ons-in-mballoc.patch
 
 # Add better support for DMI-based autoloading
 Patch3110: linux-2.6-dmi-autoload.patch
@@ -1314,6 +1320,10 @@
 # Filesystem patches
 ApplyPatch linux-2.6.27-ext4-rename-ext4dev-to-ext4.patch
 ApplyPatch linux-2.6.27.9-ext4-cap-check-delay.patch
+ApplyPatch linux-2.6.27-ext4-print-warning-once.patch
+ApplyPatch linux-2.6.27-ext4-fix-header-check.patch
+ApplyPatch linux-2.6.27-ext4-fix-bb-prealloc-list-corruption.patch
+ApplyPatch linux-2.6.27-ext4-fix-bogus-bug-ons-in-mballoc.patch
 
 # linux1394 git patches
 ApplyPatch linux-2.6-firewire-git-update.patch
@@ -1929,6 +1939,9 @@
 %kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL}.xen -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.xen.conf %{with_xen} xen
 
 %changelog
+* Wed Mar 18 2009 Chuck Ebbert <cebbert at redhat.com> 2.6.27.20-78.2.37
+- Copy ext4 fixes from F-10 2.6.27 kernel.
+
 * Tue Mar 17 2009 Chuck Ebbert <cebbert at redhat.com> 2.6.27.20-78.2.36
 - 2.6.27.20
 - Dropped patches, merged in -stable:




More information about the fedora-extras-commits mailing list