Unverified Commit 74e85e88 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!13234 xfs: Fix missing interval for missing_owner in xfs fsmap

parents c795ec3a ef9e4394
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -158,6 +158,7 @@ struct xfs_getfsmap_info {
	struct fsmap		*fsmap_recs;	/* mapping records */
	struct xfs_buf		*agf_bp;	/* AGF, for refcount queries */
	xfs_daddr_t		next_daddr;	/* next daddr we expect */
	xfs_daddr_t		end_daddr;	/* daddr of high fsmap key */
	u64			missing_owner;	/* owner of holes */
	u32			dev;		/* device id */
	xfs_agnumber_t		agno;		/* AG number, if applicable */
@@ -172,6 +173,7 @@ struct xfs_getfsmap_dev {
	int			(*fn)(struct xfs_trans *tp,
				      const struct xfs_fsmap *keys,
				      struct xfs_getfsmap_info *info);
	sector_t		nr_sectors;
};

/* Compare two getfsmap device handlers. */
@@ -267,6 +269,18 @@ xfs_getfsmap_helper(
		return 0;
	}

	/*
	 * For an info->last query, we're looking for a gap between the last
	 * mapping emitted and the high key specified by userspace.  If the
	 * user's query spans less than 1 fsblock, then info->high and
	 * info->low will have the same rm_startblock, which causes rec_daddr
	 * and next_daddr to be the same.  Therefore, use the end_daddr that
	 * we calculated from userspace's high key to synthesize the record.
	 * Note that if the btree query found a mapping, there won't be a gap.
	 */
	if (info->last && info->end_daddr != XFS_BUF_DADDR_NULL)
		rec_daddr = info->end_daddr;

	/* Are we just counting mappings? */
	if (info->head->fmh_count == 0) {
		if (info->head->fmh_entries == UINT_MAX)
@@ -855,17 +869,21 @@ xfs_getfsmap(

	/* Set up our device handlers. */
	memset(handlers, 0, sizeof(handlers));
	handlers[0].nr_sectors = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
	handlers[0].dev = new_encode_dev(mp->m_ddev_targp->bt_dev);
	if (use_rmap)
		handlers[0].fn = xfs_getfsmap_datadev_rmapbt;
	else
		handlers[0].fn = xfs_getfsmap_datadev_bnobt;
	if (mp->m_logdev_targp != mp->m_ddev_targp) {
		handlers[1].nr_sectors = XFS_FSB_TO_BB(mp,
						       mp->m_sb.sb_logblocks);
		handlers[1].dev = new_encode_dev(mp->m_logdev_targp->bt_dev);
		handlers[1].fn = xfs_getfsmap_logdev;
	}
#ifdef CONFIG_XFS_RT
	if (mp->m_rtdev_targp) {
		handlers[2].nr_sectors = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
		handlers[2].dev = new_encode_dev(mp->m_rtdev_targp->bt_dev);
		handlers[2].fn = xfs_getfsmap_rtdev_rtbitmap;
	}
@@ -908,6 +926,7 @@ xfs_getfsmap(

	info.next_daddr = head->fmh_keys[0].fmr_physical +
			  head->fmh_keys[0].fmr_length;
	info.end_daddr = XFS_BUF_DADDR_NULL;
	info.fsmap_recs = fsmap_recs;
	info.head = head;

@@ -936,8 +955,11 @@ xfs_getfsmap(
		 * low key, zero out the low key so that we get
		 * everything from the beginning.
		 */
		if (handlers[i].dev == head->fmh_keys[1].fmr_device)
		if (handlers[i].dev == head->fmh_keys[1].fmr_device) {
			dkeys[1] = head->fmh_keys[1];
			info.end_daddr = min(handlers[i].nr_sectors - 1,
					     dkeys[1].fmr_physical);
		}
		if (handlers[i].dev > head->fmh_keys[0].fmr_device)
			memset(&dkeys[0], 0, sizeof(struct xfs_fsmap));