summaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2017-06-16 14:00:12 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2017-06-20 13:45:21 -0400
commitd29cb3e45e923715f74d8a08d5c1ea996dce5a59 (patch)
tree1d9224fcb46576b180f587609419b2ea53de1e76 /fs/xfs
parentea7cdd7b7baffc40d1e60de7c93e5b1aabb3d081 (diff)
xfs: make _bmap_count_blocks consistent wrt delalloc extent behavior
There is an inconsistency in the way that _bmap_count_blocks deals with delalloc reservations -- if the specified fork is in extents format, *count is set to the total number of blocks referenced by the in-core fork, including delalloc extents. However, if the fork is in btree format, *count is set to the number of blocks referenced by the on-disk fork, which does /not/ include delalloc extents. For the lone existing caller of _bmap_count_blocks this hasn't been an issue because the function is only used to count xattr fork blocks (where there aren't any delalloc reservations). However, when scrub comes along it will use this same function to check di_nblocks against both on-disk extent maps, so we need this behavior to be consistent. Therefore, fix _bmap_count_leaves not to include delalloc extents and remove unnecessary parameters. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_bmap_util.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 863180c41858..424e3bd12700 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -219,20 +219,22 @@ xfs_bmap_eof(
219 */ 219 */
220 220
221/* 221/*
222 * Count leaf blocks given a range of extent records. 222 * Count leaf blocks given a range of extent records. Delayed allocation
223 * extents are not counted towards the totals.
223 */ 224 */
224STATIC void 225STATIC void
225xfs_bmap_count_leaves( 226xfs_bmap_count_leaves(
226 xfs_ifork_t *ifp, 227 struct xfs_ifork *ifp,
227 xfs_extnum_t idx,
228 int numrecs,
229 int *count) 228 int *count)
230{ 229{
231 int b; 230 xfs_extnum_t i;
231 xfs_extnum_t nr_exts = xfs_iext_count(ifp);
232 232
233 for (b = 0; b < numrecs; b++) { 233 for (i = 0; i < nr_exts; i++) {
234 xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b); 234 xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, i);
235 *count += xfs_bmbt_get_blockcount(frp); 235 if (!isnullstartblock(xfs_bmbt_get_startblock(frp))) {
236 *count += xfs_bmbt_get_blockcount(frp);
237 }
236 } 238 }
237} 239}
238 240
@@ -334,7 +336,8 @@ xfs_bmap_count_tree(
334} 336}
335 337
336/* 338/*
337 * Count fsblocks of the given fork. 339 * Count fsblocks of the given fork. Delayed allocation extents are
340 * not counted towards the totals.
338 */ 341 */
339static int /* error */ 342static int /* error */
340xfs_bmap_count_blocks( 343xfs_bmap_count_blocks(
@@ -354,7 +357,7 @@ xfs_bmap_count_blocks(
354 mp = ip->i_mount; 357 mp = ip->i_mount;
355 ifp = XFS_IFORK_PTR(ip, whichfork); 358 ifp = XFS_IFORK_PTR(ip, whichfork);
356 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) { 359 if ( XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS ) {
357 xfs_bmap_count_leaves(ifp, 0, xfs_iext_count(ifp), count); 360 xfs_bmap_count_leaves(ifp, count);
358 return 0; 361 return 0;
359 } 362 }
360 363