rpms/kernel/F-9 linux-2.6.27-ext4-calculate-journal-credits-correctly.patch, NONE, 1.1 linux-2.6.28-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch, NONE, 1.1 linux-2.6.28-jbd2-dont-give-up-looking-for-space-so-easily.patch, NONE, 1.1 kernel.spec, 1.842, 1.843

Chuck Ebbert cebbert at fedoraproject.org
Sat Nov 8 22:14:19 UTC 2008


Author: cebbert

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

Modified Files:
	kernel.spec 
Added Files:
	linux-2.6.27-ext4-calculate-journal-credits-correctly.patch 
	linux-2.6.28-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch 
	linux-2.6.28-jbd2-dont-give-up-looking-for-space-so-easily.patch 
Log Message:
Fix last-minute ext4 / jbd2 bugs (#469582)

linux-2.6.27-ext4-calculate-journal-credits-correctly.patch:

--- NEW FILE linux-2.6.27-ext4-calculate-journal-credits-correctly.patch ---
From: Theodore Ts'o <tytso at mit.edu>
Date: Thu, 6 Nov 2008 21:49:36 +0000 (-0500)
Subject: ext4: calculate journal credits correctly
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=ac51d83705c2a38c71f39cde99708b14e6212a60

ext4: calculate journal credits correctly

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" <tytso at mit.edu>
---

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 8dbf695..5a130b5 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4580,9 +4580,10 @@ static int ext4_indirect_trans_blocks(struct inode *inode, int nrblocks,
 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

linux-2.6.28-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch:

--- NEW FILE linux-2.6.28-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch ---
From: Theodore Ts'o <tytso at mit.edu>
Date: Mon, 3 Nov 2008 23:10:55 +0000 (-0500)
Subject: ext4: wait on all pending commits in ext4_sync_fs()
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=14ce0cb411c88681ab8f3a4c9caa7f42e97a3184

ext4: wait on all pending commits in ext4_sync_fs()

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 <ajones at riverbed.com>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
Cc: Eric Sandeen <sandeen at redhat.com>
Cc: <linux-ext4 at vger.kernel.org>
---

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index e27acd1..e4a241c 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2884,12 +2884,9 @@ int ext4_force_commit(struct super_block *sb)
 /*
  * 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)
@@ -2899,15 +2896,15 @@ static void ext4_write_super(struct super_block *sb)
 
 static int ext4_sync_fs(struct super_block *sb, int wait)
 {
-	tid_t target;
+	int ret = 0;
 
 	trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait);
 	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;
 }
 
 /*

linux-2.6.28-jbd2-dont-give-up-looking-for-space-so-easily.patch:

--- NEW FILE linux-2.6.28-jbd2-dont-give-up-looking-for-space-so-easily.patch ---
From: Theodore Ts'o <tytso at mit.edu>
Date: Fri, 7 Nov 2008 03:38:07 +0000 (-0500)
Subject: jbd2: don't give up looking for space so easily in __jbd2_log_wait_for_space
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8c3f25d8950c3e9fe6c9849f88679b3f2a071550

jbd2: don't give up looking for space so easily in __jbd2_log_wait_for_space

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" <tytso at mit.edu>
Cc: Duane Griffin <duaneg at dghda.com>
Cc: Toshiyuki Okajima <toshi.okajima at jp.fujitsu.com>
---

diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index 9203c33..9497718 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -116,7 +116,7 @@ static int __try_to_free_cp_buf(struct journal_head *jh)
  */
 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);
@@ -129,25 +129,43 @@ void __jbd2_log_wait_for_space(journal_t *journal)
 		/*
 		 * 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);


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-9/kernel.spec,v
retrieving revision 1.842
retrieving revision 1.843
diff -u -r1.842 -r1.843
--- kernel.spec	8 Nov 2008 21:20:37 -0000	1.842
+++ kernel.spec	8 Nov 2008 22:13:48 -0000	1.843
@@ -710,6 +710,10 @@
 Patch2902: linux-2.6.27-ext-dir-corruption-fix.patch
 Patch2903: linux-2.6.27-delay-ext4-free-block-cap-check.patch
 
+Patch2905: linux-2.6.27-ext4-calculate-journal-credits-correctly.patch
+Patch2906: linux-2.6.28-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch
+Patch2907: linux-2.6.28-jbd2-dont-give-up-looking-for-space-so-easily.patch
+
 # cciss sysfs links are broken
 Patch3000: linux-2.6-blk-cciss-fix-regression-sysfs-symlink-missing.patch
 
@@ -1277,6 +1281,10 @@
 # Delay capability() checks 'til last in ext4
 ApplyPatch linux-2.6.27-delay-ext4-free-block-cap-check.patch
 
+# minimal set of ext4 fixes from upstream
+ApplyPatch linux-2.6.27-ext4-calculate-journal-credits-correctly.patch
+ApplyPatch linux-2.6.28-ext4-wait-on-all-pending-commits-in-ext4_sync_fs.patch
+ApplyPatch linux-2.6.28-jbd2-dont-give-up-looking-for-space-so-easily.patch
 
 # linux1394 git patches
 ApplyPatch linux-2.6-firewire-git-update.patch
@@ -1892,6 +1900,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
+* Sat Nov 08 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.27.5-30
+- Fix last-minute ext4 / jbd2 bugs (#469582)
+
 * Sat Nov 08 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.27.5-29
 - Fix some more of the docking bugs in 2.6.27 (#451399)
 




More information about the fedora-extras-commits mailing list