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);