From: Christoph Hellwig Date: Mon, 14 Apr 2025 05:36:02 +0000 (+0200) Subject: xfs: add support for zoned space reservations X-Git-Tag: v6.15.0~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d22f260a04fe1f71fbff9a0cae125d61634c8d70;p=thirdparty%2Fxfsprogs-dev.git xfs: add support for zoned space reservations Source kernel commit: 0bb2193056b5969e4148fc0909e89a5362da873e For zoned file systems garbage collection (GC) has to take the iolock and mmaplock after moving data to a new place to synchronize with readers. This means waiting for garbage collection with the iolock can deadlock. To avoid this, the worst case required blocks have to be reserved before taking the iolock, which is done using a new RTAVAILABLE counter that tracks blocks that are free to write into and don't require garbage collection. The new helpers try to take these available blocks, and if there aren't enough available it wakes and waits for GC. This is done using a list of on-stack reservations to ensure fairness. Co-developed-by: Hans Holmberg Signed-off-by: Hans Holmberg Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Christoph Hellwig --- diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 82952b0d..d5f7d28e 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -471,6 +471,8 @@ static inline int retzero(void) { return 0; } #define xfs_sb_validate_fsb_count(sbp, nblks) (0) #define xlog_calc_iovec_len(len) roundup(len, sizeof(uint32_t)) +#define xfs_zoned_add_available(mp, rtxnum) do { } while (0) + /* * Prototypes for kernel static functions that are aren't in their * associated header files. diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index c40cdf00..3cb47c3c 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -4783,12 +4783,18 @@ xfs_bmap_del_extent_delay( da_diff = da_old - da_new; fdblocks = da_diff; - if (bflags & XFS_BMAPI_REMAP) + if (bflags & XFS_BMAPI_REMAP) { ; - else if (isrt) - xfs_add_frextents(mp, xfs_blen_to_rtbxlen(mp, del->br_blockcount)); - else + } else if (isrt) { + xfs_rtbxlen_t rtxlen; + + rtxlen = xfs_blen_to_rtbxlen(mp, del->br_blockcount); + if (xfs_is_zoned_inode(ip)) + xfs_zoned_add_available(mp, rtxlen); + xfs_add_frextents(mp, rtxlen); + } else { fdblocks += del->br_blockcount; + } xfs_add_fdblocks(mp, fdblocks); xfs_mod_delalloc(ip, -(int64_t)del->br_blockcount, -da_diff); diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h index dc1db15f..f6f4f2d4 100644 --- a/libxfs/xfs_types.h +++ b/libxfs/xfs_types.h @@ -244,12 +244,22 @@ enum xfs_free_counter { */ XC_FREE_RTEXTENTS, + /* + * Number of available for use RT extents. + * + * This counter only exists for zoned RT device and indicates the number + * of RT extents that can be directly used by writes. XC_FREE_RTEXTENTS + * also includes blocks that have been written previously and freed, but + * sit in a rtgroup that still needs a zone reset. + */ + XC_FREE_RTAVAILABLE, XC_FREE_NR, }; #define XFS_FREECOUNTER_STR \ { XC_FREE_BLOCKS, "blocks" }, \ - { XC_FREE_RTEXTENTS, "rtextents" } + { XC_FREE_RTEXTENTS, "rtextents" }, \ + { XC_FREE_RTAVAILABLE, "rtavailable" } /* * Type verifier functions