All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Matthias Goergens <matthias.goergens@gmail.com>
Cc: Theodore Ts'o <tytso@mit.edu>, linux-ext4@vger.kernel.org
Subject: Re: [PATCH e2fsprogs 1/2] libext2fs: fix self-deadlock in flush_cached_blocks() write-error retry
Date: Tue, 22 Sep 2026 11:18:40 -0700	[thread overview]
Message-ID: <20260922181840.GC6239@frogsfrogsfrogs> (raw)
In-Reply-To: <20260922110435.1528332-2-matthias.goergens@gmail.com>

On Tue, Sep 22, 2026 at 07:04:34PM +0800, Matthias Goergens wrote:
> flush_cached_blocks() drops CACHE_MTX before invoking the channel's
> write_error handler, then re-acquires it and jumps to the retry label.
> The retry label is above the while loop, whose first statement acquires
> CACHE_MTX again:
> 
>   retry:
> 	while (errors_found) {
> 		if ((flags & FLUSH_NOLOCK) == 0)
> 			mutex_lock(data, CACHE_MTX);		<- second
> 		...
> 				mutex_unlock(data, CACHE_MTX);
> 				(channel->write_error)(...);
> 				...
> 				mutex_lock(data, CACHE_MTX);		<- first
> 				goto retry;
> 
> The mutex is created with pthread_mutex_init(..., NULL), so it is not
> recursive and the second acquisition blocks the thread that already
> holds it.  The first flush that has to report a write error through a
> registered handler deadlocks, every time.
> 
> Found by fuzzing e2fsck with corrupt images.  An image whose group
> descriptors force bitmap relocation makes e2fsck -fn fail hundreds of
> writes on the read-only device; the aborted run reaches fatal_error(),
> whose io_channel_flush() enters this loop.  e2fsck then sleeps forever
> at 0% CPU and does not respond to SIGTERM, so an init script waiting on
> fsck waits indefinitely.  Read-only checking is enough to reach it.
> 
>   unfixed:  killed after 35s, no progress
>   fixed:    exits 12 after 13ms
> 
> Drop the redundant acquisition; the loop head takes the lock.
> 
> Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
> ---
>  lib/ext2fs/unix_io.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c
> index abd33ba..29968e3 100644
> --- a/lib/ext2fs/unix_io.c
> +++ b/lib/ext2fs/unix_io.c
> @@ -738,7 +738,7 @@ retry:
>  					retval2);
>  				if (err_buf)
>  					ext2fs_free_mem(&err_buf);
> -				mutex_lock(data, CACHE_MTX);
> +				/* the loop head re-acquires CACHE_MTX */

Yep, looks correct.
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

>  				goto retry;
>  			} else
>  				cache->write_err = 0;
> -- 
> 2.55.0
> 
> 

  reply	other threads:[~2026-09-22 18:18 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-22 11:04 [PATCH e2fsprogs 0/2] e2fsck: fix a self-deadlock that hangs fsck on corrupt images Matthias Goergens
2026-09-22 11:04 ` [PATCH e2fsprogs 1/2] libext2fs: fix self-deadlock in flush_cached_blocks() write-error retry Matthias Goergens
2026-09-22 18:18   ` Darrick J. Wong [this message]
2026-09-22 11:04 ` [PATCH e2fsprogs 2/2] tests: add f_cache_mtx_deadlock for the flush_cached_blocks() retry lock Matthias Goergens

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260922181840.GC6239@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=matthias.goergens@gmail.com \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.