aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 5b6092ef51ef..f0efc7e970ef 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -5413,6 +5413,7 @@ xfs_bmap_shift_extents(
5413 int whichfork = XFS_DATA_FORK; 5413 int whichfork = XFS_DATA_FORK;
5414 int logflags; 5414 int logflags;
5415 xfs_filblks_t blockcount = 0; 5415 xfs_filblks_t blockcount = 0;
5416 int total_extents;
5416 5417
5417 if (unlikely(XFS_TEST_ERROR( 5418 if (unlikely(XFS_TEST_ERROR(
5418 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && 5419 (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
@@ -5429,7 +5430,6 @@ xfs_bmap_shift_extents(
5429 ASSERT(current_ext != NULL); 5430 ASSERT(current_ext != NULL);
5430 5431
5431 ifp = XFS_IFORK_PTR(ip, whichfork); 5432 ifp = XFS_IFORK_PTR(ip, whichfork);
5432
5433 if (!(ifp->if_flags & XFS_IFEXTENTS)) { 5433 if (!(ifp->if_flags & XFS_IFEXTENTS)) {
5434 /* Read in all the extents */ 5434 /* Read in all the extents */
5435 error = xfs_iread_extents(tp, ip, whichfork); 5435 error = xfs_iread_extents(tp, ip, whichfork);
@@ -5456,7 +5456,6 @@ xfs_bmap_shift_extents(
5456 5456
5457 /* We are going to change core inode */ 5457 /* We are going to change core inode */
5458 logflags = XFS_ILOG_CORE; 5458 logflags = XFS_ILOG_CORE;
5459
5460 if (ifp->if_flags & XFS_IFBROOT) { 5459 if (ifp->if_flags & XFS_IFBROOT) {
5461 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); 5460 cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
5462 cur->bc_private.b.firstblock = *firstblock; 5461 cur->bc_private.b.firstblock = *firstblock;
@@ -5467,8 +5466,14 @@ xfs_bmap_shift_extents(
5467 logflags |= XFS_ILOG_DEXT; 5466 logflags |= XFS_ILOG_DEXT;
5468 } 5467 }
5469 5468
5470 while (nexts++ < num_exts && 5469 /*
5471 *current_ext < XFS_IFORK_NEXTENTS(ip, whichfork)) { 5470 * There may be delalloc extents in the data fork before the range we
5471 * are collapsing out, so we cannot
5472 * use the count of real extents here. Instead we have to calculate it
5473 * from the incore fork.
5474 */
5475 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
5476 while (nexts++ < num_exts && *current_ext < total_extents) {
5472 5477
5473 gotp = xfs_iext_get_ext(ifp, *current_ext); 5478 gotp = xfs_iext_get_ext(ifp, *current_ext);
5474 xfs_bmbt_get_all(gotp, &got); 5479 xfs_bmbt_get_all(gotp, &got);
@@ -5556,10 +5561,11 @@ xfs_bmap_shift_extents(
5556 } 5561 }
5557 5562
5558 (*current_ext)++; 5563 (*current_ext)++;
5564 total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
5559 } 5565 }
5560 5566
5561 /* Check if we are done */ 5567 /* Check if we are done */
5562 if (*current_ext == XFS_IFORK_NEXTENTS(ip, whichfork)) 5568 if (*current_ext == total_extents)
5563 *done = 1; 5569 *done = 1;
5564 5570
5565del_cursor: 5571del_cursor:
@@ -5568,6 +5574,5 @@ del_cursor:
5568 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); 5574 error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
5569 5575
5570 xfs_trans_log_inode(tp, ip, logflags); 5576 xfs_trans_log_inode(tp, ip, logflags);
5571
5572 return error; 5577 return error;
5573} 5578}