@@ -976,7 +976,6 @@ xfs_free_open_zones(
976976}
977977
978978struct 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
10121044static 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