From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Christoph Hellwig <hch@lst.de>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH 5/8] xfs: use xfs_iext_*_extent helpers in xfs_bmap_shift_extents
Date: Tue, 29 Aug 2017 17:05:41 -0700 [thread overview]
Message-ID: <20170830000541.GF4757@magnolia> (raw)
In-Reply-To: <20170829174835.2218-6-hch@lst.de>
On Tue, Aug 29, 2017 at 07:48:32PM +0200, Christoph Hellwig wrote:
> This abstracts the function away from details of the low-level extent
> list implementation.
>
> Note that it seems like the previous implementation of rmap for
> the merge case was completely broken, but it no seems appear to
> trigger that.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Series looks ok enough to test,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
> fs/xfs/libxfs/xfs_bmap.c | 180 +++++++++++++++++++++++------------------------
> 1 file changed, 88 insertions(+), 92 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 6af3cc1fc630..02725becedfa 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -5881,32 +5881,26 @@ xfs_bmse_merge(
> int whichfork,
> xfs_fileoff_t shift, /* shift fsb */
> int current_ext, /* idx of gotp */
> - struct xfs_bmbt_rec_host *gotp, /* extent to shift */
> - struct xfs_bmbt_rec_host *leftp, /* preceding extent */
> + struct xfs_bmbt_irec *got, /* extent to shift */
> + struct xfs_bmbt_irec *left, /* preceding extent */
> struct xfs_btree_cur *cur,
> - int *logflags) /* output */
> + int *logflags, /* output */
> + struct xfs_defer_ops *dfops)
> {
> - struct xfs_bmbt_irec got;
> - struct xfs_bmbt_irec left;
> + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
> + struct xfs_bmbt_irec new;
> xfs_filblks_t blockcount;
> int error, i;
> struct xfs_mount *mp = ip->i_mount;
>
> - xfs_bmbt_get_all(gotp, &got);
> - xfs_bmbt_get_all(leftp, &left);
> - blockcount = left.br_blockcount + got.br_blockcount;
> + blockcount = left->br_blockcount + got->br_blockcount;
>
> ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
> ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
> - ASSERT(xfs_bmse_can_merge(&left, &got, shift));
> + ASSERT(xfs_bmse_can_merge(left, got, shift));
>
> - /*
> - * Merge the in-core extents. Note that the host record pointers and
> - * current_ext index are invalid once the extent has been removed via
> - * xfs_iext_remove().
> - */
> - xfs_bmbt_set_blockcount(leftp, blockcount);
> - xfs_iext_remove(ip, current_ext, 1, 0);
> + new = *left;
> + new.br_blockcount = blockcount;
>
> /*
> * Update the on-disk extent count, the btree if necessary and log the
> @@ -5917,12 +5911,12 @@ xfs_bmse_merge(
> *logflags |= XFS_ILOG_CORE;
> if (!cur) {
> *logflags |= XFS_ILOG_DEXT;
> - return 0;
> + goto done;
> }
>
> /* lookup and remove the extent to merge */
> - error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock,
> - got.br_blockcount, &i);
> + error = xfs_bmbt_lookup_eq(cur, got->br_startoff, got->br_startblock,
> + got->br_blockcount, &i);
> if (error)
> return error;
> XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
> @@ -5933,16 +5927,29 @@ xfs_bmse_merge(
> XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
>
> /* lookup and update size of the previous extent */
> - error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock,
> - left.br_blockcount, &i);
> + error = xfs_bmbt_lookup_eq(cur, left->br_startoff, left->br_startblock,
> + left->br_blockcount, &i);
> if (error)
> return error;
> XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
>
> - left.br_blockcount = blockcount;
> + error = xfs_bmbt_update(cur, new.br_startoff, new.br_startblock,
> + new.br_blockcount, new.br_state);
> + if (error)
> + return error;
>
> - return xfs_bmbt_update(cur, left.br_startoff, left.br_startblock,
> - left.br_blockcount, left.br_state);
> +done:
> + xfs_iext_update_extent(ifp, current_ext - 1, &new);
> + xfs_iext_remove(ip, current_ext, 1, 0);
> +
> + /* update reverse mapping */
> + error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, got);
> + if (error)
> + return error;
> + error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, left);
> + if (error)
> + return error;
> + return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &new);
> }
>
> /*
> @@ -5954,7 +5961,7 @@ xfs_bmse_shift_one(
> int whichfork,
> xfs_fileoff_t offset_shift_fsb,
> int *current_ext,
> - struct xfs_bmbt_rec_host *gotp,
> + struct xfs_bmbt_irec *got,
> struct xfs_btree_cur *cur,
> int *logflags,
> enum shift_direction direction,
> @@ -5963,9 +5970,7 @@ xfs_bmse_shift_one(
> struct xfs_ifork *ifp;
> struct xfs_mount *mp;
> xfs_fileoff_t startoff;
> - struct xfs_bmbt_rec_host *adj_irecp;
> - struct xfs_bmbt_irec got;
> - struct xfs_bmbt_irec adj_irec;
> + struct xfs_bmbt_irec adj_irec, new;
> int error;
> int i;
> int total_extents;
> @@ -5974,13 +5979,11 @@ xfs_bmse_shift_one(
> ifp = XFS_IFORK_PTR(ip, whichfork);
> total_extents = xfs_iext_count(ifp);
>
> - xfs_bmbt_get_all(gotp, &got);
> -
> /* delalloc extents should be prevented by caller */
> - XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got.br_startblock));
> + XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got->br_startblock));
>
> if (direction == SHIFT_LEFT) {
> - startoff = got.br_startoff - offset_shift_fsb;
> + startoff = got->br_startoff - offset_shift_fsb;
>
> /*
> * Check for merge if we've got an extent to the left,
> @@ -5988,46 +5991,39 @@ xfs_bmse_shift_one(
> * of the file for the shift.
> */
> if (!*current_ext) {
> - if (got.br_startoff < offset_shift_fsb)
> + if (got->br_startoff < offset_shift_fsb)
> return -EINVAL;
> goto update_current_ext;
> }
> +
> /*
> - * grab the left extent and check for a large
> - * enough hole.
> + * grab the left extent and check for a large enough hole.
> */
> - adj_irecp = xfs_iext_get_ext(ifp, *current_ext - 1);
> - xfs_bmbt_get_all(adj_irecp, &adj_irec);
> -
> - if (startoff <
> - adj_irec.br_startoff + adj_irec.br_blockcount)
> + xfs_iext_get_extent(ifp, *current_ext - 1, &adj_irec);
> + if (startoff < adj_irec.br_startoff + adj_irec.br_blockcount)
> return -EINVAL;
>
> /* check whether to merge the extent or shift it down */
> - if (xfs_bmse_can_merge(&adj_irec, &got,
> - offset_shift_fsb)) {
> - error = xfs_bmse_merge(ip, whichfork, offset_shift_fsb,
> - *current_ext, gotp, adj_irecp,
> - cur, logflags);
> - if (error)
> - return error;
> - adj_irec = got;
> - goto update_rmap;
> + if (xfs_bmse_can_merge(&adj_irec, got, offset_shift_fsb)) {
> + return xfs_bmse_merge(ip, whichfork, offset_shift_fsb,
> + *current_ext, got, &adj_irec,
> + cur, logflags, dfops);
> }
> } else {
> - startoff = got.br_startoff + offset_shift_fsb;
> + startoff = got->br_startoff + offset_shift_fsb;
> /* nothing to move if this is the last extent */
> if (*current_ext >= (total_extents - 1))
> goto update_current_ext;
> +
> /*
> * If this is not the last extent in the file, make sure there
> * is enough room between current extent and next extent for
> * accommodating the shift.
> */
> - adj_irecp = xfs_iext_get_ext(ifp, *current_ext + 1);
> - xfs_bmbt_get_all(adj_irecp, &adj_irec);
> - if (startoff + got.br_blockcount > adj_irec.br_startoff)
> + xfs_iext_get_extent(ifp, *current_ext + 1, &adj_irec);
> + if (startoff + got->br_blockcount > adj_irec.br_startoff)
> return -EINVAL;
> +
> /*
> * Unlike a left shift (which involves a hole punch),
> * a right shift does not modify extent neighbors
> @@ -6035,45 +6031,48 @@ xfs_bmse_shift_one(
> * in this scenario. Check anyways and warn if we
> * encounter two extents that could be one.
> */
> - if (xfs_bmse_can_merge(&got, &adj_irec, offset_shift_fsb))
> + if (xfs_bmse_can_merge(got, &adj_irec, offset_shift_fsb))
> WARN_ON_ONCE(1);
> }
> +
> /*
> * Increment the extent index for the next iteration, update the start
> * offset of the in-core extent and update the btree if applicable.
> */
> update_current_ext:
> - if (direction == SHIFT_LEFT)
> - (*current_ext)++;
> - else
> - (*current_ext)--;
> - xfs_bmbt_set_startoff(gotp, startoff);
> *logflags |= XFS_ILOG_CORE;
> - adj_irec = got;
> - if (!cur) {
> +
> + new = *got;
> + new.br_startoff = startoff;
> +
> + if (cur) {
> + error = xfs_bmbt_lookup_eq(cur, got->br_startoff,
> + got->br_startblock, got->br_blockcount, &i);
> + if (error)
> + return error;
> + XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
> +
> + error = xfs_bmbt_update(cur, new.br_startoff,
> + new.br_startblock, new.br_blockcount,
> + new.br_state);
> + if (error)
> + return error;
> + } else {
> *logflags |= XFS_ILOG_DEXT;
> - goto update_rmap;
> }
>
> - error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock,
> - got.br_blockcount, &i);
> - if (error)
> - return error;
> - XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
> + xfs_iext_update_extent(ifp, *current_ext, &new);
>
> - got.br_startoff = startoff;
> - error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock,
> - got.br_blockcount, got.br_state);
> - if (error)
> - return error;
> + if (direction == SHIFT_LEFT)
> + (*current_ext)++;
> + else
> + (*current_ext)--;
>
> -update_rmap:
> /* update reverse mapping */
> - error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, &adj_irec);
> + error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, got);
> if (error)
> return error;
> - adj_irec.br_startoff = startoff;
> - return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &adj_irec);
> + return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &new);
> }
>
> /*
> @@ -6100,7 +6099,6 @@ xfs_bmap_shift_extents(
> int num_exts)
> {
> struct xfs_btree_cur *cur = NULL;
> - struct xfs_bmbt_rec_host *gotp;
> struct xfs_bmbt_irec got;
> struct xfs_mount *mp = ip->i_mount;
> struct xfs_ifork *ifp;
> @@ -6161,25 +6159,23 @@ xfs_bmap_shift_extents(
> ASSERT(direction == SHIFT_RIGHT);
>
> current_ext = total_extents - 1;
> - gotp = xfs_iext_get_ext(ifp, current_ext);
> - xfs_bmbt_get_all(gotp, &got);
> - *next_fsb = got.br_startoff;
> - if (stop_fsb > *next_fsb) {
> + xfs_iext_get_extent(ifp, current_ext, &got);
> + if (stop_fsb > got.br_startoff) {
> *done = 1;
> goto del_cursor;
> }
> + *next_fsb = got.br_startoff;
> } else {
> /*
> * Look up the extent index for the fsb where we start shifting. We can
> * henceforth iterate with current_ext as extent list changes are locked
> * out via ilock.
> *
> - * gotp can be null in 2 cases: 1) if there are no extents or 2)
> - * *next_fsb lies in a hole beyond which there are no extents. Either
> - * way, we are done.
> + * If next_fsb lies in a hole beyond which there are no extents we are
> + * done.
> */
> - gotp = xfs_iext_bno_to_ext(ifp, *next_fsb, ¤t_ext);
> - if (!gotp) {
> + if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, ¤t_ext,
> + &got)) {
> *done = 1;
> goto del_cursor;
> }
> @@ -6187,7 +6183,9 @@ xfs_bmap_shift_extents(
>
> /* Lookup the extent index at which we have to stop */
> if (direction == SHIFT_RIGHT) {
> - xfs_iext_bno_to_ext(ifp, stop_fsb, &stop_extent);
> + struct xfs_bmbt_irec s;
> +
> + xfs_iext_lookup_extent(ip, ifp, stop_fsb, &stop_extent, &s);
> /* Make stop_extent exclusive of shift range */
> stop_extent--;
> if (current_ext <= stop_extent) {
> @@ -6204,7 +6202,7 @@ xfs_bmap_shift_extents(
>
> while (nexts++ < num_exts) {
> error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb,
> - ¤t_ext, gotp, cur, &logflags,
> + ¤t_ext, &got, cur, &logflags,
> direction, dfops);
> if (error)
> goto del_cursor;
> @@ -6222,13 +6220,11 @@ xfs_bmap_shift_extents(
> *next_fsb = NULLFSBLOCK;
> break;
> }
> - gotp = xfs_iext_get_ext(ifp, current_ext);
> + xfs_iext_get_extent(ifp, current_ext, &got);
> }
>
> - if (!*done) {
> - xfs_bmbt_get_all(gotp, &got);
> + if (!*done)
> *next_fsb = got.br_startoff;
> - }
>
> del_cursor:
> if (cur)
> --
> 2.11.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2017-08-30 0:05 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-29 17:48 a few extent lookup cleanups Christoph Hellwig
2017-08-29 17:48 ` [PATCH 1/8] xfs: add a xfs_iext_update_extent helper Christoph Hellwig
2017-08-29 18:09 ` Darrick J. Wong
2017-08-29 17:48 ` [PATCH 2/8] xfs: switch xfs_bmap_local_to_extents to use xfs_iext_insert Christoph Hellwig
2017-08-29 18:13 ` Darrick J. Wong
2017-08-29 17:48 ` [PATCH 3/8] xfs: use xfs_iext_get_extent in xfs_bmap_first_unused Christoph Hellwig
2017-08-29 18:41 ` Darrick J. Wong
2017-09-01 20:06 ` Christoph Hellwig
2017-09-01 20:08 ` Darrick J. Wong
2017-08-29 17:48 ` [PATCH 4/8] xfs: move some code around inside xfs_bmap_shift_extents Christoph Hellwig
2017-08-29 19:35 ` Darrick J. Wong
2017-08-29 17:48 ` [PATCH 5/8] xfs: use xfs_iext_*_extent helpers in xfs_bmap_shift_extents Christoph Hellwig
2017-08-30 0:05 ` Darrick J. Wong [this message]
2017-08-30 23:03 ` Darrick J. Wong
2017-08-29 17:48 ` [PATCH 6/8] xfs: use xfs_iext_*_extent helpers in xfs_bmap_split_extent_at Christoph Hellwig
2017-08-29 18:42 ` Darrick J. Wong
2017-08-29 17:48 ` [PATCH 7/8] xfs: rewrite xfs_bmap_count_leaves using xfs_iext_get_extent Christoph Hellwig
2017-08-29 18:43 ` Darrick J. Wong
2017-08-29 17:48 ` [PATCH 8/8] xfs: replace xfs_qm_get_rtblks with a direct call to xfs_bmap_count_leaves Christoph Hellwig
2017-08-29 18:44 ` Darrick J. Wong
2017-08-30 23:10 ` [PATCH 9/8] xfs: simplify the rmap code in xfs_bmse_merge Darrick J. Wong
2017-08-31 13:31 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170830000541.GF4757@magnolia \
--to=darrick.wong@oracle.com \
--cc=hch@lst.de \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).