aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext3/super.c24
-rw-r--r--fs/jbd/journal.c30
2 files changed, 51 insertions, 3 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 5dbf4dba03c4..3ef272488ac9 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2361,6 +2361,21 @@ static int ext3_commit_super(struct super_block *sb,
2361 2361
2362 if (!sbh) 2362 if (!sbh)
2363 return error; 2363 return error;
2364
2365 if (buffer_write_io_error(sbh)) {
2366 /*
2367 * Oh, dear. A previous attempt to write the
2368 * superblock failed. This could happen because the
2369 * USB device was yanked out. Or it could happen to
2370 * be a transient write error and maybe the block will
2371 * be remapped. Nothing we can do but to retry the
2372 * write and hope for the best.
2373 */
2374 ext3_msg(sb, KERN_ERR, "previous I/O error to "
2375 "superblock detected");
2376 clear_buffer_write_io_error(sbh);
2377 set_buffer_uptodate(sbh);
2378 }
2364 /* 2379 /*
2365 * If the file system is mounted read-only, don't update the 2380 * If the file system is mounted read-only, don't update the
2366 * superblock write time. This avoids updating the superblock 2381 * superblock write time. This avoids updating the superblock
@@ -2377,8 +2392,15 @@ static int ext3_commit_super(struct super_block *sb,
2377 es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb)); 2392 es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb));
2378 BUFFER_TRACE(sbh, "marking dirty"); 2393 BUFFER_TRACE(sbh, "marking dirty");
2379 mark_buffer_dirty(sbh); 2394 mark_buffer_dirty(sbh);
2380 if (sync) 2395 if (sync) {
2381 error = sync_dirty_buffer(sbh); 2396 error = sync_dirty_buffer(sbh);
2397 if (buffer_write_io_error(sbh)) {
2398 ext3_msg(sb, KERN_ERR, "I/O error while writing "
2399 "superblock");
2400 clear_buffer_write_io_error(sbh);
2401 set_buffer_uptodate(sbh);
2402 }
2403 }
2382 return error; 2404 return error;
2383} 2405}
2384 2406
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
86static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); 86static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
87static void __journal_abort_soft (journal_t *journal, int errno); 87static void __journal_abort_soft (journal_t *journal, int errno);
88static 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
1030out: 1056out: