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 914258bf2c
.
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
committed by
Jan Kara
parent
8117f98c05
commit
dff6825e9f
@@ -2361,6 +2361,21 @@ static int ext3_commit_super(struct super_block *sb,
|
||||
|
||||
if (!sbh)
|
||||
return error;
|
||||
|
||||
if (buffer_write_io_error(sbh)) {
|
||||
/*
|
||||
* Oh, dear. A previous attempt to write the
|
||||
* superblock failed. This could happen because the
|
||||
* USB device was yanked out. Or it could happen to
|
||||
* be a transient write error and maybe the block will
|
||||
* be remapped. Nothing we can do but to retry the
|
||||
* write and hope for the best.
|
||||
*/
|
||||
ext3_msg(sb, KERN_ERR, "previous I/O error to "
|
||||
"superblock detected");
|
||||
clear_buffer_write_io_error(sbh);
|
||||
set_buffer_uptodate(sbh);
|
||||
}
|
||||
/*
|
||||
* If the file system is mounted read-only, don't update the
|
||||
* superblock write time. This avoids updating the superblock
|
||||
@@ -2377,8 +2392,15 @@ static int ext3_commit_super(struct super_block *sb,
|
||||
es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb));
|
||||
BUFFER_TRACE(sbh, "marking dirty");
|
||||
mark_buffer_dirty(sbh);
|
||||
if (sync)
|
||||
if (sync) {
|
||||
error = sync_dirty_buffer(sbh);
|
||||
if (buffer_write_io_error(sbh)) {
|
||||
ext3_msg(sb, KERN_ERR, "I/O error while writing "
|
||||
"superblock");
|
||||
clear_buffer_write_io_error(sbh);
|
||||
set_buffer_uptodate(sbh);
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user