Skip to content

Commit 776b76f

Browse files
Christoph Hellwigcmaiolino
authored andcommitted
xfs: pass the write pointer to xfs_init_zone
Move the two methods to query the write pointer out of xfs_init_zone into the callers, so that xfs_init_zone doesn't have to bother with the blk_zone structure and instead operates purely at the XFS realtime group level. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
1 parent fc633b5 commit 776b76f

1 file changed

Lines changed: 37 additions & 29 deletions

File tree

fs/xfs/xfs_zone_alloc.c

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -981,43 +981,43 @@ struct xfs_init_zones {
981981
uint64_t reclaimable;
982982
};
983983

984+
/*
985+
* For sequential write required zones, we restart writing at the hardware write
986+
* pointer returned by xfs_zone_validate().
987+
*
988+
* For conventional zones or conventional devices we have to query the rmap to
989+
* find the highest recorded block and set the write pointer to the block after
990+
* that. In case of a power loss this misses blocks where the data I/O has
991+
* completed but not recorded in the rmap yet, and it also rewrites blocks if
992+
* the most recently written ones got deleted again before unmount, but this is
993+
* the best we can do without hardware support.
994+
*/
995+
static xfs_rgblock_t
996+
xfs_rmap_estimate_write_pointer(
997+
struct xfs_rtgroup *rtg)
998+
{
999+
xfs_rgblock_t highest_rgbno;
1000+
1001+
xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
1002+
highest_rgbno = xfs_rtrmap_highest_rgbno(rtg);
1003+
xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);
1004+
1005+
if (highest_rgbno == NULLRGBLOCK)
1006+
return 0;
1007+
return highest_rgbno + 1;
1008+
}
1009+
9841010
static int
9851011
xfs_init_zone(
9861012
struct xfs_init_zones *iz,
9871013
struct xfs_rtgroup *rtg,
988-
struct blk_zone *zone)
1014+
xfs_rgblock_t write_pointer)
9891015
{
9901016
struct xfs_mount *mp = rtg_mount(rtg);
9911017
struct xfs_zone_info *zi = mp->m_zone_info;
9921018
uint32_t used = rtg_rmap(rtg)->i_used_blocks;
993-
xfs_rgblock_t write_pointer, highest_rgbno;
9941019
int error;
9951020

996-
if (zone && !xfs_zone_validate(zone, rtg, &write_pointer))
997-
return -EFSCORRUPTED;
998-
999-
/*
1000-
* For sequential write required zones we retrieved the hardware write
1001-
* pointer above.
1002-
*
1003-
* For conventional zones or conventional devices we don't have that
1004-
* luxury. Instead query the rmap to find the highest recorded block
1005-
* and set the write pointer to the block after that. In case of a
1006-
* power loss this misses blocks where the data I/O has completed but
1007-
* not recorded in the rmap yet, and it also rewrites blocks if the most
1008-
* recently written ones got deleted again before unmount, but this is
1009-
* the best we can do without hardware support.
1010-
*/
1011-
if (!zone || zone->cond == BLK_ZONE_COND_NOT_WP) {
1012-
xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
1013-
highest_rgbno = xfs_rtrmap_highest_rgbno(rtg);
1014-
if (highest_rgbno == NULLRGBLOCK)
1015-
write_pointer = 0;
1016-
else
1017-
write_pointer = highest_rgbno + 1;
1018-
xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);
1019-
}
1020-
10211021
/*
10221022
* If there are no used blocks, but the zone is not in empty state yet
10231023
* we lost power before the zoned reset. In that case finish the work
@@ -1066,6 +1066,7 @@ xfs_get_zone_info_cb(
10661066
struct xfs_mount *mp = iz->mp;
10671067
xfs_fsblock_t zsbno = xfs_daddr_to_rtb(mp, zone->start);
10681068
xfs_rgnumber_t rgno;
1069+
xfs_rgblock_t write_pointer;
10691070
struct xfs_rtgroup *rtg;
10701071
int error;
10711072

@@ -1080,7 +1081,13 @@ xfs_get_zone_info_cb(
10801081
xfs_warn(mp, "realtime group not found for zone %u.", rgno);
10811082
return -EFSCORRUPTED;
10821083
}
1083-
error = xfs_init_zone(iz, rtg, zone);
1084+
if (!xfs_zone_validate(zone, rtg, &write_pointer)) {
1085+
xfs_rtgroup_rele(rtg);
1086+
return -EFSCORRUPTED;
1087+
}
1088+
if (zone->cond == BLK_ZONE_COND_NOT_WP)
1089+
write_pointer = xfs_rmap_estimate_write_pointer(rtg);
1090+
error = xfs_init_zone(iz, rtg, write_pointer);
10841091
xfs_rtgroup_rele(rtg);
10851092
return error;
10861093
}
@@ -1290,7 +1297,8 @@ xfs_mount_zones(
12901297
struct xfs_rtgroup *rtg = NULL;
12911298

12921299
while ((rtg = xfs_rtgroup_next(mp, rtg))) {
1293-
error = xfs_init_zone(&iz, rtg, NULL);
1300+
error = xfs_init_zone(&iz, rtg,
1301+
xfs_rmap_estimate_write_pointer(rtg));
12941302
if (error) {
12951303
xfs_rtgroup_rele(rtg);
12961304
goto out_free_zone_info;

0 commit comments

Comments
 (0)