@@ -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+
9841010static int
9851011xfs_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