Skip to content

Commit 7102733

Browse files
Christoph Hellwigbrauner
authored andcommitted
iomap: simplify io_flags and io_type in struct iomap_ioend
The ioend fields for distinct types of I/O are a bit complicated. Consolidate them into a single io_flag field with it's own flags decoupled from the iomap flags. This also prepares for adding a new flag that is unrelated to both of the iomap namespaces. Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20250206064035.2323428-3-hch@lst.de Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent c501059 commit 7102733

3 files changed

Lines changed: 46 additions & 25 deletions

File tree

fs/iomap/buffered-io.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,13 +1605,10 @@ iomap_ioend_can_merge(struct iomap_ioend *ioend, struct iomap_ioend *next)
16051605
{
16061606
if (ioend->io_bio.bi_status != next->io_bio.bi_status)
16071607
return false;
1608-
if (next->io_flags & IOMAP_F_BOUNDARY)
1608+
if (next->io_flags & IOMAP_IOEND_BOUNDARY)
16091609
return false;
1610-
if ((ioend->io_flags & IOMAP_F_SHARED) ^
1611-
(next->io_flags & IOMAP_F_SHARED))
1612-
return false;
1613-
if ((ioend->io_type == IOMAP_UNWRITTEN) ^
1614-
(next->io_type == IOMAP_UNWRITTEN))
1610+
if ((ioend->io_flags & IOMAP_IOEND_NOMERGE_FLAGS) !=
1611+
(next->io_flags & IOMAP_IOEND_NOMERGE_FLAGS))
16151612
return false;
16161613
if (ioend->io_offset + ioend->io_size != next->io_offset)
16171614
return false;
@@ -1709,7 +1706,8 @@ static int iomap_submit_ioend(struct iomap_writepage_ctx *wpc, int error)
17091706
}
17101707

