Skip to content

Commit b53fdb2

Browse files
Christoph Hellwigbrauner
authored andcommitted
iomap: improve shared block detection in iomap_unshare_iter
Currently iomap_unshare_iter relies on the IOMAP_F_SHARED flag to detect blocks to unshare. This is reasonable, but IOMAP_F_SHARED is also useful for the file system to do internal book keeping for out of place writes. XFS used to that, until it got removed in commit 72a048c ("xfs: only set IOMAP_F_SHARED when providing a srcmap to a write") because unshare for incorrectly unshare such blocks. Add an extra safeguard by checking the explicitly provided srcmap instead of the fallback to the iomap for valid data, as that catches the case where we'd just copy from the same place we'd write to easily, allowing to reinstate setting IOMAP_F_SHARED for all XFS writes that go to the COW fork. Signed-off-by: Christoph Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent 7a9d43e commit b53fdb2

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

fs/iomap/buffered-io.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,16 +1338,25 @@ EXPORT_SYMBOL_GPL(iomap_file_buffered_write_punch_delalloc);
13381338
static loff_t iomap_unshare_iter(struct iomap_iter *iter)
13391339
{
13401340
struct iomap *iomap = &iter->iomap;
1341-
const struct iomap *srcmap = iomap_iter_srcmap(iter);
13421341
loff_t pos = iter->pos;
13431342
loff_t length = iomap_length(iter);
13441343
loff_t written = 0;
13451344

1346-
/* don't bother with blocks that are not shared to start with */
1345+
/* Don't bother with blocks that are not shared to start with. */
13471346
if (!(iomap->flags & IOMAP_F_SHARED))
13481347
return length;
1349-
/* don't bother with holes or unwritten extents */
1350-
if (srcmap->type == IOMAP_HOLE || srcmap->type == IOMAP_UNWRITTEN)
1348+
1349+
/*
1350+
* Don't bother with holes or unwritten extents.
1351+
*
1352+
* Note that we use srcmap directly instead of iomap_iter_srcmap as
1353+
* unsharing requires providing a separate source map, and the presence
1354+
* of one is a good indicator that unsharing is needed, unlike
1355+
* IOMAP_F_SHARED which can be set for any data that goes into the COW
1356+
* fork for XFS.
1357+
*/
1358+
if (iter->srcmap.type == IOMAP_HOLE ||
1359+
iter->srcmap.type == IOMAP_UNWRITTEN)
13511360
return length;
13521361

13531362
do {

0 commit comments

Comments
 (0)