diff options
-rw-r--r-- | fs/ext4/super.c | 23 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 27 |
2 files changed, 47 insertions, 3 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 8175318abd84..fb5766e2bffe 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -2810,13 +2810,34 @@ static void ext4_commit_super(struct super_block *sb, | |||
2810 | 2810 | ||
2811 | if (!sbh) | 2811 | if (!sbh) |
2812 | return; | 2812 | return; |
2813 | if (buffer_write_io_error(sbh)) { | ||
2814 | /* | ||
2815 | * Oh, dear. A previous attempt to write the | ||
2816 | * superblock failed. This could happen because the | ||
2817 | * USB device was yanked out. Or it could happen to | ||
2818 | * be a transient write error and maybe the block will | ||
2819 | * be remapped. Nothing we can do but to retry the | ||
2820 | * write and hope for the best. | ||
2821 | */ | ||
2822 | printk(KERN_ERR "ext4: previous I/O error to " | ||
2823 | "superblock detected for %s.\n", sb->s_id); | ||
2824 | clear_buffer_write_io_error(sbh); | ||
2825 | set_buffer_uptodate(sbh); | ||
2826 | } | ||
2813 | es->s_wtime = cpu_to_le32(get_seconds()); | 2827 | es->s_wtime = cpu_to_le32(get_seconds()); |
2814 | ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb)); | 2828 | ext4_free_blocks_count_set(es, ext4_count_free_blocks(sb)); |
2815 | es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb)); | 2829 | es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb)); |
2816 | BUFFER_TRACE(sbh, "marking dirty"); | 2830 | BUFFER_TRACE(sbh, "marking dirty"); |
2817 | mark_buffer_dirty(sbh); | 2831 | mark_buffer_dirty(sbh); |
2818 | if (sync) | 2832 | if (sync) { |
2819 | sync_dirty_buffer(sbh); | 2833 | sync_dirty_buffer(sbh); |
2834 | if (buffer_write_io_error(sbh)) { | ||
2835 | printk(KERN_ERR "ext4: I/O error while writing " | ||
2836 | "superblock for %s.\n", sb->s_id); | ||
2837 | clear_buffer_write_io_error(sbh); | ||
2838 | set_buffer_uptodate(sbh); | ||
2839 | } | ||
2840 | } | ||
2820 | } | 2841 | } |
2821 | 2842 | ||
2822 | 2843 | ||
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 81186a29742e..01c3901c3a07 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -1255,6 +1255,22 @@ void jbd2_journal_update_superblock(journal_t *journal, int wait) | |||
1255 | goto out; | 1255 | goto out; |
1256 | } | 1256 | } |
1257 | 1257 | ||
1258 | if (buffer_write_io_error(bh)) { | ||
1259 | /* | ||
1260 | * Oh, dear. A previous attempt to write the journal | ||
1261 | * superblock failed. This could happen because the | ||
1262 | * USB device was yanked out. Or it could happen to | ||
1263 | * be a transient write error and maybe the block will | ||
1264 | * be remapped. Nothing we can do but to retry the | ||
1265 | * write and hope for the best. | ||
1266 | */ | ||
1267 | printk(KERN_ERR "JBD2: previous I/O error detected " | ||
1268 | "for journal superblock update for %s.\n", | ||
1269 | journal->j_devname); | ||
1270 | clear_buffer_write_io_error(bh); | ||
1271 | set_buffer_uptodate(bh); | ||
1272 | } | ||
1273 | |||
1258 | spin_lock(&journal->j_state_lock); | 1274 | spin_lock(&journal->j_state_lock); |
1259 | jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n", | 1275 | jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n", |
1260 | journal->j_tail, journal->j_tail_sequence, journal->j_errno); | 1276 | journal->j_tail, journal->j_tail_sequence, journal->j_errno); |
@@ -1266,9 +1282,16 @@ void jbd2_journal_update_superblock(journal_t *journal, int wait) | |||
1266 | 1282 | ||
1267 | BUFFER_TRACE(bh, "marking dirty"); | 1283 | BUFFER_TRACE(bh, "marking dirty"); |
1268 | mark_buffer_dirty(bh); | 1284 | mark_buffer_dirty(bh); |
1269 | if (wait) | 1285 | if (wait) { |
1270 | sync_dirty_buffer(bh); | 1286 | sync_dirty_buffer(bh); |
1271 | else | 1287 | if (buffer_write_io_error(bh)) { |
1288 | printk(KERN_ERR "JBD2: I/O error detected " | ||
1289 | "when updating journal superblock for %s.\n", | ||
1290 | journal->j_devname); | ||
1291 | clear_buffer_write_io_error(bh); | ||
1292 | set_buffer_uptodate(bh); | ||
1293 | } | ||
1294 | } else | ||
1272 | ll_rw_block(SWRITE, 1, &bh); | 1295 | ll_rw_block(SWRITE, 1, &bh); |
1273 | 1296 | ||
1274 | out: | 1297 | out: |