17111708
static struct iomap_ioend *iomap_alloc_ioend(struct iomap_writepage_ctx *wpc,
1712-
struct writeback_control *wbc, struct inode *inode, loff_t pos)
1709+
struct writeback_control *wbc, struct inode *inode, loff_t pos,
1710+
u16 ioend_flags)
17131711
{
17141712
struct iomap_ioend *ioend;
17151713
struct bio *bio;
@@ -1724,8 +1722,7 @@ static struct iomap_ioend *iomap_alloc_ioend(struct iomap_writepage_ctx *wpc,
17241722

17251723
ioend = iomap_ioend_from_bio(bio);
17261724
INIT_LIST_HEAD(&ioend->io_list);
1727-
ioend->io_type = wpc->iomap.type;
1728-
ioend->io_flags = wpc->iomap.flags;
1725+
ioend->io_flags = ioend_flags;
17291726
if (pos > wpc->iomap.offset)
17301727
wpc->iomap.flags &= ~IOMAP_F_BOUNDARY;
17311728
ioend->io_inode = inode;
@@ -1737,14 +1734,13 @@ static struct iomap_ioend *iomap_alloc_ioend(struct iomap_writepage_ctx *wpc,
17371734
return ioend;
17381735
}
17391736

1740-
static bool iomap_can_add_to_ioend(struct iomap_writepage_ctx *wpc, loff_t pos)
1737+
static bool iomap_can_add_to_ioend(struct iomap_writepage_ctx *wpc, loff_t pos,
1738+
u16 ioend_flags)
17411739
{
1742-
if (wpc->iomap.offset == pos && (wpc->iomap.flags & IOMAP_F_BOUNDARY))
1743-
return false;
1744-
if ((wpc->iomap.flags & IOMAP_F_SHARED) !=
1745-
(wpc->ioend->io_flags & IOMAP_F_SHARED))
1740+
if (ioend_flags & IOMAP_IOEND_BOUNDARY)
17461741
return false;
1747-
if (wpc->iomap.type != wpc->ioend->io_type)
1742+
if ((ioend_flags & IOMAP_IOEND_NOMERGE_FLAGS) !=
1743+
(wpc->ioend->io_flags & IOMAP_IOEND_NOMERGE_FLAGS))
17481744
return false;
17491745
if (pos != wpc->ioend->io_offset + wpc->ioend->io_size)
17501746
return false;
@@ -1779,14 +1775,23 @@ static int iomap_add_to_ioend(struct iomap_writepage_ctx *wpc,
17791775
{
17801776
struct iomap_folio_state *ifs = folio->private;
17811777
size_t poff = offset_in_folio(folio, pos);
1778+
unsigned int ioend_flags = 0;
17821779
int error;
17831780

1784-
if (!wpc->ioend || !iomap_can_add_to_ioend(wpc, pos)) {
1781+
if (wpc->iomap.type == IOMAP_UNWRITTEN)
1782+
ioend_flags |= IOMAP_IOEND_UNWRITTEN;
1783+
if (wpc->iomap.flags & IOMAP_F_SHARED)
1784+
ioend_flags |= IOMAP_IOEND_SHARED;
1785+
if (pos == wpc->iomap.offset && (wpc->iomap.flags & IOMAP_F_BOUNDARY))
1786+
ioend_flags |= IOMAP_IOEND_BOUNDARY;
1787+
1788+
if (!wpc->ioend || !iomap_can_add_to_ioend(wpc, pos, ioend_flags)) {
17851789
new_ioend:
17861790
error = iomap_submit_ioend(wpc, 0);
17871791
if (error)
17881792
return error;
1789-
wpc->ioend = iomap_alloc_ioend(wpc, wbc, inode, pos);
1793+
wpc->ioend = iomap_alloc_ioend(wpc, wbc, inode, pos,
1794+
ioend_flags);
17901795
}
17911796

17921797
if (!bio_add_folio(&wpc->ioend->io_bio, folio, len, poff))

fs/xfs/xfs_aops.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ xfs_end_ioend(
114114
*/
115115
error = blk_status_to_errno(ioend->io_bio.bi_status);
116116
if (unlikely(error)) {
117-
if (ioend->io_flags & IOMAP_F_SHARED) {
117+
if (ioend->io_flags & IOMAP_IOEND_SHARED) {
118118
xfs_reflink_cancel_cow_range(ip, offset, size, true);
119119
xfs_bmap_punch_delalloc_range(ip, XFS_DATA_FORK, offset,
120120
offset + size);
@@ -125,9 +125,9 @@ xfs_end_ioend(
125125
/*
126126
* Success: commit the COW or unwritten blocks if needed.
127127
*/
128-
if (ioend->io_flags & IOMAP_F_SHARED)
128+
if (ioend->io_flags & IOMAP_IOEND_SHARED)
129129
error = xfs_reflink_end_cow(ip, offset, size);
130-
else if (ioend->io_type == IOMAP_UNWRITTEN)
130+
else if (ioend->io_flags & IOMAP_IOEND_UNWRITTEN)
131131
error = xfs_iomap_write_unwritten(ip, offset, size, false);
132132

133133
if (!error && xfs_ioend_is_append(ioend))
@@ -410,16 +410,16 @@ xfs_submit_ioend(
410410
nofs_flag = memalloc_nofs_save();
411411

412412
/* Convert CoW extents to regular */
413-
if (!status && (ioend->io_flags & IOMAP_F_SHARED)) {
413+
if (!status && (ioend->io_flags & IOMAP_IOEND_SHARED)) {
414414
status = xfs_reflink_convert_cow(XFS_I(ioend->io_inode),
415415
ioend->io_offset, ioend->io_size);
416416
}
417417

418418
memalloc_nofs_restore(nofs_flag);
419419

420420
/* send ioends that might require a transaction to the completion wq */
421-
if (xfs_ioend_is_append(ioend) || ioend->io_type == IOMAP_UNWRITTEN ||
422-
(ioend->io_flags & IOMAP_F_SHARED))
421+
if (xfs_ioend_is_append(ioend) ||
422+
(ioend->io_flags & (IOMAP_IOEND_UNWRITTEN | IOMAP_IOEND_SHARED)))
423423
ioend->io_bio.bi_end_io = xfs_end_bio;
424424

425425
if (status)

include/linux/iomap.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,13 +327,29 @@ loff_t iomap_seek_data(struct inode *inode, loff_t offset,
327327
sector_t iomap_bmap(struct address_space *mapping, sector_t bno,
328328
const struct iomap_ops *ops);
329329

330+
/*
331+
* Flags for iomap_ioend->io_flags.
332+
*/
333+
/* shared COW extent */
334+
#define IOMAP_IOEND_SHARED (1U << 0)
335+
/* unwritten extent */
336+
#define IOMAP_IOEND_UNWRITTEN (1U << 1)
337+
/* don't merge into previous ioend */
338+
#define IOMAP_IOEND_BOUNDARY (1U << 2)
339+
340+
/*
341+
* Flags that if set on either ioend prevent the merge of two ioends.
342+
* (IOMAP_IOEND_BOUNDARY also prevents merges, but only one-way)
343+
*/
344+
#define IOMAP_IOEND_NOMERGE_FLAGS \
345+
(IOMAP_IOEND_SHARED | IOMAP_IOEND_UNWRITTEN)
346+
330347
/*
331348
* Structure for writeback I/O completions.
332349
*/
333350
struct iomap_ioend {
334351
struct list_head io_list; /* next ioend in chain */
335-
u16 io_type;
336-
u16 io_flags; /* IOMAP_F_* */
352+
u16 io_flags; /* IOMAP_IOEND_* */
337353
struct inode *io_inode; /* file being written to */
338354
size_t io_size; /* size of data within eof */
339355
loff_t io_offset; /* offset in the file */

0 commit comments

Comments
 (0)