File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -398,6 +398,7 @@ xfs_sb_has_ro_compat_feature(
398398#define XFS_SB_FEAT_INCOMPAT_PARENT (1 << 7) /* parent pointers */
399399#define XFS_SB_FEAT_INCOMPAT_METADIR (1 << 8) /* metadata dir tree */
400400#define XFS_SB_FEAT_INCOMPAT_ZONED (1 << 9) /* zoned RT allocator */
401+ #define XFS_SB_FEAT_INCOMPAT_ZONE_GAPS (1 << 10) /* RTGs have LBA gaps */
401402
402403#define XFS_SB_FEAT_INCOMPAT_ALL \
403404 (XFS_SB_FEAT_INCOMPAT_FTYPE | \
@@ -409,7 +410,8 @@ xfs_sb_has_ro_compat_feature(
409410 XFS_SB_FEAT_INCOMPAT_EXCHRANGE | \
410411 XFS_SB_FEAT_INCOMPAT_PARENT | \
411412 XFS_SB_FEAT_INCOMPAT_METADIR | \
412- XFS_SB_FEAT_INCOMPAT_ZONED)
413+ XFS_SB_FEAT_INCOMPAT_ZONED | \
414+ XFS_SB_FEAT_INCOMPAT_ZONE_GAPS)
413415
414416#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
415417static inline bool
Original file line number Diff line number Diff line change @@ -123,7 +123,11 @@ xfs_gbno_to_daddr(
123123 struct xfs_groups * g = & mp -> m_groups [xg -> xg_type ];
124124 xfs_fsblock_t fsbno ;
125125
126- fsbno = (xfs_fsblock_t )xg -> xg_gno * g -> blocks + gbno ;
126+ if (g -> has_daddr_gaps )
127+ fsbno = xfs_gbno_to_fsb (xg , gbno );
128+ else
129+ fsbno = (xfs_fsblock_t )xg -> xg_gno * g -> blocks + gbno ;
130+
127131 return XFS_FSB_TO_BB (mp , g -> start_fsb + fsbno );
128132}
129133
Original file line number Diff line number Diff line change @@ -245,11 +245,14 @@ xfs_rtb_to_daddr(
245245 xfs_rtblock_t rtbno )
246246{
247247 struct xfs_groups * g = & mp -> m_groups [XG_TYPE_RTG ];
248- xfs_rgnumber_t rgno = xfs_rtb_to_rgno (mp , rtbno );
249- uint64_t start_bno = (xfs_rtblock_t )rgno * g -> blocks ;
250248
251- return XFS_FSB_TO_BB (mp ,
252- g -> start_fsb + start_bno + (rtbno & g -> blkmask ));
249+ if (xfs_has_rtgroups (mp ) && !g -> has_daddr_gaps ) {
250+ xfs_rgnumber_t rgno = xfs_rtb_to_rgno (mp , rtbno );
251+
252+ rtbno = (xfs_rtblock_t )rgno * g -> blocks + (rtbno & g -> blkmask );
253+ }
254+
255+ return XFS_FSB_TO_BB (mp , g -> start_fsb + rtbno );
253256}
254257
255258static inline xfs_rtblock_t
@@ -261,7 +264,7 @@ xfs_daddr_to_rtb(
261264 xfs_rfsblock_t bno ;
262265
263266 bno = XFS_BB_TO_FSBT (mp , daddr ) - g -> start_fsb ;
264- if (xfs_has_rtgroups (mp )) {
267+ if (xfs_has_rtgroups (mp ) && ! g -> has_daddr_gaps ) {
265268 xfs_rgnumber_t rgno ;
266269 uint32_t rgbno ;
267270
Original file line number Diff line number Diff line change @@ -1205,6 +1205,9 @@ xfs_sb_mount_rextsize(
12051205 rgs -> blklog = mp -> m_sb .sb_rgblklog ;
12061206 rgs -> blkmask = xfs_mask32lo (mp -> m_sb .sb_rgblklog );
12071207 rgs -> start_fsb = mp -> m_sb .sb_rtstart ;
1208+ if (xfs_sb_has_incompat_feature (sbp ,
1209+ XFS_SB_FEAT_INCOMPAT_ZONE_GAPS ))
1210+ rgs -> has_daddr_gaps = true;
12081211 } else {
12091212 rgs -> blocks = 0 ;
12101213 rgs -> blklog = 0 ;
Original file line number Diff line number Diff line change @@ -137,6 +137,7 @@ xfs_zone_validate(
137137{
138138 struct xfs_mount * mp = rtg_mount (rtg );
139139 struct xfs_groups * g = & mp -> m_groups [XG_TYPE_RTG ];
140+ uint32_t expected_size ;
140141
141142 /*
142143 * Check that the zone capacity matches the rtgroup size stored in the
@@ -151,11 +152,25 @@ xfs_zone_validate(
151152 return false;
152153 }
153154
154- if (XFS_BB_TO_FSB (mp , zone -> len ) != 1 << g -> blklog ) {
155+ if (g -> has_daddr_gaps ) {
156+ expected_size = 1 << g -> blklog ;
157+ } else {
158+ if (zone -> len != zone -> capacity ) {
159+ xfs_warn (mp ,
160+ "zone %u has capacity != size ((0x%llx vs 0x%llx)" ,
161+ rtg_rgno (rtg ),
162+ XFS_BB_TO_FSB (mp , zone -> len ),
163+ XFS_BB_TO_FSB (mp , zone -> capacity ));
164+ return false;
165+ }
166+ expected_size = g -> blocks ;
167+ }
168+
169+ if (XFS_BB_TO_FSB (mp , zone -> len ) != expected_size ) {
155170 xfs_warn (mp ,
156171"zone %u length (0x%llx) does match geometry (0x%x)." ,
157172 rtg_rgno (rtg ), XFS_BB_TO_FSB (mp , zone -> len ),
158- 1 << g -> blklog );
173+ expected_size );
159174 }
160175
161176 switch (zone -> type ) {
Original file line number Diff line number Diff line change @@ -97,6 +97,15 @@ struct xfs_groups {
9797 */
9898 uint8_t blklog ;
9999
100+ /*
101+ * Zoned devices can have gaps beyond the usable capacity of a zone and
102+ * the end in the LBA/daddr address space. In other words, the hardware
103+ * equivalent to the RT groups already takes care of the power of 2
104+ * alignment for us. In this case the sparse FSB/RTB address space maps
105+ * 1:1 to the device address space.
106+ */
107+ bool has_daddr_gaps ;
108+
100109 /*
101110 * Mask to extract the group-relative block number from a FSB.
102111 * For a pre-rtgroups filesystem we pretend to have one very large
You can’t perform that action at this time.
0 commit comments