diff options
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r-- | fs/xfs/xfs_bmap.c | 17 |
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 | ||
5565 | del_cursor: | 5571 | del_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 | } |