Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1100

kernel-2.6.18-238.el5.src.rpm

From: Hideo AOKI <haoki@redhat.com>
Date: Thu, 21 Aug 2008 12:55:06 -0400
Subject: [fs] jdb: add missing error checks for file data writes
Message-id: 48AD9DEA.6080409@redhat.com
O-Subject: [RHEL 5.3 PATCH 1/6] bz#439581: jdb: add missing error checks for file data writes
Bugzilla: 439581
RH-Acked-by: Josef Bacik <jbacik@redhat.com>
RH-Acked-by: Eric Sandeen <sandeen@redhat.com>

BZ#:
------
https://bugzilla.redhat.com/show_bug.cgi?id=439581

Description and upstream status:
--------------------------------
This patch is a part of the patch named `jbd: don't abort if flushing
file data failed', which can be found at:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff_plain;h=cbe5f466f6995e10a10c7ae66d6dc8608f08a6b8

The original patch does the following two things:

  (1) stop aborting the journal on file data write errors, instead
      just call printk() and set AS_EIO to appropriate address_space
      objects
  (2) add missing error checks for file data writes

This patch does only (2).

The following buffers are newly checked for errors:

  (a) the buffer which has already been written out by pdflush
  (b) the buffer which has been unlocked before scanned in the
      t_locked_list loop

Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>

diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 08f4f90..f87c878 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -174,7 +174,7 @@ void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
 /*
  *  Submit all the data buffers to disk
  */
-static void journal_submit_data_buffers(journal_t *journal,
+static int journal_submit_data_buffers(journal_t *journal,
 				transaction_t *commit_transaction)
 {
 	struct journal_head *jh;
@@ -182,6 +182,7 @@ static void journal_submit_data_buffers(journal_t *journal,
 	int locked;
 	int bufs = 0;
 	struct buffer_head **wbuf = journal->j_wbuf;
+	int err = 0;
 
 	/*
 	 * Whenever we unlock the journal and sleep, things can get added
@@ -255,6 +256,8 @@ write_out_data:
 			put_bh(bh);
 		} else {
 			BUFFER_TRACE(bh, "writeout complete: unfile");
+			if (unlikely(!buffer_uptodate(bh)))
+				err = -EIO;
 			__journal_unfile_buffer(jh);
 			jbd_unlock_bh_state(bh);
 			if (locked)
@@ -273,6 +276,8 @@ write_out_data:
 	}
 	spin_unlock(&journal->j_list_lock);
 	journal_do_submit_data(wbuf, bufs);
+
+	return err;
 }
 
 /*
@@ -412,8 +417,7 @@ void journal_commit_transaction(journal_t *journal)
 	 * Now start flushing things to disk, in the order they appear
 	 * on the transaction lists.  Data blocks go first.
 	 */
-	err = 0;
-	journal_submit_data_buffers(journal, commit_transaction);
+	err = journal_submit_data_buffers(journal, commit_transaction);
 
 	/*
 	 * Wait for all previously submitted IO to complete.
@@ -428,10 +432,11 @@ void journal_commit_transaction(journal_t *journal)
 		if (buffer_locked(bh)) {
 			spin_unlock(&journal->j_list_lock);
 			wait_on_buffer(bh);
-			if (unlikely(!buffer_uptodate(bh)))
-				err = -EIO;
 			spin_lock(&journal->j_list_lock);
 		}
+		if (unlikely(!buffer_uptodate(bh)))
+			err = -EIO;
+
 		if (!inverted_lock(journal, bh)) {
 			put_bh(bh);
 			spin_lock(&journal->j_list_lock);