Re: [PATCH v2 07/11] xfs: iomap CoW-based atomic write support

From: John Garry
Date: Tue Feb 25 2025 - 13:10:17 EST


On 25/02/2025 17:47, Darrick J. Wong wrote:
I can try, and would then need to try to factor out what would be much
duplicated code.
<nod> I think it's pretty straightforward:

Yeah, I already had done sometime like this since.


xfs_direct_cow_write_iomap_begin()
{
ASSERT(flags & IOMAP_WRITE);
ASSERT(flags & IOMAP_DIRECT);
ASSERT(flags & IOMAP_ATOMIC_SW);

if (xfs_is_shutdown(mp))
return -EIO;

/*
* Writes that span EOF might trigger an IO size update on
* completion, so consider them to be dirty for the purposes of
* O_DSYNC even if there is no other metadata changes pending or
* have been made here.
*/
if (offset + length > i_size_read(inode))
iomap_flags |= IOMAP_F_DIRTY;

lockmode = XFS_ILOCK_EXCL;
error = xfs_ilock_for_iomap(ip, flags, &lockmode);
if (error)
return error;

error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
&imap, &nimaps, 0);
if (error)
goto out_unlock;

error = xfs_reflink_allocate_cow(ip, &imap, &cmap, &shared,
&lockmode, true, true);
if (error)
goto out_unlock;

endoff = XFS_FSB_TO_B(mp, cmap.br_startoff + cmap.br_blockcount);
trace_xfs_iomap_found(ip, offset, endoff - offset, XFS_COW_FORK,
&cmap);
if (imap.br_startblock != HOLESTARTBLOCK) {

note: As you know, all this is common to xfs_direct_write_iomap_begin(), but unfortunately can't neatly be factored out due to the xfs_iunlock() calls.

seq = xfs_iomap_inode_sequence(ip, 0);
error = xfs_bmbt_to_iomap(ip, srcmap, &imap, flags, 0,
seq);
if (error)
goto out_unlock;
}
seq = xfs_iomap_inode_sequence(ip, IOMAP_F_SHARED);
xfs_iunlock(ip, lockmode);
return xfs_bmbt_to_iomap(ip, iomap, &cmap, flags,
IOMAP_F_SHARED, seq);

out_unlock:
if (lockmode)
xfs_iunlock(ip, lockmode);
return error;
}


Cheers,
John