From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Long Li <leo.lilong@huawei.com>,
Brian Foster <bfoster@redhat.com>,
Christian Brauner <brauner@kernel.org>,
Sasha Levin <sashal@kernel.org>,
linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.12 04/20] iomap: pass byte granular end position to iomap_add_to_ioend
Date: Mon, 13 Jan 2025 13:34:09 -0500 [thread overview]
Message-ID: <20250113183425.1783715-4-sashal@kernel.org> (raw)
In-Reply-To: <20250113183425.1783715-1-sashal@kernel.org>
From: Long Li <leo.lilong@huawei.com>
[ Upstream commit b44679c63e4d3ac820998b6bd59fba89a72ad3e7 ]
This is a preparatory patch for fixing zero padding issues in concurrent
append write scenarios. In the following patches, we need to obtain
byte-granular writeback end position for io_size trimming after EOF
handling.
Due to concurrent writeback and truncate operations, inode size may
shrink. Resampling inode size would force writeback code to handle the
newly appeared post-EOF blocks, which is undesirable. As Dave
explained in [1]:
"Really, the issue is that writeback mappings have to be able to
handle the range being mapped suddenly appear to be beyond EOF.
This behaviour is a longstanding writeback constraint, and is what
iomap_writepage_handle_eof() is attempting to handle.
We handle this by only sampling i_size_read() whilst we have the
folio locked and can determine the action we should take with that
folio (i.e. nothing, partial zeroing, or skip altogether). Once
we've made the decision that the folio is within EOF and taken
action on it (i.e. moved the folio to writeback state), we cannot
then resample the inode size because a truncate may have started
and changed the inode size."
To avoid resampling inode size after EOF handling, we convert end_pos
to byte-granular writeback position and return it from EOF handling
function.
Since iomap_set_range_dirty() can handle unaligned lengths, this
conversion has no impact on it. However, iomap_find_dirty_range()
requires aligned start and end range to find dirty blocks within the
given range, so the end position needs to be rounded up when passed
to it.
LINK [1]: https://lore.kernel.org/linux-xfs/Z1Gg0pAa54MoeYME@localhost.localdomain/
Signed-off-by: Long Li <leo.lilong@huawei.com>
Link: https://lore.kernel.org/r/20241209114241.3725722-2-leo.lilong@huawei.com
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/iomap/buffered-io.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index ef0b68bccbb6..3ffd9937dd51 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -1764,7 +1764,8 @@ static bool iomap_can_add_to_ioend(struct iomap_writepage_ctx *wpc, loff_t pos)
*/
static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
struct writeback_control *wbc, struct folio *folio,
- struct inode *inode, loff_t pos, unsigned len)
+ struct inode *inode, loff_t pos, loff_t end_pos,
+ unsigned len)
{
struct iomap_folio_state *ifs = folio->private;
size_t poff = offset_in_folio(folio, pos);
@@ -1790,8 +1791,8 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
static int iomap_writepage_map_blocks(struct iomap_writepage_ctx *wpc,
struct writeback_control *wbc, struct folio *folio,
- struct inode *inode, u64 pos, unsigned dirty_len,
- unsigned *count)
+ struct inode *inode, u64 pos, u64 end_pos,
+ unsigned dirty_len, unsigned *count)
{
int error;
@@ -1816,7 +1817,7 @@ static int iomap_writepage_map_blocks(struct iomap_writepage_ctx *wpc,
break;
default:
error = iomap_add_to_ioend(wpc, wbc, folio, inode, pos,
- map_len);
+ end_pos, map_len);
if (!error)
(*count)++;
break;
@@ -1887,11 +1888,11 @@ static bool iomap_writepage_handle_eof(struct folio *folio, struct inode *inode,
* remaining memory is zeroed when mapped, and writes to that
* region are not written out to the file.
*
- * Also adjust the writeback range to skip all blocks entirely
- * beyond i_size.
+ * Also adjust the end_pos to the end of file and skip writeback
+ * for all blocks entirely beyond i_size.
*/
folio_zero_segment(folio, poff, folio_size(folio));
- *end_pos = round_up(isize, i_blocksize(inode));
+ *end_pos = isize;
}
return true;
@@ -1904,6 +1905,7 @@ static int iomap_writepage_map(struct iomap_writepage_ctx *wpc,
struct inode *inode = folio->mapping->host;
u64 pos = folio_pos(folio);
u64 end_pos = pos + folio_size(folio);
+ u64 end_aligned = 0;
unsigned count = 0;
int error = 0;
u32 rlen;
@@ -1945,9 +1947,10 @@ static int iomap_writepage_map(struct iomap_writepage_ctx *wpc,
/*
* Walk through the folio to find dirty areas to write back.
*/
- while ((rlen = iomap_find_dirty_range(folio, &pos, end_pos))) {
+ end_aligned = round_up(end_pos, i_blocksize(inode));
+ while ((rlen = iomap_find_dirty_range(folio, &pos, end_aligned))) {
error = iomap_writepage_map_blocks(wpc, wbc, folio, inode,
- pos, rlen, &count);
+ pos, end_pos, rlen, &count);
if (error)
break;
pos += rlen;
--
2.39.5
next prev parent reply other threads:[~2025-01-13 18:34 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-13 18:34 [PATCH AUTOSEL 6.12 01/20] mac802154: check local interfaces before deleting sdata list Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 02/20] hfs: Sanity check the root record Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 03/20] fs/qnx6: Fix building with GCC 15 Sasha Levin
2025-01-13 18:34 ` Sasha Levin [this message]
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 05/20] fs: fix missing declaration of init_files Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 06/20] kheaders: Ignore silly-rename files Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 07/20] netfs: Fix non-contiguous donation between completed reads Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 08/20] cachefiles: Parse the "secctx" immediately Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 09/20] scsi: ufs: core: Honor runtime/system PM levels if set by host controller drivers Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 10/20] gpio: virtuser: lock up configfs that an instantiated device depends on Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 11/20] gpio: sim: " Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 12/20] selftests: tc-testing: reduce rshift value Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 13/20] ovl: pass realinode to ovl_encode_real_fh() instead of realdentry Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 14/20] platform/x86/intel: power-domains: Add Clearwater Forest support Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 15/20] platform/x86: ISST: Add Clearwater Forest to support list Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 16/20] ACPI: resource: acpi_dev_irq_override(): Check DMI match last Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 17/20] sched_ext: keep running prev when prev->scx.slice != 0 Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 18/20] iomap: avoid avoid truncating 64-bit offset to 32 bits Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 19/20] afs: Fix merge preference rule failure condition Sasha Levin
2025-01-13 18:34 ` [PATCH AUTOSEL 6.12 20/20] poll_wait: add mb() to fix theoretical race between waitqueue_active() and .poll() Sasha Levin
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=20250113183425.1783715-4-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=bfoster@redhat.com \
--cc=brauner@kernel.org \
--cc=leo.lilong@huawei.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
--cc=stable@vger.kernel.org \
/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