Skip to content

Commit 5948705

Browse files
Christoph Hellwigcmaiolino
authored andcommitted
xfs: don't allocate the xfs_extent_busy structure for zoned RTGs
Busy extent tracking is primarily used to ensure that freed blocks are not reused for data allocations before the transaction that deleted them has been committed to stable storage, and secondarily to drive online discard. None of the use cases applies to zoned RTGs, as the zoned allocator can't overwrite blocks before resetting the zone, which already flushes out all transactions touching the RTGs. So the busy extent tracking is not needed for zoned RTGs, and also not called for zoned RTGs. But somehow the code to skip allocating and freeing the structure got lost during the zoned XFS upstreaming process. This not only causes these structures to unnecessarily allocated, but can also lead to memory leaks as the xg_busy_extents pointer in the xfs_group structure is overlayed with the pointer for the linked list of to be reset zones. Stop allocating and freeing the structure to not pointlessly allocate memory which is then leaked when the zone is reset. Fixes: 080d01c ("xfs: implement zoned garbage collection") Signed-off-by: Christoph Hellwig <[email protected]> Cc: <[email protected]> # v6.15 [cem: Fix type and add stable tag] Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Carlos Maiolino <[email protected]>
1 parent 9b027aa commit 5948705

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

fs/xfs/libxfs/xfs_group.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ xfs_group_free(
163163

164164
xfs_defer_drain_free(&xg->xg_intents_drain);
165165
#ifdef __KERNEL__
166-
kfree(xg->xg_busy_extents);
166+
if (xfs_group_has_extent_busy(xg->xg_mount, xg->xg_type))
167+
kfree(xg->xg_busy_extents);
167168
#endif
168169

169170
if (uninit)
@@ -189,9 +190,11 @@ xfs_group_insert(
189190
xg->xg_type = type;
190191

191192
#ifdef __KERNEL__
192-
xg->xg_busy_extents = xfs_extent_busy_alloc();
193-
if (!xg->xg_busy_extents)
194-
return -ENOMEM;
193+
if (xfs_group_has_extent_busy(mp, type)) {
194+
xg->xg_busy_extents = xfs_extent_busy_alloc();
195+
if (!xg->xg_busy_extents)
196+
return -ENOMEM;
197+
}
195198
spin_lock_init(&xg->xg_state_lock);
196199
xfs_hooks_init(&xg->xg_rmap_update_hooks);
197200
#endif
@@ -210,7 +213,8 @@ xfs_group_insert(
210213
out_drain:
211214
xfs_defer_drain_free(&xg->xg_intents_drain);
212215
#ifdef __KERNEL__
213-
kfree(xg->xg_busy_extents);
216+
if (xfs_group_has_extent_busy(xg->xg_mount, xg->xg_type))
217+
kfree(xg->xg_busy_extents);
214218
#endif
215219
return error;
216220
}

fs/xfs/xfs_extent_busy.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,12 @@ static inline void xfs_extent_busy_sort(struct list_head *list)
6868
list_sort(NULL, list, xfs_extent_busy_ag_cmp);
6969
}
7070

71+
/*
72+
* Zoned RTGs don't need to track busy extents, as the actual block freeing only
73+
* happens by a zone reset, which forces out all transactions that touched the
74+
* to be reset zone first.
75+
*/
76+
#define xfs_group_has_extent_busy(mp, type) \
77+
((type) == XG_TYPE_AG || !xfs_has_zoned((mp)))
78+
7179
#endif /* __XFS_EXTENT_BUSY_H__ */

0 commit comments

Comments
 (0)