summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilfred Mallawa <wilfred.mallawa@wdc.com>2026-03-01 03:34:35 +0300
committerCarlos Maiolino <cem@kernel.org>2026-03-04 11:58:24 +0300
commitc6ce65cb17aa9321687d1b8a842487f839e1a548 (patch)
tree6837855520d20dad6e275c39a5149a5524f83067
parent650b774cf94495465d6a38c31bb1a6ce697b6b37 (diff)
downloadlinux-c6ce65cb17aa9321687d1b8a842487f839e1a548.tar.xz
xfs: add write pointer to xfs_rtgroup_geometry
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>
-rw-r--r--fs/xfs/libxfs/xfs_fs.h5
-rw-r--r--fs/xfs/xfs_ioctl.c19
2 files changed, 23 insertions, 1 deletions
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index d165de607d17..185f09f327c0 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -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 */
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index facffdc8dca8..46e234863644 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -37,12 +37,15 @@
#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;