aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/libxfs/xfs_bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs/xfs_bmap.c')
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c77
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
5516out_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
5575shift_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
5602out_error:
5603 return error;
5604} 5579}
5605 5580
5606/* 5581/*