Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Christoph Hellwig and committed by
Carlos Maiolino
12d12dcc b37c1e4e

+50 -64
+50 -64
fs/xfs/xfs_zone_alloc.c
··· 976 976 } 977 977 978 978 struct xfs_init_zones { 979 - struct xfs_mount *mp; 980 979 uint32_t zone_size; 981 980 uint32_t zone_capacity; 982 981 uint64_t available; ··· 993 994 * the most recently written ones got deleted again before unmount, but this is 994 995 * the best we can do without hardware support. 995 996 */ 996 - static xfs_rgblock_t 997 - xfs_rmap_estimate_write_pointer( 998 - struct xfs_rtgroup *rtg) 997 + static int 998 + xfs_query_write_pointer( 999 + struct xfs_init_zones *iz, 1000 + struct xfs_rtgroup *rtg, 1001 + xfs_rgblock_t *write_pointer) 999 1002 { 1003 + struct xfs_mount *mp = rtg_mount(rtg); 1004 + struct block_device *bdev = mp->m_rtdev_targp->bt_bdev; 1005 + sector_t start = xfs_gbno_to_daddr(&rtg->rtg_group, 0); 1000 1006 xfs_rgblock_t highest_rgbno; 1007 + struct blk_zone zone = {}; 1008 + int error; 1009 + 1010 + if (bdev_is_zoned(bdev)) { 1011 + error = blkdev_get_zone_info(bdev, start, &zone); 1012 + if (error) 1013 + return error; 1014 + if (zone.start != start) { 1015 + xfs_warn(mp, "mismatched zone start: 0x%llx/0x%llx.", 1016 + zone.start, start); 1017 + return -EFSCORRUPTED; 1018 + } 1019 + 1020 + if (!xfs_validate_blk_zone(mp, &zone, rtg_rgno(rtg), 1021 + iz->zone_size, iz->zone_capacity, 1022 + write_pointer)) 1023 + return -EFSCORRUPTED; 1024 + 1025 + /* 1026 + * Use the hardware write pointer returned by 1027 + * xfs_validate_blk_zone for sequential write required zones, 1028 + * else fall through to the rmap-based estimation below. 1029 + */ 1030 + if (zone.cond != BLK_ZONE_COND_NOT_WP) 1031 + return 0; 1032 + } 1001 1033 1002 1034 xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP); 1003 1035 highest_rgbno = xfs_rtrmap_highest_rgbno(rtg); 1004 1036 xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP); 1005 1037 1006 1038 if (highest_rgbno == NULLRGBLOCK) 1007 - return 0; 1008 - return highest_rgbno + 1; 1039 + *write_pointer = 0; 1040 + else 1041 + *write_pointer = highest_rgbno + 1; 1042 + return 0; 1009 1043 } 1010 1044 1011 1045 static int ··· 1114 1082 } 1115 1083 1116 1084 return 0; 1117 - } 1118 - 1119 - static int 1120 - xfs_get_zone_info_cb( 1121 - struct blk_zone *zone, 1122 - unsigned int idx, 1123 - void *data) 1124 - { 1125 - struct xfs_init_zones *iz = data; 1126 - struct xfs_mount *mp = iz->mp; 1127 - xfs_fsblock_t zsbno = xfs_daddr_to_rtb(mp, zone->start); 1128 - xfs_rgnumber_t rgno; 1129 - xfs_rgblock_t write_pointer; 1130 - struct xfs_rtgroup *rtg; 1131 - int error; 1132 - 1133 - if (xfs_rtb_to_rgbno(mp, zsbno) != 0) { 1134 - xfs_warn(mp, "mismatched zone start 0x%llx.", zsbno); 1135 - return -EFSCORRUPTED; 1136 - } 1137 - 1138 - rgno = xfs_rtb_to_rgno(mp, zsbno); 1139 - rtg = xfs_rtgroup_grab(mp, rgno); 1140 - if (!rtg) { 1141 - xfs_warn(mp, "realtime group not found for zone %u.", rgno); 1142 - return -EFSCORRUPTED; 1143 - } 1144 - if (!xfs_validate_blk_zone(mp, zone, idx, iz->zone_size, 1145 - iz->zone_capacity, &write_pointer)) { 1146 - xfs_rtgroup_rele(rtg); 1147 - return -EFSCORRUPTED; 1148 - } 1149 - if (zone->cond == BLK_ZONE_COND_NOT_WP) 1150 - write_pointer = xfs_rmap_estimate_write_pointer(rtg); 1151 - error = xfs_init_zone(iz, rtg, write_pointer); 1152 - xfs_rtgroup_rele(rtg); 1153 - return error; 1154 1085 } 1155 1086 1156 1087 /* ··· 1250 1255 struct xfs_mount *mp) 1251 1256 { 1252 1257 struct xfs_init_zones iz = { 1253 - .mp = mp, 1254 1258 .zone_capacity = mp->m_groups[XG_TYPE_RTG].blocks, 1255 1259 .zone_size = xfs_rtgroup_raw_size(mp), 1256 1260 }; 1257 - struct xfs_buftarg *bt = mp->m_rtdev_targp; 1258 - xfs_extlen_t zone_blocks = mp->m_groups[XG_TYPE_RTG].blocks; 1261 + struct xfs_rtgroup *rtg = NULL; 1259 1262 int error; 1260 1263 1261 - if (!bt) { 1264 + if (!mp->m_rtdev_targp) { 1262 1265 xfs_notice(mp, "RT device missing."); 1263 1266 return -EINVAL; 1264 1267 } ··· 1284 1291 return -ENOMEM; 1285 1292 1286 1293 xfs_info(mp, "%u zones of %u blocks (%u max open zones)", 1287 - mp->m_sb.sb_rgcount, zone_blocks, mp->m_max_open_zones); 1294 + mp->m_sb.sb_rgcount, iz.zone_capacity, mp->m_max_open_zones); 1288 1295 trace_xfs_zones_mount(mp); 1289 1296 1290 1297 /* ··· 1308 1315 * or beneficial. 1309 1316 */ 1310 1317 mp->m_super->s_min_writeback_pages = 1311 - XFS_FSB_TO_B(mp, min(zone_blocks, XFS_MAX_BMBT_EXTLEN)) >> 1318 + XFS_FSB_TO_B(mp, min(iz.zone_capacity, XFS_MAX_BMBT_EXTLEN)) >> 1312 1319 PAGE_SHIFT; 1313 1320 1314 - if (bdev_is_zoned(bt->bt_bdev)) { 1315 - error = blkdev_report_zones_cached(bt->bt_bdev, 1316 - XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart), 1317 - mp->m_sb.sb_rgcount, xfs_get_zone_info_cb, &iz); 1318 - if (error < 0) 1319 - goto out_free_zone_info; 1320 - } else { 1321 - struct xfs_rtgroup *rtg = NULL; 1321 + while ((rtg = xfs_rtgroup_next(mp, rtg))) { 1322 + xfs_rgblock_t write_pointer; 1322 1323 1323 - while ((rtg = xfs_rtgroup_next(mp, rtg))) { 1324 - error = xfs_init_zone(&iz, rtg, 1325 - xfs_rmap_estimate_write_pointer(rtg)); 1326 - if (error) { 1327 - xfs_rtgroup_rele(rtg); 1328 - goto out_free_zone_info; 1329 - } 1324 + error = xfs_query_write_pointer(&iz, rtg, &write_pointer); 1325 + if (!error) 1326 + error = xfs_init_zone(&iz, rtg, write_pointer); 1327 + if (error) { 1328 + xfs_rtgroup_rele(rtg); 1329 + goto out_free_zone_info; 1330 1330 } 1331 1331 } 1332 1332