]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfs: add write pointer to xfs_rtgroup_geometry
authorWilfred Mallawa <wilfred.mallawa@wdc.com>
Sun, 1 Mar 2026 00:34:35 +0000 (10:34 +1000)
committerCarlos Maiolino <cem@kernel.org>
Wed, 4 Mar 2026 08:58:24 +0000 (09:58 +0100)
There is currently no XFS ioctl that allows userspace to retrieve the
write pointer for a specific realtime group block for zoned XFS. On zoned
block devices, userspace can obtain this information via zone reports from
the underlying device. However, for zoned XFS operating on regular block
devices, no equivalent mechanism exists.

Access to the realtime group write pointer is useful to userspace
development and analysis tools such as Zonar [1]. So extend the existing
struct xfs_rtgroup_geometry to add a new rg_writepointer field. This field
is valid if XFS_RTGROUP_GEOM_WRITEPOINTER flag is set. The rg_writepointer
field specifies the location of the current writepointer as a block offset
into the respective rtgroup.

[1] https://lwn.net/Articles/1059364/

Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
fs/xfs/libxfs/xfs_fs.h
fs/xfs/xfs_ioctl.c

index d165de607d179ed18e57cd021336af05c08a9cd5..185f09f327c00c33fbb58aee03770107d31cb028 100644 (file)
@@ -995,7 +995,8 @@ struct xfs_rtgroup_geometry {
        __u32 rg_sick;          /* o: sick things in ag */
        __u32 rg_checked;       /* o: checked metadata in ag */
        __u32 rg_flags;         /* i/o: flags for this ag */
-       __u32 rg_reserved[27];  /* o: zero */
+       __u32 rg_writepointer;  /* o: write pointer block offset for zoned */
+       __u32 rg_reserved[26];  /* o: zero */
 };
 #define XFS_RTGROUP_GEOM_SICK_SUPER    (1U << 0)  /* superblock */
 #define XFS_RTGROUP_GEOM_SICK_BITMAP   (1U << 1)  /* rtbitmap */
@@ -1003,6 +1004,8 @@ struct xfs_rtgroup_geometry {
 #define XFS_RTGROUP_GEOM_SICK_RMAPBT   (1U << 3)  /* reverse mappings */
 #define XFS_RTGROUP_GEOM_SICK_REFCNTBT (1U << 4)  /* reference counts */
 
+#define XFS_RTGROUP_GEOM_WRITEPOINTER  (1U << 0)  /* write pointer */
+
 /* Health monitor event domains */
 
 /* affects the whole fs */
index facffdc8dca837bacb48e1304ec90b56054ca787..46e234863644f036a40f970b7cfe722bbf0fbf3e 100644 (file)
 #include "xfs_ioctl.h"
 #include "xfs_xattr.h"
 #include "xfs_rtbitmap.h"
+#include "xfs_rtrmap_btree.h"
 #include "xfs_file.h"
 #include "xfs_exchrange.h"
 #include "xfs_handle.h"
 #include "xfs_rtgroup.h"
 #include "xfs_healthmon.h"
 #include "xfs_verify_media.h"
+#include "xfs_zone_priv.h"
+#include "xfs_zone_alloc.h"
 
 #include <linux/mount.h>
 #include <linux/fileattr.h>
@@ -413,6 +416,7 @@ xfs_ioc_rtgroup_geometry(
 {
        struct xfs_rtgroup      *rtg;
        struct xfs_rtgroup_geometry rgeo;
+       xfs_rgblock_t           highest_rgbno;
        int                     error;
 
        if (copy_from_user(&rgeo, arg, sizeof(rgeo)))
@@ -433,6 +437,21 @@ xfs_ioc_rtgroup_geometry(
        if (error)
                return error;
 
+       if (xfs_has_zoned(mp)) {
+               xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
+               if (rtg->rtg_open_zone) {
+                       rgeo.rg_writepointer = rtg->rtg_open_zone->oz_allocated;
+               } else {
+                       highest_rgbno = xfs_rtrmap_highest_rgbno(rtg);
+                       if (highest_rgbno == NULLRGBLOCK)
+                               rgeo.rg_writepointer = 0;
+                       else
+                               rgeo.rg_writepointer = highest_rgbno + 1;
+               }
+               xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);
+               rgeo.rg_flags |= XFS_RTGROUP_GEOM_WRITEPOINTER;
+       }
+
        if (copy_to_user(arg, &rgeo, sizeof(rgeo)))
                return -EFAULT;
        return 0;