From: Qu Wenruo <quwenruo.btrfs@gmx.com>
To: "linux-fsdevel@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
linux-xfs@vger.kernel.org,
linux-btrfs <linux-btrfs@vger.kernel.org>,
Christian Brauner <brauner@kernel.org>
Subject: Iomap buffered write short copy handling (with full folio uptodate)
Date: Fri, 21 Mar 2025 18:42:25 +1030 [thread overview]
Message-ID: <1f7da968-4a4c-4d3e-8014-5c2e89d65faa@gmx.com> (raw)
Hi,
I'm wondering if the current iomap short copy handler can handle the
following case correctly:
The fs block size is 4K, page size is 4K, the buffered write is into
file range [0, 4K), the fs is always doing data COW.
The folio at file offset 0 is already uptodate, and the folio size is
also 4K.
- ops->iomap_begin() got called for the range [0, 4K) from iomap_iter()
The fs reserved space of one block of data, and some extra metadata
space.
- copy_folio_from_iter_atomic() only copied 1K bytes
- iomap_write_end() returned true
Since the folio is already uptodate, we can handle the short copy.
The folio is marked dirty and uptodate.
- __iomap_put_folio() unlocked and put the folio
- Now a writeback was triggered for that folio at file offset 0
The folio got properly written to disk.
But remember we have only reserved one block of data space, and that
reserved space is consumed by this writeback.
What's worse is, the fs can even do a snapshot of that involved inode,
so that the current copy of that 1K short-written block will not be
freed.
- copy_folio_from_iter_atomic() copied the remaining 3K bytes
All these happens inside the do {} while () loop of
iomap_write_iter(), thus no iomap_begin() callback can be triggered to
allocate extra space.
- __iomap_put_folio() unlocked and put the folio 0 again.
- Now a writeback got started for that folio at file offset 0 again
This requires another free data block from the fs.
In that case, iomap_begin() only reserved one block of data.
But in the end, we wrote 2 blocks of data due to short copy.
I'm wondering what's the proper handling of short copy during buffered
write.
Is there any special locking I missed preventing the folio from being
written back halfway?
Or is it just too hard to trigger such case in the real world?
Thanks,
Qu
next reply other threads:[~2025-03-21 8:12 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-21 8:12 Qu Wenruo [this message]
2025-03-21 8:57 ` Iomap buffered write short copy handling (with full folio uptodate) Dave Chinner
2025-03-21 9:16 ` Qu Wenruo
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=1f7da968-4a4c-4d3e-8014-5c2e89d65faa@gmx.com \
--to=quwenruo.btrfs@gmx.com \
--cc=brauner@kernel.org \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-xfs@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