diff options
Diffstat (limited to 'fs/jbd')
-rw-r--r-- | fs/jbd/journal.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index d7a86935553a..e56117651826 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -85,6 +85,7 @@ EXPORT_SYMBOL(journal_force_commit); | |||
85 | 85 | ||
86 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); | 86 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); |
87 | static void __journal_abort_soft (journal_t *journal, int errno); | 87 | static void __journal_abort_soft (journal_t *journal, int errno); |
88 | static const char *journal_dev_name(journal_t *journal, char *buffer); | ||
88 | 89 | ||
89 | /* | 90 | /* |
90 | * Helper function used to manage commit timeouts | 91 | * Helper function used to manage commit timeouts |
@@ -1011,6 +1012,23 @@ void journal_update_superblock(journal_t *journal, int wait) | |||
1011 | goto out; | 1012 | goto out; |
1012 | } | 1013 | } |
1013 | 1014 | ||
1015 | if (buffer_write_io_error(bh)) { | ||
1016 | char b[BDEVNAME_SIZE]; | ||
1017 | /* | ||
1018 | * Oh, dear. A previous attempt to write the journal | ||
1019 | * superblock failed. This could happen because the | ||
1020 | * USB device was yanked out. Or it could happen to | ||
1021 | * be a transient write error and maybe the block will | ||
1022 | * be remapped. Nothing we can do but to retry the | ||
1023 | * write and hope for the best. | ||
1024 | */ | ||
1025 | printk(KERN_ERR "JBD: previous I/O error detected " | ||
1026 | "for journal superblock update for %s.\n", | ||
1027 | journal_dev_name(journal, b)); | ||
1028 | clear_buffer_write_io_error(bh); | ||
1029 | set_buffer_uptodate(bh); | ||
1030 | } | ||
1031 | |||
1014 | spin_lock(&journal->j_state_lock); | 1032 | spin_lock(&journal->j_state_lock); |
1015 | jbd_debug(1,"JBD: updating superblock (start %u, seq %d, errno %d)\n", | 1033 | jbd_debug(1,"JBD: updating superblock (start %u, seq %d, errno %d)\n", |
1016 | journal->j_tail, journal->j_tail_sequence, journal->j_errno); | 1034 | journal->j_tail, journal->j_tail_sequence, journal->j_errno); |
@@ -1022,9 +1040,17 @@ void journal_update_superblock(journal_t *journal, int wait) | |||
1022 | 1040 | ||
1023 | BUFFER_TRACE(bh, "marking dirty"); | 1041 | BUFFER_TRACE(bh, "marking dirty"); |
1024 | mark_buffer_dirty(bh); | 1042 | mark_buffer_dirty(bh); |
1025 | if (wait) | 1043 | if (wait) { |
1026 | sync_dirty_buffer(bh); | 1044 | sync_dirty_buffer(bh); |
1027 | else | 1045 | if (buffer_write_io_error(bh)) { |
1046 | char b[BDEVNAME_SIZE]; | ||
1047 | printk(KERN_ERR "JBD: I/O error detected " | ||
1048 | "when updating journal superblock for %s.\n", | ||
1049 | journal_dev_name(journal, b)); | ||
1050 | clear_buffer_write_io_error(bh); | ||
1051 | set_buffer_uptodate(bh); | ||
1052 | } | ||
1053 | } else | ||
1028 | write_dirty_buffer(bh, WRITE); | 1054 | write_dirty_buffer(bh, WRITE); |
1029 | 1055 | ||
1030 | out: | 1056 | out: |