| From a17712c8e4be4fa5404d20e9cd3b2b21eae7bc56 Mon Sep 17 00:00:00 2001 |
| From: Jon Derrick <jonathan.derrick@intel.com> |
| Date: Mon, 2 Jul 2018 18:45:18 -0400 |
| Subject: ext4: check superblock mapped prior to committing |
| |
| From: Jon Derrick <jonathan.derrick@intel.com> |
| |
| commit a17712c8e4be4fa5404d20e9cd3b2b21eae7bc56 upstream. |
| |
| This patch attempts to close a hole leading to a BUG seen with hot |
| removals during writes [1]. |
| |
| A block device (NVME namespace in this test case) is formatted to EXT4 |
| without partitions. It's mounted and write I/O is run to a file, then |
| the device is hot removed from the slot. The superblock attempts to be |
| written to the drive which is no longer present. |
| |
| The typical chain of events leading to the BUG: |
| ext4_commit_super() |
| __sync_dirty_buffer() |
| submit_bh() |
| submit_bh_wbc() |
| BUG_ON(!buffer_mapped(bh)); |
| |
| This fix checks for the superblock's buffer head being mapped prior to |
| syncing. |
| |
| [1] https://www.spinics.net/lists/linux-ext4/msg56527.html |
| |
| Signed-off-by: Jon Derrick <jonathan.derrick@intel.com> |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Cc: stable@kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/ext4/super.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| --- a/fs/ext4/super.c |
| +++ b/fs/ext4/super.c |
| @@ -4442,6 +4442,14 @@ static int ext4_commit_super(struct supe |
| |
| if (!sbh || block_device_ejected(sb)) |
| return error; |
| + |
| + /* |
| + * The superblock bh should be mapped, but it might not be if the |
| + * device was hot-removed. Not much we can do but fail the I/O. |
| + */ |
| + if (!buffer_mapped(sbh)) |
| + return error; |
| + |
| if (buffer_write_io_error(sbh)) { |
| /* |
| * Oh, dear. A previous attempt to write the |