Commit ffb375a8 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong

xfs: pass two imaps to xfs_reflink_allocate_cow

xfs_reflink_allocate_cow consumes the source data fork imap, and
potentially returns the COW fork imap.  Split the arguments in two
to clear up the calling conventions and to prepare for returning
a source iomap from ->iomap_begin.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent dd26b846
...@@ -996,9 +996,8 @@ xfs_file_iomap_begin( ...@@ -996,9 +996,8 @@ xfs_file_iomap_begin(
goto out_found; goto out_found;
/* may drop and re-acquire the ilock */ /* may drop and re-acquire the ilock */
cmap = imap; error = xfs_reflink_allocate_cow(ip, &imap, &cmap, &shared,
error = xfs_reflink_allocate_cow(ip, &cmap, &shared, &lockmode, &lockmode, directio);
directio);
if (error) if (error)
goto out_unlock; goto out_unlock;
...@@ -1011,7 +1010,8 @@ xfs_file_iomap_begin( ...@@ -1011,7 +1010,8 @@ xfs_file_iomap_begin(
* newly allocated address. If the data fork has a hole, copy * newly allocated address. If the data fork has a hole, copy
* the COW fork mapping to avoid allocating to the data fork. * the COW fork mapping to avoid allocating to the data fork.
*/ */
if (directio || imap.br_startblock == HOLESTARTBLOCK) if (shared &&
(directio || imap.br_startblock == HOLESTARTBLOCK))
imap = cmap; imap = cmap;
end_fsb = imap.br_startoff + imap.br_blockcount; end_fsb = imap.br_startoff + imap.br_blockcount;
......
...@@ -308,13 +308,13 @@ static int ...@@ -308,13 +308,13 @@ static int
xfs_find_trim_cow_extent( xfs_find_trim_cow_extent(
struct xfs_inode *ip, struct xfs_inode *ip,
struct xfs_bmbt_irec *imap, struct xfs_bmbt_irec *imap,
struct xfs_bmbt_irec *cmap,
bool *shared, bool *shared,
bool *found) bool *found)
{ {
xfs_fileoff_t offset_fsb = imap->br_startoff; xfs_fileoff_t offset_fsb = imap->br_startoff;
xfs_filblks_t count_fsb = imap->br_blockcount; xfs_filblks_t count_fsb = imap->br_blockcount;
struct xfs_iext_cursor icur; struct xfs_iext_cursor icur;
struct xfs_bmbt_irec got;
*found = false; *found = false;
...@@ -322,23 +322,22 @@ xfs_find_trim_cow_extent( ...@@ -322,23 +322,22 @@ xfs_find_trim_cow_extent(
* If we don't find an overlapping extent, trim the range we need to * If we don't find an overlapping extent, trim the range we need to
* allocate to fit the hole we found. * allocate to fit the hole we found.
*/ */
if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &got)) if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, cmap))
got.br_startoff = offset_fsb + count_fsb; cmap->br_startoff = offset_fsb + count_fsb;
if (got.br_startoff > offset_fsb) { if (cmap->br_startoff > offset_fsb) {
xfs_trim_extent(imap, imap->br_startoff, xfs_trim_extent(imap, imap->br_startoff,
got.br_startoff - imap->br_startoff); cmap->br_startoff - imap->br_startoff);
return xfs_inode_need_cow(ip, imap, shared); return xfs_inode_need_cow(ip, imap, shared);
} }
*shared = true; *shared = true;
if (isnullstartblock(got.br_startblock)) { if (isnullstartblock(cmap->br_startblock)) {
xfs_trim_extent(imap, got.br_startoff, got.br_blockcount); xfs_trim_extent(imap, cmap->br_startoff, cmap->br_blockcount);
return 0; return 0;
} }
/* real extent found - no need to allocate */ /* real extent found - no need to allocate */
xfs_trim_extent(&got, offset_fsb, count_fsb); xfs_trim_extent(cmap, offset_fsb, count_fsb);
*imap = got;
*found = true; *found = true;
return 0; return 0;
} }
...@@ -348,6 +347,7 @@ int ...@@ -348,6 +347,7 @@ int
xfs_reflink_allocate_cow( xfs_reflink_allocate_cow(
struct xfs_inode *ip, struct xfs_inode *ip,
struct xfs_bmbt_irec *imap, struct xfs_bmbt_irec *imap,
struct xfs_bmbt_irec *cmap,
bool *shared, bool *shared,
uint *lockmode, uint *lockmode,
bool convert_now) bool convert_now)
...@@ -367,7 +367,7 @@ xfs_reflink_allocate_cow( ...@@ -367,7 +367,7 @@ xfs_reflink_allocate_cow(
xfs_ifork_init_cow(ip); xfs_ifork_init_cow(ip);
} }
error = xfs_find_trim_cow_extent(ip, imap, shared, &found); error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found);
if (error || !*shared) if (error || !*shared)
return error; return error;
if (found) if (found)
...@@ -392,7 +392,7 @@ xfs_reflink_allocate_cow( ...@@ -392,7 +392,7 @@ xfs_reflink_allocate_cow(
/* /*
* Check for an overlapping extent again now that we dropped the ilock. * Check for an overlapping extent again now that we dropped the ilock.
*/ */
error = xfs_find_trim_cow_extent(ip, imap, shared, &found); error = xfs_find_trim_cow_extent(ip, imap, cmap, shared, &found);
if (error || !*shared) if (error || !*shared)
goto out_trans_cancel; goto out_trans_cancel;
if (found) { if (found) {
...@@ -411,7 +411,7 @@ xfs_reflink_allocate_cow( ...@@ -411,7 +411,7 @@ xfs_reflink_allocate_cow(
nimaps = 1; nimaps = 1;
error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount, error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount,
XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC, XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC,
resblks, imap, &nimaps); resblks, cmap, &nimaps);
if (error) if (error)
goto out_unreserve; goto out_unreserve;
...@@ -427,15 +427,15 @@ xfs_reflink_allocate_cow( ...@@ -427,15 +427,15 @@ xfs_reflink_allocate_cow(
if (nimaps == 0) if (nimaps == 0)
return -ENOSPC; return -ENOSPC;
convert: convert:
xfs_trim_extent(imap, offset_fsb, count_fsb); xfs_trim_extent(cmap, offset_fsb, count_fsb);
/* /*
* COW fork extents are supposed to remain unwritten until we're ready * COW fork extents are supposed to remain unwritten until we're ready
* to initiate a disk write. For direct I/O we are going to write the * to initiate a disk write. For direct I/O we are going to write the
* data and need the conversion, but for buffered writes we're done. * data and need the conversion, but for buffered writes we're done.
*/ */
if (!convert_now || imap->br_state == XFS_EXT_NORM) if (!convert_now || cmap->br_state == XFS_EXT_NORM)
return 0; return 0;
trace_xfs_reflink_convert_cow(ip, imap); trace_xfs_reflink_convert_cow(ip, cmap);
return xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb); return xfs_reflink_convert_cow_locked(ip, offset_fsb, count_fsb);
out_unreserve: out_unreserve:
......
...@@ -25,8 +25,8 @@ extern int xfs_reflink_trim_around_shared(struct xfs_inode *ip, ...@@ -25,8 +25,8 @@ extern int xfs_reflink_trim_around_shared(struct xfs_inode *ip,
bool xfs_inode_need_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap, bool xfs_inode_need_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap,
bool *shared); bool *shared);
extern int xfs_reflink_allocate_cow(struct xfs_inode *ip, int xfs_reflink_allocate_cow(struct xfs_inode *ip, struct xfs_bmbt_irec *imap,
struct xfs_bmbt_irec *imap, bool *shared, uint *lockmode, struct xfs_bmbt_irec *cmap, bool *shared, uint *lockmode,
bool convert_now); bool convert_now);
extern int xfs_reflink_convert_cow(struct xfs_inode *ip, xfs_off_t offset, extern int xfs_reflink_convert_cow(struct xfs_inode *ip, xfs_off_t offset,
xfs_off_t count); xfs_off_t count);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment