Skip to content

Commit 6ef6a0e

Browse files
Darrick J. Wongbrauner
authored andcommitted
iomap: share iomap_unshare_iter predicate code with fsdax
The predicate code that iomap_unshare_iter uses to decide if it's really needs to unshare a file range mapping should be shared with the fsdax version, because right now they're opencoded and inconsistent. Note that we simplify the predicate logic a bit -- we no longer allow unsharing of inline data mappings, but there aren't any filesystems that allow shared inline data currently. This is a fix in the sense that it should have been ported to fsdax. Fixes: b53fdb2 ("iomap: improve shared block detection in iomap_unshare_iter") Signed-off-by: Darrick J. Wong <[email protected]> Link: https://lore.kernel.org/r/172796813294.1131942.15762084021076932620.stgit@frogsfrogsfrogs Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent b8c4076 commit 6ef6a0e

File tree

3 files changed

+18
-16
lines changed

3 files changed

+18
-16
lines changed

fs/dax.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,8 +1268,7 @@ static s64 dax_unshare_iter(struct iomap_iter *iter)
12681268
s64 ret = 0;
12691269
void *daddr = NULL, *saddr = NULL;
12701270

1271-
/* don't bother with blocks that are not shared to start with */
1272-
if (!(iomap->flags & IOMAP_F_SHARED))
1271+
if (!iomap_want_unshare_iter(iter))
12731272
return length;
12741273

12751274
id = dax_read_lock();

fs/iomap/buffered-io.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,29 +1309,31 @@ void iomap_file_buffered_write_punch_delalloc(struct inode *inode,
13091309
}
13101310
EXPORT_SYMBOL_GPL(iomap_file_buffered_write_punch_delalloc);
13111311

1312-
static loff_t iomap_unshare_iter(struct iomap_iter *iter)
1312+
bool iomap_want_unshare_iter(const struct iomap_iter *iter)
13131313
{
1314-
struct iomap *iomap = &iter->iomap;
1315-
loff_t pos = iter->pos;
1316-
loff_t length = iomap_length(iter);
1317-
loff_t written = 0;
1318-
1319-
/* Don't bother with blocks that are not shared to start with. */
1320-
if (!(iomap->flags & IOMAP_F_SHARED))
1321-
return length;
1322-
13231314
/*
1324-
* Don't bother with delalloc reservations, holes or unwritten extents.
1315+
* Don't bother with blocks that are not shared to start with; or
1316+
* mappings that cannot be shared, such as inline data, delalloc
1317+
* reservations, holes or unwritten extents.
13251318
*
13261319
* Note that we use srcmap directly instead of iomap_iter_srcmap as
13271320
* unsharing requires providing a separate source map, and the presence
13281321
* of one is a good indicator that unsharing is needed, unlike
13291322
* IOMAP_F_SHARED which can be set for any data that goes into the COW
13301323
* fork for XFS.
13311324
*/
1332-
if (iter->srcmap.type == IOMAP_HOLE ||
1333-
iter->srcmap.type == IOMAP_DELALLOC ||
1334-
iter->srcmap.type == IOMAP_UNWRITTEN)
1325+
return (iter->iomap.flags & IOMAP_F_SHARED) &&
1326+
iter->srcmap.type == IOMAP_MAPPED;
1327+
}
1328+
1329+
static loff_t iomap_unshare_iter(struct iomap_iter *iter)
1330+
{
1331+
struct iomap *iomap = &iter->iomap;
1332+
loff_t pos = iter->pos;
1333+
loff_t length = iomap_length(iter);
1334+
loff_t written = 0;
1335+
1336+
if (!iomap_want_unshare_iter(iter))
13351337
return length;
13361338

13371339
do {

include/linux/iomap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ void iomap_invalidate_folio(struct folio *folio, size_t offset, size_t len);
267267
bool iomap_dirty_folio(struct address_space *mapping, struct folio *folio);
268268
int iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len,
269269
const struct iomap_ops *ops);
270+
bool iomap_want_unshare_iter(const struct iomap_iter *iter);
270271
int iomap_zero_range(struct inode *inode, loff_t pos, loff_t len,
271272
bool *did_zero, const struct iomap_ops *ops);
272273
int iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero,

0 commit comments

Comments
 (0)