aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2014-09-23 01:39:04 -0400
committerDave Chinner <david@fromorbit.com>2014-09-23 01:39:04 -0400
commita979bdfea10a61dce0055b4d416d640f4f5f495e (patch)
treeef48ae3ce031f6133fa2c9c56d01f6d31fe4d953
parentddb19e3180fa42362a04e86771d758be1de0bb13 (diff)
xfs: refactor single extent shift into xfs_bmse_shift_one() helper
xfs_bmap_shift_extents() has a variety of conditions and error checks that make the logic difficult to follow and indent heavy. Refactor the loop body of this function into a new xfs_bmse_shift_one() helper. This simplifies the error checks, eliminates index decrement on merge hack by pushing the index increment down into the helper, and makes the code more readable by reducing multiple levels of indentation. This is a code refactor only. The behavior of extent shift and collapse range is not modified. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c164
1 files changed, 91 insertions, 73 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 532c4aab20f2..69bf8d868b64 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -5518,6 +5518,88 @@ out_error:
5518} 5518}
5519 5519
5520/* 5520/*
5521 * Shift a single extent.
5522 */
5523STATIC int
5524xfs_bmse_shift_one(
5525 struct xfs_inode *ip,
5526 int whichfork,
5527 xfs_fileoff_t offset_shift_fsb,
5528 int *current_ext,
5529 struct xfs_bmbt_rec_host *gotp,
5530 struct xfs_btree_cur *cur,
5531 int *logflags)
5532{
5533 struct xfs_ifork *ifp;
5534 xfs_fileoff_t startoff;
5535 struct xfs_bmbt_rec_host *leftp;
5536 struct xfs_bmbt_irec got;
5537 struct xfs_bmbt_irec left;
5538 int error;
5539 int i;
5540
5541 ifp = XFS_IFORK_PTR(ip, whichfork);
5542
5543 xfs_bmbt_get_all(gotp, &got);
5544 startoff = got.br_startoff - offset_shift_fsb;
5545
5546 /*
5547 * If this is the first extent in the file, make sure there's enough
5548 * room at the start of the file and jump right to the shift as there's
5549 * no left extent to merge.
5550 */
5551 if (*current_ext == 0) {
5552 if (got.br_startoff < offset_shift_fsb)
5553 return -EINVAL;
5554 goto shift_extent;
5555 }
5556
5557 /* grab the left extent and check for a large enough hole */
5558 leftp = xfs_iext_get_ext(ifp, *current_ext - 1);
5559 xfs_bmbt_get_all(leftp, &left);
5560
5561 if (startoff < left.br_startoff + left.br_blockcount)
5562 return -EINVAL;
5563
5564 /* check whether to merge the extent or shift it down */
5565 if (!xfs_bmse_can_merge(&left, &got, offset_shift_fsb))
5566 goto shift_extent;
5567
5568 return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, *current_ext,
5569 gotp, leftp, cur, logflags);
5570
5571shift_extent:
5572 /*
5573 * Increment the extent index for the next iteration, update the start
5574 * offset of the in-core extent and update the btree if applicable.
5575 */
5576 (*current_ext)++;
5577 xfs_bmbt_set_startoff(gotp, startoff);
5578 *logflags |= XFS_ILOG_CORE;
5579 if (!cur) {
5580 *logflags |= XFS_ILOG_DEXT;
5581 return 0;
5582 }
5583
5584 error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock,
5585 got.br_blockcount, &i);
5586 if (error)
5587 return error;
5588 XFS_WANT_CORRUPTED_GOTO(i == 1, out_error);
5589
5590 got.br_startoff = startoff;
5591 error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock,
5592 got.br_blockcount, got.br_state);
5593 if (error)
5594 return error;
5595
5596 return 0;
5597
5598out_error:
5599 return error;
5600}
5601
5602/*
5521 * Shift extent records to the left to cover a hole. 5603 * Shift extent records to the left to cover a hole.
5522 * 5604 *
5523 * The maximum number of extents to be shifted in a single operation is 5605 * The maximum number of extents to be shifted in a single operation is
@@ -5541,16 +5623,12 @@ xfs_bmap_shift_extents(
5541{ 5623{
5542 struct xfs_btree_cur *cur = NULL; 5624 struct xfs_btree_cur *cur = NULL;
5543 struct xfs_bmbt_rec_host *gotp; 5625 struct xfs_bmbt_rec_host *gotp;
5544 struct xfs_bmbt_rec_host *leftp;
5545 struct xfs_bmbt_irec got; 5626 struct xfs_bmbt_irec got;
5546 struct xfs_bmbt_irec left;
5547 struct xfs_mount *mp = ip->i_mount; 5627 struct xfs_mount *mp = ip->i_mount;
5548 struct xfs_ifork *ifp; 5628 struct xfs_ifork *ifp;
5549 xfs_extnum_t nexts = 0; 5629 xfs_extnum_t nexts = 0;
5550 xfs_extnum_t current_ext; 5630 xfs_extnum_t current_ext;
5551 xfs_fileoff_t startoff;
5552 int error = 0; 5631 int error = 0;
5553 int i;
5554 int whichfork = XFS_DATA_FORK; 5632 int whichfork = XFS_DATA_FORK;
5555 int logflags = 0; 5633 int logflags = 0;
5556 int total_extents; 5634 int total_extents;
@@ -5599,16 +5677,6 @@ xfs_bmap_shift_extents(
5599 *done = 1; 5677 *done = 1;
5600 goto del_cursor; 5678 goto del_cursor;
5601 } 5679 }
5602 xfs_bmbt_get_all(gotp, &got);
5603
5604 /*
5605 * If the first extent is shifted, offset_shift_fsb cannot be larger
5606 * than the starting offset of the first extent.
5607 */
5608 if (current_ext == 0 && got.br_startoff < offset_shift_fsb) {
5609 error = -EINVAL;
5610 goto del_cursor;
5611 }
5612 5680
5613 /* 5681 /*
5614 * There may be delalloc extents in the data fork before the range we 5682 * There may be delalloc extents in the data fork before the range we
@@ -5617,75 +5685,25 @@ xfs_bmap_shift_extents(
5617 */ 5685 */
5618 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); 5686 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
5619 while (nexts++ < num_exts && current_ext < total_extents) { 5687 while (nexts++ < num_exts && current_ext < total_extents) {
5620 startoff = got.br_startoff - offset_shift_fsb; 5688 error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb,
5621 5689 &current_ext, gotp, cur, &logflags);
5622 /* grab the left extent and check for a potential merge */ 5690 if (error)
5623 if (current_ext > 0) { 5691 goto del_cursor;
5624 leftp = xfs_iext_get_ext(ifp, current_ext - 1);
5625 xfs_bmbt_get_all(leftp, &left);
5626
5627 /* make sure hole is large enough for shift */
5628 if (startoff < left.br_startoff + left.br_blockcount) {
5629 error = -EINVAL;
5630 goto del_cursor;
5631 }
5632
5633 if (xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) {
5634 error = xfs_bmse_merge(ip, whichfork,
5635 offset_shift_fsb, current_ext, gotp,
5636 leftp, cur, &logflags);
5637 if (error)
5638 goto del_cursor;
5639
5640 /*
5641 * The extent was merged so adjust the extent
5642 * index and move onto the next.
5643 */
5644 current_ext--;
5645 goto next;
5646 }
5647 }
5648
5649 /*
5650 * We didn't merge the extent so do the shift. Update the start
5651 * offset in the in-core extent and btree, if necessary.
5652 */
5653 xfs_bmbt_set_startoff(gotp, startoff);
5654 logflags |= XFS_ILOG_CORE;
5655 if (cur) {
5656 error = xfs_bmbt_lookup_eq(cur, got.br_startoff,
5657 got.br_startblock,
5658 got.br_blockcount,
5659 &i);
5660 if (error)
5661 goto del_cursor;
5662 XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor);
5663
5664 got.br_startoff = startoff;
5665 error = xfs_bmbt_update(cur, got.br_startoff,
5666 got.br_startblock,
5667 got.br_blockcount,
5668 got.br_state);
5669 if (error)
5670 goto del_cursor;
5671 } else {
5672 logflags |= XFS_ILOG_DEXT;
5673 }
5674 5692
5675next:
5676 /* update total extent count and grab the next record */ 5693 /* update total extent count and grab the next record */
5677 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); 5694 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
5678 if (++current_ext >= total_extents) 5695 if (current_ext >= total_extents)
5679 break; 5696 break;
5680 gotp = xfs_iext_get_ext(ifp, current_ext); 5697 gotp = xfs_iext_get_ext(ifp, current_ext);
5681 xfs_bmbt_get_all(gotp, &got);
5682 } 5698 }
5683 5699
5684 /* Check if we are done */ 5700 /* Check if we are done */
5685 if (current_ext == total_extents) 5701 if (current_ext == total_extents) {
5686 *done = 1; 5702 *done = 1;
5687 else if (next_fsb) 5703 } else if (next_fsb) {
5704 xfs_bmbt_get_all(gotp, &got);
5688 *next_fsb = got.br_startoff; 5705 *next_fsb = got.br_startoff;
5706 }
5689 5707
5690del_cursor: 5708del_cursor:
5691 if (cur) 5709 if (cur)