Skip to content

Commit 12d12dc

Browse files
Christoph Hellwigcmaiolino
authored andcommitted
xfs: use blkdev_get_zone_info to simplify zone reporting
Unwind the callback based programming model by querying the cached zone information using blkdev_get_zone_info. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
1 parent b37c1e4 commit 12d12dc

1 file changed

Lines changed: 50 additions & 64 deletions

File tree

fs/xfs/xfs_zone_alloc.c

Lines changed: 50 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,6 @@ xfs_free_open_zones(
976976
}
977977

978978
struct xfs_init_zones {
979-
struct xfs_mount *mp;
980979
uint32_t zone_size;
981980
uint32_t zone_capacity;
982981
uint64_t available;
@@ -994,19 +993,52 @@ struct xfs_init_zones {
994993
* the most recently written ones got deleted again before unmount, but this is
995994
* the best we can do without hardware support.
996995
*/
997-
static xfs_rgblock_t
998-
xfs_rmap_estimate_write_pointer(
999-
struct xfs_rtgroup *rtg)
996+
static int
997+
xfs_query_write_pointer(
998+
struct xfs_init_zones *iz,
999+
struct xfs_rtgroup *rtg,
1000+
xfs_rgblock_t *write_pointer)
10001001
{
1002+
struct xfs_mount *mp = rtg_mount(rtg);
1003+
struct block_device *bdev = mp->m_rtdev_targp->bt_bdev;
1004+
sector_t start = xfs_gbno_to_daddr(&rtg->rtg_group, 0);
10011005
xfs_rgblock_t highest_rgbno;
1006+
struct blk_zone zone = {};
1007+
int error;
1008+
1009+
if (bdev_is_zoned(bdev)) {
1010+
error = blkdev_get_zone_info(bdev, start, &zone);
1011+
if (error)
1012+
return error;
1013+
if (zone.start != start) {
1014+
xfs_warn(mp, "mismatched zone start: 0x%llx/0x%llx.",
1015+
zone.start, start);
1016+
return -EFSCORRUPTED;
1017+
}
1018+
1019+
if (!xfs_validate_blk_zone(mp, &zone, rtg_rgno(rtg),
1020+
iz->zone_size, iz->zone_capacity,
1021+
write_pointer))
1022+
return -EFSCORRUPTED;
1023+
1024+
/*
1025+
* Use the hardware write pointer returned by
1026+
* xfs_validate_blk_zone for sequential write required zones,
1027+
* else fall through to the rmap-based estimation below.
1028+
*/
1029+
if (zone.cond != BLK_ZONE_COND_NOT_WP)
1030+
return 0;
1031+
}
10021032

10031033
xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
10041034
highest_rgbno = xfs_rtrmap_highest_rgbno(rtg);
10051035
xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);
10061036

10071037
if (highest_rgbno == NULLRGBLOCK)
1008-
return 0;
1009-
return highest_rgbno + 1;
1038+
*write_pointer = 0;
1039+
else
1040+
*write_pointer = highest_rgbno + 1;
1041+
return 0;
10101042
}
10111043

10121044
static int
@@ -1084,43 +1116,6 @@ xfs_init_zone(
10841116
return 0;
10851117
}
10861118

1087-
static int
1088-
xfs_get_zone_info_cb(
1089-
struct blk_zone *zone,
1090-
unsigned int idx,
1091-
void *data)
1092-
{
1093-
struct xfs_init_zones *iz = data;
1094-
struct xfs_mount *mp = iz->mp;
1095-
xfs_fsblock_t zsbno = xfs_daddr_to_rtb(mp, zone->start);
1096-
xfs_rgnumber_t rgno;
1097-
xfs_rgblock_t write_pointer;
1098-
struct xfs_rtgroup *rtg;
1099-
int error;
1100-
1101-
if (xfs_rtb_to_rgbno(mp, zsbno) != 0) {
1102-
xfs_warn(mp, "mismatched zone start 0x%llx.", zsbno);
1103-
return -EFSCORRUPTED;
1104-
}
1105-
1106-
rgno = xfs_rtb_to_rgno(mp, zsbno);
1107-
rtg = xfs_rtgroup_grab(mp, rgno);
1108-
if (!rtg) {
1109-
xfs_warn(mp, "realtime group not found for zone %u.", rgno);
1110-
return -EFSCORRUPTED;
1111-
}
1112-
if (!xfs_validate_blk_zone(mp, zone, idx, iz->zone_size,
1113-
iz->zone_capacity, &write_pointer)) {
1114-
xfs_rtgroup_rele(rtg);
1115-
return -EFSCORRUPTED;
1116-
}
1117-
if (zone->cond == BLK_ZONE_COND_NOT_WP)
1118-
write_pointer = xfs_rmap_estimate_write_pointer(rtg);
1119-
error = xfs_init_zone(iz, rtg, write_pointer);
1120-
xfs_rtgroup_rele(rtg);
1121-
return error;
1122-
}
1123-
11241119
/*
11251120
* Calculate the max open zone limit based on the of number of backing zones
11261121
* available.
@@ -1255,15 +1250,13 @@ xfs_mount_zones(
12551250
struct xfs_mount *mp)
12561251
{
12571252
struct xfs_init_zones iz = {
1258-
.mp = mp,
12591253
.zone_capacity = mp->m_groups[XG_TYPE_RTG].blocks,
12601254
.zone_size = xfs_rtgroup_raw_size(mp),
12611255
};
1262-
struct xfs_buftarg *bt = mp->m_rtdev_targp;
1263-
xfs_extlen_t zone_blocks = mp->m_groups[XG_TYPE_RTG].blocks;
1256+
struct xfs_rtgroup *rtg = NULL;
12641257
int error;
12651258

1266-
if (!bt) {
1259+
if (!mp->m_rtdev_targp) {
12671260
xfs_notice(mp, "RT device missing.");
12681261
return -EINVAL;
12691262
}
@@ -1291,7 +1284,7 @@ xfs_mount_zones(
12911284
return -ENOMEM;
12921285

12931286
xfs_info(mp, "%u zones of %u blocks (%u max open zones)",
1294-
mp->m_sb.sb_rgcount, zone_blocks, mp->m_max_open_zones);
1287+
mp->m_sb.sb_rgcount, iz.zone_capacity, mp->m_max_open_zones);
12951288
trace_xfs_zones_mount(mp);
12961289

12971290
/*
@@ -1315,25 +1308,18 @@ xfs_mount_zones(
13151308
* or beneficial.
13161309
*/
13171310
mp->m_super->s_min_writeback_pages =
1318-
XFS_FSB_TO_B(mp, min(zone_blocks, XFS_MAX_BMBT_EXTLEN)) >>
1311+
XFS_FSB_TO_B(mp, min(iz.zone_capacity, XFS_MAX_BMBT_EXTLEN)) >>
13191312
PAGE_SHIFT;
13201313

1321-
if (bdev_is_zoned(bt->bt_bdev)) {
1322-
error = blkdev_report_zones_cached(bt->bt_bdev,
1323-
XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart),
1324-
mp->m_sb.sb_rgcount, xfs_get_zone_info_cb, &iz);
1325-
if (error < 0)
1314+
while ((rtg = xfs_rtgroup_next(mp, rtg))) {
1315+
xfs_rgblock_t write_pointer;
1316+
1317+
error = xfs_query_write_pointer(&iz, rtg, &write_pointer);
1318+
if (!error)
1319+
error = xfs_init_zone(&iz, rtg, write_pointer);
1320+
if (error) {
1321+
xfs_rtgroup_rele(rtg);
13261322
goto out_free_zone_info;
1327-
} else {
1328-
struct xfs_rtgroup *rtg = NULL;
1329-
1330-
while ((rtg = xfs_rtgroup_next(mp, rtg))) {
1331-
error = xfs_init_zone(&iz, rtg,
1332-
xfs_rmap_estimate_write_pointer(rtg));
1333-
if (error) {
1334-
xfs_rtgroup_rele(rtg);
1335-
goto out_free_zone_info;
1336-
}
13371323
}
13381324
}
13391325

0 commit comments

Comments
 (0)