aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/super.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@us.ibm.com>2010-10-04 15:35:05 -0400
committerJan Kara <jack@suse.cz>2010-10-27 19:30:02 -0400
commitdff6825e9fde93891e60751e01480337a991235e (patch)
tree3b243584ee48752096b110c04ecd803e285325ae /fs/ext3/super.c
parent8117f98c058dbe463eaba2b51b84d19bd5d78804 (diff)
ext3/jbd: Avoid WARN() messages when failing to write the superblock
This fixes a WARN backtrace in mark_buffer_dirty() that occurs during unmount when the underlying block device is removed. This bug has been seen on System Z when removing all paths from a multipath-backed ext3 mount; on System P when injecting enough PCI EEH errors to make the SCSI controller go offline; and similar warnings have been seen (and patched) with ext2/ext4. The super block update from a previous operation has marked the buffer as in error, and the flag has to be cleared before doing the update. Similar changes have been made to ext4 by commit 914258bf2cb22bf4336a1b1d90c551b4b11ca5aa. Signed-off-by: Darrick J. Wong <djwong@us.ibm.com> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r--fs/ext3/super.c24
1 files changed, 23 insertions, 1 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