Commit da6f8410 authored by Chandan Babu R's avatar Chandan Babu R

Merge tag 'fix-fsmap-6.6_2023-09-12' of...

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: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandanbabu@kernel.org>

* 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
parents 57c0f4a8 cfa2df68
...@@ -565,6 +565,19 @@ xfs_getfsmap_rtdev_rtbitmap( ...@@ -565,6 +565,19 @@ xfs_getfsmap_rtdev_rtbitmap(
} }
#endif /* CONFIG_XFS_RT */ #endif /* CONFIG_XFS_RT */
static inline bool
rmap_not_shareable(struct xfs_mount *mp, const struct xfs_rmap_irec *r)
{
if (!xfs_has_reflink(mp))
return true;
if (XFS_RMAP_NON_INODE_OWNER(r->rm_owner))
return true;
if (r->rm_flags & (XFS_RMAP_ATTR_FORK | XFS_RMAP_BMBT_BLOCK |
XFS_RMAP_UNWRITTEN))
return true;
return false;
}
/* Execute a getfsmap query against the regular data device. */ /* Execute a getfsmap query against the regular data device. */
STATIC int STATIC int
__xfs_getfsmap_datadev( __xfs_getfsmap_datadev(
...@@ -598,7 +611,6 @@ __xfs_getfsmap_datadev( ...@@ -598,7 +611,6 @@ __xfs_getfsmap_datadev(
* low to the fsmap low key and max out the high key to the end * low to the fsmap low key and max out the high key to the end
* of the AG. * of the AG.
*/ */
info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb);
info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset); info->low.rm_offset = XFS_BB_TO_FSBT(mp, keys[0].fmr_offset);
error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]); error = xfs_fsmap_owner_to_rmap(&info->low, &keys[0]);
if (error) if (error)
...@@ -608,12 +620,9 @@ __xfs_getfsmap_datadev( ...@@ -608,12 +620,9 @@ __xfs_getfsmap_datadev(
/* Adjust the low key if we are continuing from where we left off. */ /* Adjust the low key if we are continuing from where we left off. */
if (info->low.rm_blockcount == 0) { if (info->low.rm_blockcount == 0) {
/* empty */ /* No previous record from which to continue */
} else if (XFS_RMAP_NON_INODE_OWNER(info->low.rm_owner) || } else if (rmap_not_shareable(mp, &info->low)) {
(info->low.rm_flags & (XFS_RMAP_ATTR_FORK | /* Last record seen was an unshareable extent */
XFS_RMAP_BMBT_BLOCK |
XFS_RMAP_UNWRITTEN))) {
info->low.rm_startblock += info->low.rm_blockcount;
info->low.rm_owner = 0; info->low.rm_owner = 0;
info->low.rm_offset = 0; info->low.rm_offset = 0;
...@@ -621,8 +630,10 @@ __xfs_getfsmap_datadev( ...@@ -621,8 +630,10 @@ __xfs_getfsmap_datadev(
if (XFS_FSB_TO_DADDR(mp, start_fsb) >= eofs) if (XFS_FSB_TO_DADDR(mp, start_fsb) >= eofs)
return 0; return 0;
} else { } else {
/* Last record seen was a shareable file data extent */
info->low.rm_offset += info->low.rm_blockcount; info->low.rm_offset += info->low.rm_blockcount;
} }
info->low.rm_startblock = XFS_FSB_TO_AGBNO(mp, start_fsb);
info->high.rm_startblock = -1U; info->high.rm_startblock = -1U;
info->high.rm_owner = ULLONG_MAX; info->high.rm_owner = ULLONG_MAX;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment