Patch "ext4: fix deadlock during page writeback" has been added to the 4.6-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
ext4: fix deadlock during page writeback
to the 4.6-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ext4-fix-deadlock-during-page-writeback.patch
and it can be found in the queue-4.6 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
646caa9c8e196880b41cd3e3d33a2ebc752bdb85Mon Sep 17 00:00:00 2001
From: Jan Kara <[email protected]>
Date: Mon, 4 Jul 2016 10:14:01 -0400
Subject: ext4: fix deadlock during page writeback
From: Jan Kara <[email protected]>
commit 646caa9c8e196880b41cd3e3d33a2ebc752bdb85 upstream.
Commit 06bd3c36a733 (ext4: fix data exposure after a crash) uncovered a deadlock in ext4_writepages() which was previously much harder to hit. After this commit xfstest generic/130 reproduces the deadlock on small filesystems.
The problem happens when ext4_do_update_inode() sets LARGE_FILE feature and marks current inode handle as synchronous. That subsequently results in ext4_journal_stop() called from ext4_writepages() to block waiting for transaction commit while still holding page locks, reference to io_end, and some prepared bio in mpd structure each of which can possibly block transaction commit from completing and thus results in deadlock.
Fix the problem by releasing page locks, io_end reference, and submitting prepared bio before calling ext4_journal_stop().
[ Changed to defer the call to ext4_journal_stop() only if the handle
is synchronous. --tytso ]
--- fs/ext4/inode.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-)
fs/ext4/inode.c +26 -3
@@ -2741,13 +2741,36 @@ retry: done = true; } } -ext4_journal_stop (handle); +/* +* Caution: If the handle is synchronous, +* ext4_journal_stop() can wait for transaction commit +* to finish which may depend on writeback of pages to +* complete or on page lock to be released. In that +* case, we have to wait until after after we have +* submitted all the IO, released page locks we hold, +* and dropped io_end reference (for extent conversion +* to be able to complete) before stopping the handle. +*/ +if (!ext4_handle_valid (handle) || handle->h_sync ==0 ) { +ext4_journal_stop (handle); + handle =NULL ; + }/* Submit prepared bio */ ext4_io_submit (&mpd.io_submit);/* Unlock pages we didn't use */ mpage_release_unused_pages (&mpd, give_up_on_write); -/* Drop our io_end reference we got from init */ -ext4_put_io_end (mpd.io_submit.io_end); +/* +* Drop our io_end reference we got from init. We have +* to be careful and use deferred io_end finishing if +* we are still holding the transaction as we can +* release the last reference to io_end which may end +* up doing unwritten extent conversion. +*/ +if (handle) { +ext4_put_io_end_defer (mpd.io_submit.io_end); +ext4_journal_stop (handle); + }else +ext4_put_io_end (mpd.io_submit.io_end);if (ret == -ENOSPC && sbi->s_journal) {/*
Patches currently in stable-queue which might be from [email protected] are
queue-4.6/ext4-fix-deadlock-during-page-writeback.patch queue-4.6/ext4-short-cut-orphan-cleanup-on-error.patch queue-4.6/udf-prevent-stack-overflow-on-corrupted-filesystem-mount.patch queue-4.6/ext4-don-t-call-ext4_should_journal_data-on-the-journal-inode.patch