summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorHidehiro Kawai <hidehiro.kawai.ez@hitachi.com>2008-08-01 04:26:04 +0200
committerTheodore Ts'o <tytso@mit.edu>2008-08-01 04:26:04 +0200
commite9e34f4e8f42177c66754fec1edfd35e70c18f99 (patch)
tree659e21aa3ea54c7643c0e3112aa3aba54ca7b4cf /fs
parentext4: don't read inode block if the buffer has a write error (diff)
downloadlinux-e9e34f4e8f42177c66754fec1edfd35e70c18f99.tar.xz
linux-e9e34f4e8f42177c66754fec1edfd35e70c18f99.zip
jbd2: don't abort if flushing file data failed
In ordered mode, the current jbd2 aborts the journal if a file data buffer has an error. But this behavior is unintended, and we found that it has been adopted accidentally. This patch undoes it and just calls printk() instead of aborting the journal. Unlike a similar patch for ext3/jbd, file data buffers are written via generic_writepages(). But we also need to set AS_EIO into their mappings because wait_on_page_writeback_range() clears AS_EIO before a user process sees it. Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/jbd2/commit.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index f8b3be873226..adf0395f318e 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -262,8 +262,18 @@ static int journal_finish_inode_data_buffers(journal_t *journal,
jinode->i_flags |= JI_COMMIT_RUNNING;
spin_unlock(&journal->j_list_lock);
err = filemap_fdatawait(jinode->i_vfs_inode->i_mapping);
- if (!ret)
- ret = err;
+ if (err) {
+ /*
+ * Because AS_EIO is cleared by
+ * wait_on_page_writeback_range(), set it again so
+ * that user process can get -EIO from fsync().
+ */
+ set_bit(AS_EIO,
+ &jinode->i_vfs_inode->i_mapping->flags);
+
+ if (!ret)
+ ret = err;
+ }
spin_lock(&journal->j_list_lock);
jinode->i_flags &= ~JI_COMMIT_RUNNING;
wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING);
@@ -670,8 +680,14 @@ start_journal_io:
* commit block, which happens below in such setting.
*/
err = journal_finish_inode_data_buffers(journal, commit_transaction);
- if (err)
- jbd2_journal_abort(journal, err);
+ if (err) {
+ char b[BDEVNAME_SIZE];
+
+ printk(KERN_WARNING
+ "JBD2: Detected IO errors while flushing file data "
+ "on %s\n", bdevname(journal->j_fs_dev, b));
+ err = 0;
+ }
/* Lo and behold: we have just managed to send a transaction to
the log. Before we can commit it, wait for the IO so far to