From: "Darrick J. Wong" <djwong@kernel.org>
To: tytso@mit.edu
Cc: linux-ext4@vger.kernel.org, linux-ext4@vger.kernel.org
Subject: [PATCH 02/29] libext2fs: fix livelock in the unix io manager
Date: Wed, 21 May 2025 15:35:26 -0700 [thread overview]
Message-ID: <174786677584.1383760.1107858755678329558.stgit@frogsfrogsfrogs> (raw)
In-Reply-To: <174786677421.1383760.15289906755026332870.stgit@frogsfrogsfrogs>
From: Darrick J. Wong <djwong@kernel.org>
generic/441 found a livelock in the unix IO manager. Let's say that
write_primary_superblock decides to call io_channel_set_blksize in the
process of writing the primary super.
unix_set_blksize then takes the cache and bounce mutexes, and calls
flush_cached_blocks. If there are dirty blocks in the cache, they will
be written with raw_write_blk. Unfortunately, that function tries to
take the bounce mutex, which we already hold. At that point, we
livelock fuse2fs.
Cc: <linux-ext4@vger.kernel.org> # v1.46.0
Fixes: f20627cc639ab6 ("libext2fs: add threading support to the I/O manager abstraction")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
lib/ext2fs/unix_io.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c
index b98c44a84bb0af..be70fee38890c8 100644
--- a/lib/ext2fs/unix_io.c
+++ b/lib/ext2fs/unix_io.c
@@ -344,7 +344,8 @@ static errcode_t raw_read_blk(io_channel channel,
return retval;
}
-#define RAW_WRITE_NO_HANDLER 1
+#define RAW_WRITE_NO_HANDLER (1U << 0)
+#define RAW_WRITE_NOLOCK (1U << 1)
static errcode_t raw_write_blk(io_channel channel,
struct unix_private_data *data,
@@ -404,13 +405,15 @@ static errcode_t raw_write_blk(io_channel channel,
(IS_ALIGNED(buf, channel->align) &&
IS_ALIGNED(location, channel->align) &&
IS_ALIGNED(size, channel->align))) {
- mutex_lock(data, BOUNCE_MTX);
+ if (!(flags & RAW_WRITE_NOLOCK))
+ mutex_lock(data, BOUNCE_MTX);
if (ext2fs_llseek(data->dev, location, SEEK_SET) < 0) {
retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
goto error_unlock;
}
actual = write(data->dev, buf, size);
- mutex_unlock(data, BOUNCE_MTX);
+ if (!(flags & RAW_WRITE_NOLOCK))
+ mutex_unlock(data, BOUNCE_MTX);
if (actual < 0) {
retval = errno;
goto error_out;
@@ -445,7 +448,8 @@ static errcode_t raw_write_blk(io_channel channel,
while (size > 0) {
int actual_w;
- mutex_lock(data, BOUNCE_MTX);
+ if (!(flags & RAW_WRITE_NOLOCK))
+ mutex_lock(data, BOUNCE_MTX);
if (size < align_size || offset) {
if (ext2fs_llseek(data->dev, aligned_blk * align_size,
SEEK_SET) < 0) {
@@ -474,7 +478,8 @@ static errcode_t raw_write_blk(io_channel channel,
goto error_unlock;
}
actual_w = write(data->dev, data->bounce, align_size);
- mutex_unlock(data, BOUNCE_MTX);
+ if (!(flags & RAW_WRITE_NOLOCK))
+ mutex_unlock(data, BOUNCE_MTX);
if (actual_w < 0) {
retval = errno;
goto error_out;
@@ -490,7 +495,8 @@ static errcode_t raw_write_blk(io_channel channel,
return 0;
error_unlock:
- mutex_unlock(data, BOUNCE_MTX);
+ if (!(flags & RAW_WRITE_NOLOCK))
+ mutex_unlock(data, BOUNCE_MTX);
error_out:
if (((flags & RAW_WRITE_NO_HANDLER) == 0) && channel->write_error)
retval = (channel->write_error)(channel, block, count, buf,
@@ -673,9 +679,14 @@ static errcode_t flush_cached_blocks(io_channel channel,
if (!cache->in_use)
continue;
if (cache->dirty) {
+ int raw_flags = RAW_WRITE_NO_HANDLER;
+
+ if (flags & FLUSH_NOLOCK)
+ raw_flags |= RAW_WRITE_NOLOCK;
+
retval = raw_write_blk(channel, data,
cache->block, 1, cache->buf,
- RAW_WRITE_NO_HANDLER);
+ raw_flags);
if (retval) {
cache->write_err = 1;
errors_found = 1;
next prev parent reply other threads:[~2025-05-21 22:35 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-21 22:34 [PATCHSET 1/6] fuse2fs: even more bug fixes Darrick J. Wong
2025-05-21 22:35 ` [PATCH 01/29] libext2fs: fix unix io manager invalidation Darrick J. Wong
2025-05-21 22:35 ` Darrick J. Wong [this message]
2025-05-21 22:35 ` [PATCH 03/29] fuse2fs: clean up error messages Darrick J. Wong
2025-05-21 22:35 ` [PATCH 04/29] fuse2fs: fix cache size parsing Darrick J. Wong
2025-05-21 22:36 ` [PATCH 05/29] fuse2fs: compact all the boolean flags in struct fuse2fs Darrick J. Wong
2025-05-21 22:36 ` [PATCH 06/29] fuse2fs: support XATTR_CREATE/REPLACE in setxattr Darrick J. Wong
2025-05-21 22:36 ` [PATCH 07/29] fuse2fs: fix error return handling in op_truncate Darrick J. Wong
2025-05-21 22:37 ` [PATCH 08/29] fuse2fs: flip parameter order in __translate_error Darrick J. Wong
2025-05-21 22:37 ` [PATCH 09/29] fuse2fs: fix CLI argument parsing leaks Darrick J. Wong
2025-05-21 22:37 ` [PATCH 10/29] fuse2fs: allow some control over acls Darrick J. Wong
2025-05-21 22:37 ` [PATCH 11/29] fuse2fs: enable processing of acls in the kernel Darrick J. Wong
2025-05-21 22:38 ` [PATCH 12/29] fuse2fs: make removexattr work correctly Darrick J. Wong
2025-05-21 22:38 ` [PATCH 13/29] fuse2fs: implement O_TRUNC correctly Darrick J. Wong
2025-05-21 22:38 ` [PATCH 14/29] fuse2fs: rearrange check_inum_access parameters a bit Darrick J. Wong
2025-05-21 22:38 ` [PATCH 15/29] fuse2fs: make filesystem corruption a hard error Darrick J. Wong
2025-05-21 22:39 ` [PATCH 16/29] fuse2fs: make internal state " Darrick J. Wong
2025-05-21 22:39 ` [PATCH 17/29] fuse2fs: make bad magic numbers report a corruption error too Darrick J. Wong
2025-05-21 22:39 ` [PATCH 18/29] fuse2fs: return EPERM for write access to EXT2_IMMUTABLE_FL files Darrick J. Wong
2025-05-21 22:39 ` [PATCH 19/29] fuse2fs: check the immutable flag in more places Darrick J. Wong
2025-05-21 22:40 ` [PATCH 20/29] fuse2fs: implement O_APPEND correctly Darrick J. Wong
2025-05-21 22:40 ` [PATCH 21/29] fuse2fs: decode fuse_main error codes Darrick J. Wong
2025-05-21 22:40 ` [PATCH 22/29] fuse2fs: fix fallocate zero range Darrick J. Wong
2025-05-21 22:40 ` [PATCH 23/29] fuse2fs: check for supported xattr name prefixes Darrick J. Wong
2025-05-21 22:41 ` [PATCH 24/29] fuse2fs: fix return value handling Darrick J. Wong
2025-05-21 22:41 ` [PATCH 25/29] fuse2fs: fix removing ea inodes when freeing a file Darrick J. Wong
2025-05-21 22:41 ` [PATCH 26/29] fuse2fs: fix post-EOF preallocation clearing on truncation Darrick J. Wong
2025-05-21 22:41 ` [PATCH 27/29] fuse2fs: also ignore the nodelalloc mount option Darrick J. Wong
2025-05-21 22:42 ` [PATCH 28/29] fuse2fs: propagate default ACLs to new children Darrick J. Wong
2025-05-21 22:42 ` [PATCH 29/29] fuse2fs: fix group membership checking in op_chmod Darrick J. Wong
2025-05-23 14:03 ` [PATCHSET 1/6] fuse2fs: even more bug fixes Theodore Ts'o
2025-05-29 1:37 ` Darrick J. Wong
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=174786677584.1383760.1107858755678329558.stgit@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=linux-ext4@vger.kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox