Skip to content

Commit da6f841

Browse files
author
Chandan Babu R
committed
Merge tag 'fix-fsmap-6.6_2023-09-12' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into xfs-6.6-fixesA
xfs: fix fsmap cursor handling This patchset addresses an integer overflow bug that Dave Chinner found in how fsmap handles figuring out where in the record set we left off when userspace calls back after the first call filled up all the designated record space. Signed-off-by: Darrick J. Wong <[email protected]> Signed-off-by: Chandan Babu R <[email protected]> * tag 'fix-fsmap-6.6_2023-09-12' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux: xfs: fix an agbno overflow in __xfs_getfsmap_datadev
2 parents 57c0f4a + cfa2df6 commit da6f841

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

fs/xfs/xfs_fsmap.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,19 @@ xfs_getfsmap_rtdev_rtbitmap(
565565
}
566566
#endif /* CONFIG_XFS_RT */
567567

568+
static inline bool
569+
rmap_not_shareable(struct xfs_mount *mp, const struct xfs_rmap_irec *r)
570+
{
571+
if (!xfs_has_reflink(mp))
572+
return true;
573+
if (XFS_RMAP_NON_INODE_OWNER(r->rm_owner))
574+
return true;
575+
if (r->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK |
576+
XFS_RMAP_UNWRITTEN))
577+
return true;
578+
return false;
579+
}
580+
568581
/* Execute a getfsmap query against the regular data device. */
569582
STATIC int
570583
__xfs_getfsmap_datadev(
@@ -598,7 +611,6 @@ __xfs_getfsmap_datadev(
598611
* low to the fsmap low key and max out the high key to the end
599612
* of the AG.
600613
*/
601-
info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb);
602614
info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset);
603615
error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]);
604616
if (error)
@@ -608,21 +620,20 @@ __xfs_getfsmap_datadev(
608620

609621
/* Adjust the low key if we are continuing from where we left off. */
610622
if (info->low.rm_blockcount == 0) {
611-
/* empty */
612-
} else if (XFS_RMAP_NON_INODE_OWNER(info->low.rm_owner) ||
613-
(info->low.rm_flags & (XFS_RMAP_ATTR_FORK |
614-
XFS_RMAP_BMBT_BLOCK |
615-
XFS_RMAP_UNWRITTEN))) {
616-
info->low.rm_startblock += info->low.rm_blockcount;
623+
/* No previous record from which to continue */
624+
} else if (rmap_not_shareable(mp, &info->low)) {
625+
/* Last record seen was an unshareable extent */
617626
info->low.rm_owner = 0;
618627
info->low.rm_offset = 0;
619628

620629
start_fsb += info->low.rm_blockcount;
621630
if (XFS_FSB_TO_DADDR(mp, start_fsb) >= eofs)
622631
return 0;
623632
} else {
633+
/* Last record seen was a shareable file data extent */
624634
info->low.rm_offset += info->low.rm_blockcount;
625635
}
636+
info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb);
626637

627638
info->high.rm_startblock = -1U;
628639
info->high.rm_owner = ULLONG_MAX;

0 commit comments

Comments
 (0)