diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_bmap.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 77 |
1 files changed, 26 insertions, 51 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 79c981984dca..b5eb4743f75a 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c | |||
@@ -22,9 +22,7 @@ | |||
22 | #include "xfs_log_format.h" | 22 | #include "xfs_log_format.h" |
23 | #include "xfs_trans_resv.h" | 23 | #include "xfs_trans_resv.h" |
24 | #include "xfs_bit.h" | 24 | #include "xfs_bit.h" |
25 | #include "xfs_inum.h" | ||
26 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
27 | #include "xfs_ag.h" | ||
28 | #include "xfs_mount.h" | 26 | #include "xfs_mount.h" |
29 | #include "xfs_da_format.h" | 27 | #include "xfs_da_format.h" |
30 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
@@ -46,7 +44,6 @@ | |||
46 | #include "xfs_trace.h" | 44 | #include "xfs_trace.h" |
47 | #include "xfs_symlink.h" | 45 | #include "xfs_symlink.h" |
48 | #include "xfs_attr_leaf.h" | 46 | #include "xfs_attr_leaf.h" |
49 | #include "xfs_dinode.h" | ||
50 | #include "xfs_filestream.h" | 47 | #include "xfs_filestream.h" |
51 | 48 | ||
52 | 49 | ||
@@ -5450,13 +5447,11 @@ xfs_bmse_merge( | |||
5450 | struct xfs_btree_cur *cur, | 5447 | struct xfs_btree_cur *cur, |
5451 | int *logflags) /* output */ | 5448 | int *logflags) /* output */ |
5452 | { | 5449 | { |
5453 | struct xfs_ifork *ifp; | ||
5454 | struct xfs_bmbt_irec got; | 5450 | struct xfs_bmbt_irec got; |
5455 | struct xfs_bmbt_irec left; | 5451 | struct xfs_bmbt_irec left; |
5456 | xfs_filblks_t blockcount; | 5452 | xfs_filblks_t blockcount; |
5457 | int error, i; | 5453 | int error, i; |
5458 | 5454 | ||
5459 | ifp = XFS_IFORK_PTR(ip, whichfork); | ||
5460 | xfs_bmbt_get_all(gotp, &got); | 5455 | xfs_bmbt_get_all(gotp, &got); |
5461 | xfs_bmbt_get_all(leftp, &left); | 5456 | xfs_bmbt_get_all(leftp, &left); |
5462 | blockcount = left.br_blockcount + got.br_blockcount; | 5457 | blockcount = left.br_blockcount + got.br_blockcount; |
@@ -5489,32 +5484,25 @@ xfs_bmse_merge( | |||
5489 | error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, | 5484 | error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, |
5490 | got.br_blockcount, &i); | 5485 | got.br_blockcount, &i); |
5491 | if (error) | 5486 | if (error) |
5492 | goto out_error; | 5487 | return error; |
5493 | XFS_WANT_CORRUPTED_GOTO(i == 1, out_error); | 5488 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
5494 | 5489 | ||
5495 | error = xfs_btree_delete(cur, &i); | 5490 | error = xfs_btree_delete(cur, &i); |
5496 | if (error) | 5491 | if (error) |
5497 | goto out_error; | 5492 | return error; |
5498 | XFS_WANT_CORRUPTED_GOTO(i == 1, out_error); | 5493 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
5499 | 5494 | ||
5500 | /* lookup and update size of the previous extent */ | 5495 | /* lookup and update size of the previous extent */ |
5501 | error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock, | 5496 | error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock, |
5502 | left.br_blockcount, &i); | 5497 | left.br_blockcount, &i); |
5503 | if (error) | 5498 | if (error) |
5504 | goto out_error; | 5499 | return error; |
5505 | XFS_WANT_CORRUPTED_GOTO(i == 1, out_error); | 5500 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
5506 | 5501 | ||
5507 | left.br_blockcount = blockcount; | 5502 | left.br_blockcount = blockcount; |
5508 | 5503 | ||
5509 | error = xfs_bmbt_update(cur, left.br_startoff, left.br_startblock, | 5504 | return xfs_bmbt_update(cur, left.br_startoff, left.br_startblock, |
5510 | left.br_blockcount, left.br_state); | 5505 | left.br_blockcount, left.br_state); |
5511 | if (error) | ||
5512 | goto out_error; | ||
5513 | |||
5514 | return 0; | ||
5515 | |||
5516 | out_error: | ||
5517 | return error; | ||
5518 | } | 5506 | } |
5519 | 5507 | ||
5520 | /* | 5508 | /* |
@@ -5544,35 +5532,29 @@ xfs_bmse_shift_one( | |||
5544 | startoff = got.br_startoff - offset_shift_fsb; | 5532 | startoff = got.br_startoff - offset_shift_fsb; |
5545 | 5533 | ||
5546 | /* delalloc extents should be prevented by caller */ | 5534 | /* delalloc extents should be prevented by caller */ |
5547 | XFS_WANT_CORRUPTED_GOTO(!isnullstartblock(got.br_startblock), | 5535 | XFS_WANT_CORRUPTED_RETURN(!isnullstartblock(got.br_startblock)); |
5548 | out_error); | ||
5549 | 5536 | ||
5550 | /* | 5537 | /* |
5551 | * If this is the first extent in the file, make sure there's enough | 5538 | * Check for merge if we've got an extent to the left, otherwise make |
5552 | * room at the start of the file and jump right to the shift as there's | 5539 | * sure there's enough room at the start of the file for the shift. |
5553 | * no left extent to merge. | ||
5554 | */ | 5540 | */ |
5555 | if (*current_ext == 0) { | 5541 | if (*current_ext) { |
5556 | if (got.br_startoff < offset_shift_fsb) | 5542 | /* grab the left extent and check for a large enough hole */ |
5557 | return -EINVAL; | 5543 | leftp = xfs_iext_get_ext(ifp, *current_ext - 1); |
5558 | goto shift_extent; | 5544 | xfs_bmbt_get_all(leftp, &left); |
5559 | } | ||
5560 | 5545 | ||
5561 | /* grab the left extent and check for a large enough hole */ | 5546 | if (startoff < left.br_startoff + left.br_blockcount) |
5562 | leftp = xfs_iext_get_ext(ifp, *current_ext - 1); | 5547 | return -EINVAL; |
5563 | xfs_bmbt_get_all(leftp, &left); | ||
5564 | 5548 | ||
5565 | if (startoff < left.br_startoff + left.br_blockcount) | 5549 | /* check whether to merge the extent or shift it down */ |
5550 | if (xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) { | ||
5551 | return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, | ||
5552 | *current_ext, gotp, leftp, cur, | ||
5553 | logflags); | ||
5554 | } | ||
5555 | } else if (got.br_startoff < offset_shift_fsb) | ||
5566 | return -EINVAL; | 5556 | return -EINVAL; |
5567 | 5557 | ||
5568 | /* check whether to merge the extent or shift it down */ | ||
5569 | if (!xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) | ||
5570 | goto shift_extent; | ||
5571 | |||
5572 | return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, *current_ext, | ||
5573 | gotp, leftp, cur, logflags); | ||
5574 | |||
5575 | shift_extent: | ||
5576 | /* | 5558 | /* |
5577 | * Increment the extent index for the next iteration, update the start | 5559 | * Increment the extent index for the next iteration, update the start |
5578 | * offset of the in-core extent and update the btree if applicable. | 5560 | * offset of the in-core extent and update the btree if applicable. |
@@ -5589,18 +5571,11 @@ shift_extent: | |||
5589 | got.br_blockcount, &i); | 5571 | got.br_blockcount, &i); |
5590 | if (error) | 5572 | if (error) |
5591 | return error; | 5573 | return error; |
5592 | XFS_WANT_CORRUPTED_GOTO(i == 1, out_error); | 5574 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
5593 | 5575 | ||
5594 | got.br_startoff = startoff; | 5576 | got.br_startoff = startoff; |
5595 | error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, | 5577 | return xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, |
5596 | got.br_blockcount, got.br_state); | 5578 | got.br_blockcount, got.br_state); |
5597 | if (error) | ||
5598 | return error; | ||
5599 | |||
5600 | return 0; | ||
5601 | |||
5602 | out_error: | ||
5603 | return error; | ||
5604 | } | 5579 | } |
5605 | 5580 | ||
5606 | /* | 5581 | /* |