diff options
author | Theodore Ts'o <tytso@mit.edu> | 2011-09-09 18:28:51 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-09-09 18:28:51 -0400 |
commit | 7c2e70879fc0949b4220ee61b7c4553f6976a94d (patch) | |
tree | 5eea688d4ca50ec27e9cf59144f257e1683cfeb7 | |
parent | 02fac1297eb3f471a27368271aadd285548297b0 (diff) |
ext4: add ext4-specific kludge to avoid an oops after the disk disappears
The del_gendisk() function uninitializes the disk-specific data
structures, including the bdi structure, without telling anyone
else. Once this happens, any attempt to call mark_buffer_dirty()
(for example, by ext4_commit_super), will cause a kernel OOPS.
Fix this for now until we can fix things in an architecturally correct
way.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r-- | fs/ext4/super.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ee2f74a7084d..5dcd0dacc591 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -414,6 +414,22 @@ static void save_error_info(struct super_block *sb, const char *func, | |||
414 | ext4_commit_super(sb, 1); | 414 | ext4_commit_super(sb, 1); |
415 | } | 415 | } |
416 | 416 | ||
417 | /* | ||
418 | * The del_gendisk() function uninitializes the disk-specific data | ||
419 | * structures, including the bdi structure, without telling anyone | ||
420 | * else. Once this happens, any attempt to call mark_buffer_dirty() | ||
421 | * (for example, by ext4_commit_super), will cause a kernel OOPS. | ||
422 | * This is a kludge to prevent these oops until we can put in a proper | ||
423 | * hook in del_gendisk() to inform the VFS and file system layers. | ||
424 | */ | ||
425 | static int block_device_ejected(struct super_block *sb) | ||
426 | { | ||
427 | struct inode *bd_inode = sb->s_bdev->bd_inode; | ||
428 | struct backing_dev_info *bdi = bd_inode->i_mapping->backing_dev_info; | ||
429 | |||
430 | return bdi->dev == NULL; | ||
431 | } | ||
432 | |||
417 | 433 | ||
418 | /* Deal with the reporting of failure conditions on a filesystem such as | 434 | /* Deal with the reporting of failure conditions on a filesystem such as |
419 | * inconsistencies detected or read IO failures. | 435 | * inconsistencies detected or read IO failures. |
@@ -4072,7 +4088,7 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
4072 | struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; | 4088 | struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; |
4073 | int error = 0; | 4089 | int error = 0; |
4074 | 4090 | ||
4075 | if (!sbh) | 4091 | if (!sbh || block_device_ejected(sb)) |
4076 | return error; | 4092 | return error; |
4077 | if (buffer_write_io_error(sbh)) { | 4093 | if (buffer_write_io_error(sbh)) { |
4078 | /* | 4094 | /* |