From 4f6ba5c553600ce852a09542d45be9680ae13bf7 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 4 Jul 2018 00:06:19 -0400 Subject: [PATCH] add patch check-superblock-mapped-prior-to-committing --- check-superblock-mapped-prior-to-committing | 53 +++++++++++++++++++++++++++++ series | 1 + timestamps | 10 ++++-- 3 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 check-superblock-mapped-prior-to-committing diff --git a/check-superblock-mapped-prior-to-committing b/check-superblock-mapped-prior-to-committing new file mode 100644 index 00000000..be74184c --- /dev/null +++ b/check-superblock-mapped-prior-to-committing @@ -0,0 +1,53 @@ +ext4: check superblock mapped prior to committing + +From: Jon Derrick + +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 +Signed-off-by: Theodore Ts'o +--- + fs/ext4/super.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 0c4c220..ee33233 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -4736,6 +4736,14 @@ static int ext4_commit_super(struct super_block *sb, int sync) + + 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 the file system is mounted read-only, don't update the + * superblock write time. This avoids updating the superblock +-- +2.7.4 + + diff --git a/series b/series index 64caa4eb..d18b0eb1 100644 --- a/series +++ b/series @@ -14,6 +14,7 @@ dont-mark-buffer-has-modified-if-the-handle-is-out-of-credits avoid-running-out-journal-credits-when-appending-to-an-inline-file add-more-inode-number-paranoia-checks add-more-mount-time-superblock-checking +check-superblock-mapped-prior-to-committing #################################################### # unstable patches diff --git a/timestamps b/timestamps index 1f177830..ae03d499 100755 --- a/timestamps +++ b/timestamps @@ -47,7 +47,11 @@ touch -d @1529194905 dont-mark-buffer-has-modified-if-the-handle-is-out-of-credi touch -d @1529206919 avoid-running-out-journal-credits-when-appending-to-an-inline-file touch -d @1529210474 add-more-inode-number-paranoia-checks touch -d @1529210534 stable-boundary -touch -d @1529273334 series touch -d @1529273480 add-more-mount-time-superblock-checking -touch -d @1529273480 status -touch -d @1530546268 timestamps +touch -d @1530569804 handle-layout-changes-to-pinned-DAX-mappings.mbox +touch -d @1530569831 dax_layout_busy_warn_on_not_exceptional +touch -d @1530569881 handle-layout-changes-to-pinned-DAX-mappings +touch -d @1530571518 check-superblock-mapped-prior-to-committing +touch -d @1530677152 series +touch -d @1530677156 status +touch -d @1530677170 timestamps -- 2.11.4.GIT