Commit 4453593b authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: return work remaining at the end of a bunmapi operation

Return the range of file blocks that bunmapi didn't free.  This hint
is used by CoW and reflink to figure out what part of an extent
actually got freed so that it can set up the appropriate atomic
remapping of just the freed range.
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 17c12bcd
...@@ -5098,17 +5098,16 @@ xfs_bmap_del_extent( ...@@ -5098,17 +5098,16 @@ xfs_bmap_del_extent(
* *done is set. * *done is set.
*/ */
int /* error */ int /* error */
xfs_bunmapi( __xfs_bunmapi(
xfs_trans_t *tp, /* transaction pointer */ xfs_trans_t *tp, /* transaction pointer */
struct xfs_inode *ip, /* incore inode */ struct xfs_inode *ip, /* incore inode */
xfs_fileoff_t bno, /* starting offset to unmap */ xfs_fileoff_t bno, /* starting offset to unmap */
xfs_filblks_t len, /* length to unmap in file */ xfs_filblks_t *rlen, /* i/o: amount remaining */
int flags, /* misc flags */ int flags, /* misc flags */
xfs_extnum_t nexts, /* number of extents max */ xfs_extnum_t nexts, /* number of extents max */
xfs_fsblock_t *firstblock, /* first allocated block xfs_fsblock_t *firstblock, /* first allocated block
controls a.g. for allocs */ controls a.g. for allocs */
struct xfs_defer_ops *dfops, /* i/o: list extents to free */ struct xfs_defer_ops *dfops) /* i/o: deferred updates */
int *done) /* set if not done yet */
{ {
xfs_btree_cur_t *cur; /* bmap btree cursor */ xfs_btree_cur_t *cur; /* bmap btree cursor */
xfs_bmbt_irec_t del; /* extent being deleted */ xfs_bmbt_irec_t del; /* extent being deleted */
...@@ -5130,6 +5129,7 @@ xfs_bunmapi( ...@@ -5130,6 +5129,7 @@ xfs_bunmapi(
int wasdel; /* was a delayed alloc extent */ int wasdel; /* was a delayed alloc extent */
int whichfork; /* data or attribute fork */ int whichfork; /* data or attribute fork */
xfs_fsblock_t sum; xfs_fsblock_t sum;
xfs_filblks_t len = *rlen; /* length to unmap in file */
trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_);
...@@ -5156,7 +5156,7 @@ xfs_bunmapi( ...@@ -5156,7 +5156,7 @@ xfs_bunmapi(
return error; return error;
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
if (nextents == 0) { if (nextents == 0) {
*done = 1; *rlen = 0;
return 0; return 0;
} }
XFS_STATS_INC(mp, xs_blk_unmap); XFS_STATS_INC(mp, xs_blk_unmap);
...@@ -5427,7 +5427,10 @@ xfs_bunmapi( ...@@ -5427,7 +5427,10 @@ xfs_bunmapi(
extno++; extno++;
} }
} }
*done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; if (bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0)
*rlen = 0;
else
*rlen = bno - start + 1;
/* /*
* Convert to a btree if necessary. * Convert to a btree if necessary.
...@@ -5483,6 +5486,27 @@ xfs_bunmapi( ...@@ -5483,6 +5486,27 @@ xfs_bunmapi(
return error; return error;
} }
/* Unmap a range of a file. */
int
xfs_bunmapi(
xfs_trans_t *tp,
struct xfs_inode *ip,
xfs_fileoff_t bno,
xfs_filblks_t len,
int flags,
xfs_extnum_t nexts,
xfs_fsblock_t *firstblock,
struct xfs_defer_ops *dfops,
int *done)
{
int error;
error = __xfs_bunmapi(tp, ip, bno, &len, flags, nexts, firstblock,
dfops);
*done = (len == 0);
return error;
}
/* /*
* Determine whether an extent shift can be accomplished by a merge with the * Determine whether an extent shift can be accomplished by a merge with the
* extent that precedes the target hole of the shift. * extent that precedes the target hole of the shift.
......
...@@ -197,6 +197,10 @@ int xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip, ...@@ -197,6 +197,10 @@ int xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip,
xfs_fsblock_t *firstblock, xfs_extlen_t total, xfs_fsblock_t *firstblock, xfs_extlen_t total,
struct xfs_bmbt_irec *mval, int *nmap, struct xfs_bmbt_irec *mval, int *nmap,
struct xfs_defer_ops *dfops); struct xfs_defer_ops *dfops);
int __xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip,
xfs_fileoff_t bno, xfs_filblks_t *rlen, int flags,
xfs_extnum_t nexts, xfs_fsblock_t *firstblock,
struct xfs_defer_ops *dfops);
int xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip, int xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip,
xfs_fileoff_t bno, xfs_filblks_t len, int flags, xfs_fileoff_t bno, xfs_filblks_t len, int flags,
xfs_extnum_t nexts, xfs_fsblock_t *firstblock, xfs_extnum_t nexts, xfs_fsblock_t *firstblock,
......
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