Linux XFS filesystem development
 help / color / mirror / Atom feed
* fix missing RT detection in libxfs v2
@ 2026-09-25  5:12 Christoph Hellwig
  2026-09-25  5:12 ` [PATCH 01/10] libxfs: refactor the reinit case in libxfs_buftarg_init Christoph Hellwig
                   ` (9 more replies)
  0 siblings, 10 replies; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

Hi all,

this series fixes the detection of a missing rtdev specification in
libxfs, and cleans up some lose ends.  Compared to v1 this is a
major rework as the old version broke internal rtdevs, and further
review uncovered a lot of other lingering issues in this part of
libxfs.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 01/10] libxfs: refactor the reinit case in libxfs_buftarg_init
  2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
@ 2026-09-25  5:12 ` Christoph Hellwig
  2026-09-25 22:32   ` Darrick J. Wong
  2026-09-25  5:12 ` [PATCH 02/10] libxfs: split error injection option parsing out of libxfs_buftarg_init Christoph Hellwig
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

I had to wade through this to understand what is going on here.  Factor
the reinit code into a well-name helper and dump the rationale for it
into a comment to make it easier for the next person to understand the
logic.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/init.c | 75 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 45 insertions(+), 30 deletions(-)

diff --git a/libxfs/init.c b/libxfs/init.c
index b89c9fe360d4..63015badc24e 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -487,6 +487,43 @@ static char *wf_opts[] = {
 	[WF_MAX_OPTS]		= NULL,
 };
 
+static void
+libxfs_buftarg_reinit(
+	struct xfs_mount	*mp,
+	struct libxfs_init	*xi)
+{
+	if (mp->m_ddev_targp->bt_bdev != xi->data.dev ||
+	    mp->m_ddev_targp->bt_mount != mp) {
+		fprintf(stderr,
+			_("%s: bad buftarg reinit, ddev\n"),
+			progname);
+		exit(1);
+	}
+
+	if (!xi->log.dev || xi->log.dev == xi->data.dev) {
+		if (mp->m_logdev_targp != mp->m_ddev_targp) {
+			fprintf(stderr,
+			_("%s: bad buftarg reinit, ldev mismatch\n"),
+				progname);
+			exit(1);
+		}
+	} else if (mp->m_logdev_targp->bt_bdev != xi->log.dev ||
+		   mp->m_logdev_targp->bt_mount != mp) {
+		fprintf(stderr,
+			_("%s: bad buftarg reinit, logdev\n"),
+			progname);
+		exit(1);
+	}
+	if ((xi->rt.dev || xi->rt.dev == xi->data.dev) &&
+	    (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
+	     mp->m_rtdev_targp->bt_mount != mp)) {
+		fprintf(stderr,
+			_("%s: bad buftarg reinit, rtdev\n"),
+			progname);
+		exit(1);
+	}
+}
+
 void
 libxfs_buftarg_init(
 	struct xfs_mount	*mp,
@@ -532,37 +569,15 @@ libxfs_buftarg_init(
 		}
 	}
 
+	/*
+	 * This can happen if the utility called libxfs_buftarg_init manually
+	 * before libxfs_mount, which calls us again.
+	 *
+	 * In this case all buftargs should be initialized already, and we just
+	 * ensure the values are sane and match the current mount.
+	 */
 	if (mp->m_ddev_targp) {
-		/* should already have all buftargs initialised */
-		if (mp->m_ddev_targp->bt_bdev != xi->data.dev ||
-		    mp->m_ddev_targp->bt_mount != mp) {
-			fprintf(stderr,
-				_("%s: bad buftarg reinit, ddev\n"),
-				progname);
-			exit(1);
-		}
-		if (!xi->log.dev || xi->log.dev == xi->data.dev) {
-			if (mp->m_logdev_targp != mp->m_ddev_targp) {
-				fprintf(stderr,
-				_("%s: bad buftarg reinit, ldev mismatch\n"),
-					progname);
-				exit(1);
-			}
-		} else if (mp->m_logdev_targp->bt_bdev != xi->log.dev ||
-			   mp->m_logdev_targp->bt_mount != mp) {
-			fprintf(stderr,
-				_("%s: bad buftarg reinit, logdev\n"),
-				progname);
-			exit(1);
-		}
-		if ((xi->rt.dev || xi->rt.dev == xi->data.dev) &&
-		    (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
-		     mp->m_rtdev_targp->bt_mount != mp)) {
-			fprintf(stderr,
-				_("%s: bad buftarg reinit, rtdev\n"),
-				progname);
-			exit(1);
-		}
+		libxfs_buftarg_reinit(mp, xi);
 		return;
 	}
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 02/10] libxfs: split error injection option parsing out of libxfs_buftarg_init
  2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
  2026-09-25  5:12 ` [PATCH 01/10] libxfs: refactor the reinit case in libxfs_buftarg_init Christoph Hellwig
@ 2026-09-25  5:12 ` Christoph Hellwig
  2026-09-25 22:33   ` Darrick J. Wong
  2026-09-25  5:12 ` [PATCH 03/10] libxfs: remove buftarg member aliases Christoph Hellwig
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

Add a separate helper to keep this debug code separate from the main
initialization flow, and only set up the error injection once when
in libxfs_mount, thus skipping it for sb probing.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/init.c | 102 +++++++++++++++++++++++++-------------------------
 1 file changed, 51 insertions(+), 51 deletions(-)

diff --git a/libxfs/init.c b/libxfs/init.c
index 63015badc24e..1b5e1e1e8ba8 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -445,8 +445,7 @@ static struct xfs_buftarg *
 libxfs_buftarg_alloc(
 	struct xfs_mount	*mp,
 	struct libxfs_init	*xi,
-	struct libxfs_dev	*dev,
-	unsigned long		write_fails)
+	struct libxfs_dev	*dev)
 {
 	struct xfs_buftarg	*btp;
 
@@ -461,10 +460,6 @@ libxfs_buftarg_alloc(
 	btp->bt_bdev_fd = dev->fd;
 	btp->bt_xfile = NULL;
 	btp->flags = 0;
-	if (write_fails) {
-		btp->writes_left = write_fails;
-		btp->flags |= XFS_BUFTARG_INJECT_WRITE_FAIL;
-	}
 	pthread_mutex_init(&btp->lock, NULL);
 
 	btp->bcache = cache_init(xi->bcache_flags, libxfs_bhash_size,
@@ -487,6 +482,52 @@ static char *wf_opts[] = {
 	[WF_MAX_OPTS]		= NULL,
 };
 
+static void
+setup_buftarg_write_error(
+	struct xfs_buftarg	*btp,
+	char			*val)
+{
+	if (!val) {
+		fprintf(stderr, _("write fail requires a parameter\n"));
+		exit(1);
+	}
+	if (!btp)
+		return;
+	btp->writes_left = strtoul(val, NULL, 0);
+	if (btp->writes_left)
+		btp->flags |= XFS_BUFTARG_INJECT_WRITE_FAIL;
+}
+
+static void
+libxfs_setup_write_error_injection(
+	struct xfs_mount	*mp)
+{
+	char			*p = getenv("LIBXFS_DEBUG_WRITE_CRASH");
+
+	/* Simulate utility crash after a certain number of writes. */
+	while (p && *p) {
+		char *val;
+
+		switch (getsubopt(&p, wf_opts, &val)) {
+		case WF_DATA:
+			setup_buftarg_write_error(mp->m_ddev_targp, val);
+			break;
+		case WF_LOG:
+			setup_buftarg_write_error(mp->m_logdev_targp, val);
+			break;
+		case WF_RT:
+			if (mp->m_rtdev_targp == mp->m_ddev_targp)
+				break;
+			setup_buftarg_write_error(mp->m_rtdev_targp, val);
+			break;
+		default:
+			fprintf(stderr, _("unknown write fail type %s\n"), val);
+			exit(1);
+			break;
+		}
+	}
+}
+
 static void
 libxfs_buftarg_reinit(
 	struct xfs_mount	*mp,
@@ -529,46 +570,6 @@ libxfs_buftarg_init(
 	struct xfs_mount	*mp,
 	struct libxfs_init	*xi)
 {
-	char			*p = getenv("LIBXFS_DEBUG_WRITE_CRASH");
-	unsigned long		dfail = 0, lfail = 0, rfail = 0;
-
-	/* Simulate utility crash after a certain number of writes. */
-	while (p && *p) {
-		char *val;
-
-		switch (getsubopt(&p, wf_opts, &val)) {
-		case WF_DATA:
-			if (!val) {
-				fprintf(stderr,
-		_("ddev write fail requires a parameter\n"));
-				exit(1);
-			}
-			dfail = strtoul(val, NULL, 0);
-			break;
-		case WF_LOG:
-			if (!val) {
-				fprintf(stderr,
-		_("logdev write fail requires a parameter\n"));
-				exit(1);
-			}
-			lfail = strtoul(val, NULL, 0);
-			break;
-		case WF_RT:
-			if (!val) {
-				fprintf(stderr,
-		_("rtdev write fail requires a parameter\n"));
-				exit(1);
-			}
-			rfail = strtoul(val, NULL, 0);
-			break;
-		default:
-			fprintf(stderr, _("unknown write fail type %s\n"),
-					val);
-			exit(1);
-			break;
-		}
-	}
-
 	/*
 	 * This can happen if the utility called libxfs_buftarg_init manually
 	 * before libxfs_mount, which calls us again.
@@ -581,17 +582,15 @@ libxfs_buftarg_init(
 		return;
 	}
 
-	mp->m_ddev_targp = libxfs_buftarg_alloc(mp, xi, &xi->data, dfail);
+	mp->m_ddev_targp = libxfs_buftarg_alloc(mp, xi, &xi->data);
 	if (!xi->log.dev || xi->log.dev == xi->data.dev)
 		mp->m_logdev_targp = mp->m_ddev_targp;
 	else
-		mp->m_logdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->log,
-				lfail);
+		mp->m_logdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->log);
 	if (!xi->rt.dev || xi->rt.dev == xi->data.dev)
 		mp->m_rtdev_targp = mp->m_ddev_targp;
 	else
-		mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt,
-				rfail);
+		mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt);
 }
 
 /* Compute maximum possible height for per-AG btree types for this fs. */
@@ -740,6 +739,7 @@ libxfs_mount(
 	if (flags & LIBXFS_MOUNT_REPORT_CORRUPTION)
 		xfs_set_reporting_corruption(mp);
 	libxfs_buftarg_init(mp, xi);
+	libxfs_setup_write_error_injection(mp);
 
 	if (xi->data.name)
 		mp->m_fsname = strdup(xi->data.name);
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 03/10] libxfs: remove buftarg member aliases
  2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
  2026-09-25  5:12 ` [PATCH 01/10] libxfs: refactor the reinit case in libxfs_buftarg_init Christoph Hellwig
  2026-09-25  5:12 ` [PATCH 02/10] libxfs: split error injection option parsing out of libxfs_buftarg_init Christoph Hellwig
@ 2026-09-25  5:12 ` Christoph Hellwig
  2026-09-25  5:12 ` [PATCH 04/10] libxfs: unify buftarg handling with the kernel Christoph Hellwig
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

Remove the #defines giving historic IRIX names to the ddev/logdev/rtdev
buftargs in struct xfs_mount and use the current kernel names everywhere.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
---
 libxfs/init.c            | 12 ++++++------
 libxfs/stubs/xfs_mount.h |  3 ---
 libxfs/trans.c           |  4 ++--
 libxfs/util.c            |  2 +-
 mkfs/xfs_mkfs.c          |  4 ++--
 repair/attr_repair.c     | 11 ++++++-----
 repair/da_util.c         |  2 +-
 repair/dino_chunks.c     |  8 ++++----
 repair/dinode.c          |  8 ++++----
 repair/phase3.c          |  2 +-
 repair/phase5.c          |  6 +++---
 repair/prefetch.c        |  4 ++--
 repair/quotacheck.c      |  2 +-
 repair/rt.c              |  2 +-
 repair/scan.c            | 16 +++++++++-------
 15 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/libxfs/init.c b/libxfs/init.c
index 1b5e1e1e8ba8..1613ce2d14a3 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -330,7 +330,7 @@ rtmount_init(
 			(unsigned long long) mp->m_sb.sb_rblocks);
 		return -1;
 	}
-	error = libxfs_buf_read(mp->m_rtdev, d - XFS_FSB_TO_BB(mp, 1),
+	error = libxfs_buf_read(mp->m_rtdev_targp, d - XFS_FSB_TO_BB(mp, 1),
 			XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
 	if (error) {
 		fprintf(stderr, _("%s: realtime size check failed\n"),
@@ -687,7 +687,7 @@ check_many_rtgroups(
 	xfs_daddr_t		d;
 	int			error;
 
-	if (!mp->m_rtdev->bt_bdev) {
+	if (!mp->m_rtdev_targp->bt_bdev) {
 		fprintf(stderr, _("%s: no rt device, ignoring rgcount %u\n"),
 				progname, sbp->sb_rgcount);
 		if (!xfs_is_debugger(mp))
@@ -698,8 +698,8 @@ check_many_rtgroups(
 	}
 
 	d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_rblocks);
-	error = libxfs_buf_read(mp->m_rtdev, d - XFS_FSB_TO_BB(mp, 1), 1, 0,
-			&bp, NULL);
+	error = libxfs_buf_read(mp->m_rtdev_targp, d - XFS_FSB_TO_BB(mp, 1), 1,
+			0, &bp, NULL);
 	if (!error) {
 		libxfs_buf_relse(bp);
 		return true;
@@ -815,7 +815,7 @@ libxfs_mount(
 		return mp;
 
 	/* device size checks must pass unless we're a debugger. */
-	error = libxfs_buf_read(mp->m_dev, d - XFS_FSS_TO_BB(mp, 1),
+	error = libxfs_buf_read(mp->m_ddev_targp, d - XFS_FSS_TO_BB(mp, 1),
 			XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL);
 	if (error) {
 		fprintf(stderr, _("%s: data size check failed\n"), progname);
@@ -857,7 +857,7 @@ libxfs_mount(
 	 * read the first one and let the user know to check the geometry.
 	 */
 	if (sbp->sb_agcount > 1000000) {
-		error = libxfs_buf_read(mp->m_dev,
+		error = libxfs_buf_read(mp->m_ddev_targp,
 				XFS_AG_DADDR(mp, sbp->sb_agcount - 1, 0), 1,
 				0, &bp, NULL);
 		if (error) {
diff --git a/libxfs/stubs/xfs_mount.h b/libxfs/stubs/xfs_mount.h
index 5a714333c16e..0dea578ee3a5 100644
--- a/libxfs/stubs/xfs_mount.h
+++ b/libxfs/stubs/xfs_mount.h
@@ -102,9 +102,6 @@ typedef struct xfs_mount {
 	struct xfs_buftarg	*m_ddev_targp;
 	struct xfs_buftarg	*m_logdev_targp;
 	struct xfs_buftarg	*m_rtdev_targp;
-#define m_dev		m_ddev_targp
-#define m_logdev	m_logdev_targp
-#define m_rtdev		m_rtdev_targp
 	uint8_t			m_dircook_elog;	/* log d-cookie entry bits */
 	uint8_t			m_blkbit_log;	/* blocklog + NBBY */
 	uint8_t			m_blkbb_log;	/* blocklog - BBSHIFT */
diff --git a/libxfs/trans.c b/libxfs/trans.c
index c89b035ffeaf..88022c2fc9c2 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -500,7 +500,7 @@ libxfs_trans_getsb(
 	if (tp == NULL)
 		return libxfs_getsb(mp);
 
-	bp = xfs_trans_buf_item_match(tp, mp->m_dev, &map, 1);
+	bp = xfs_trans_buf_item_match(tp, mp->m_ddev_targp, &map, 1);
 	if (bp != NULL) {
 		ASSERT(bp->b_transp == tp);
 		bip = bp->b_log_item;
@@ -529,7 +529,7 @@ libxfs_trans_getrtsb(
 	int			len = XFS_FSS_TO_BB(mp, 1);
 	DEFINE_SINGLE_BUF_MAP(map, XFS_SB_DADDR, len);
 
-	bp = xfs_trans_buf_item_match(tp, mp->m_rtdev, &map, 1);
+	bp = xfs_trans_buf_item_match(tp, mp->m_rtdev_targp, &map, 1);
 	if (bp != NULL) {
 		ASSERT(bp->b_transp == tp);
 		bip = bp->b_log_item;
diff --git a/libxfs/util.c b/libxfs/util.c
index 6cbbe9056eba..fae8fce484b7 100644
--- a/libxfs/util.c
+++ b/libxfs/util.c
@@ -527,7 +527,7 @@ libxfs_file_write(
 		    map.br_state == XFS_EXT_UNWRITTEN)
 			return -EINVAL;
 
-		error = libxfs_buf_get(mp->m_dev,
+		error = libxfs_buf_get(mp->m_ddev_targp,
 				XFS_FSB_TO_DADDR(mp, map.br_startblock),
 				XFS_FSB_TO_BB(mp, map.br_blockcount),
 				&bp);
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 334367b81555..3ce49a36eaa8 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -5723,7 +5723,7 @@ rewrite_secondary_superblocks(
 	int			error;
 
 	/* rewrite the last superblock */
-	error = -libxfs_buf_read(mp->m_dev,
+	error = -libxfs_buf_read(mp->m_ddev_targp,
 			XFS_AGB_TO_DADDR(mp, mp->m_sb.sb_agcount - 1,
 				XFS_SB_DADDR),
 			XFS_FSS_TO_BB(mp, 1), 0, &buf, &xfs_sb_buf_ops);
@@ -5743,7 +5743,7 @@ rewrite_secondary_superblocks(
 	if (mp->m_sb.sb_agcount <= 2)
 		return;
 
-	error = -libxfs_buf_read(mp->m_dev,
+	error = -libxfs_buf_read(mp->m_ddev_targp,
 			XFS_AGB_TO_DADDR(mp, (mp->m_sb.sb_agcount - 1) / 2,
 				XFS_SB_DADDR),
 			XFS_FSS_TO_BB(mp, 1), 0, &buf, &xfs_sb_buf_ops);
diff --git a/repair/attr_repair.c b/repair/attr_repair.c
index fe4089026cae..982dc838ee55 100644
--- a/repair/attr_repair.c
+++ b/repair/attr_repair.c
@@ -443,9 +443,10 @@ rmtval_get(xfs_mount_t *mp, xfs_ino_t ino, blkmap_t *blkmap,
 			clearit = 1;
 			break;
 		}
-		error = -libxfs_buf_read(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
-				XFS_FSB_TO_BB(mp, 1), LIBXFS_READBUF_SALVAGE,
-				&bp, &xfs_attr3_rmt_buf_ops);
+		error = -libxfs_buf_read(mp->m_ddev_targp,
+				XFS_FSB_TO_DADDR(mp, bno), XFS_FSB_TO_BB(mp, 1),
+				LIBXFS_READBUF_SALVAGE, &bp,
+				&xfs_attr3_rmt_buf_ops);
 		if (error) {
 			do_warn(
 	_("can't read remote block for attributes of inode %" PRIu64 "\n"), ino);
@@ -879,7 +880,7 @@ process_leaf_attr_level(xfs_mount_t	*mp,
 			goto error_out;
 		}
 
-		error = -libxfs_buf_read(mp->m_dev,
+		error = -libxfs_buf_read(mp->m_ddev_targp,
 				XFS_FSB_TO_DADDR(mp, dev_bno),
 				XFS_FSB_TO_BB(mp, 1), LIBXFS_READBUF_SALVAGE,
 				&bp, &xfs_attr3_leaf_buf_ops);
@@ -1217,7 +1218,7 @@ process_longform_attr(
 		return 1;
 	}
 
-	error = -libxfs_buf_read(mp->m_dev, XFS_FSB_TO_DADDR(mp, bno),
+	error = -libxfs_buf_read(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, bno),
 			XFS_FSB_TO_BB(mp, 1), LIBXFS_READBUF_SALVAGE, &bp,
 			&xfs_da3_node_buf_ops);
 	if (error) {
diff --git a/repair/da_util.c b/repair/da_util.c
index 7f94f4012062..c0625b312fc6 100644
--- a/repair/da_util.c
+++ b/repair/da_util.c
@@ -64,7 +64,7 @@ da_read_buf(
 		map[i].bm_bn = XFS_FSB_TO_DADDR(mp, bmp[i].startblock);
 		map[i].bm_len = XFS_FSB_TO_BB(mp, bmp[i].blockcount);
 	}
-	libxfs_buf_read_map(mp->m_dev, map, nex, LIBXFS_READBUF_SALVAGE,
+	libxfs_buf_read_map(mp->m_ddev_targp, map, nex, LIBXFS_READBUF_SALVAGE,
 			&bp, ops);
 	if (map != map_array)
 		free(map);
diff --git a/repair/dino_chunks.c b/repair/dino_chunks.c
index 932eaf63f474..6b261a1e99bf 100644
--- a/repair/dino_chunks.c
+++ b/repair/dino_chunks.c
@@ -43,9 +43,9 @@ check_aginode_block(
 	 * tree and we wouldn't be here and we stale the buffers out
 	 * so no one else will overlap them.
 	 */
-	error = -libxfs_buf_read(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, agbno),
-			XFS_FSB_TO_BB(mp, 1), LIBXFS_READBUF_SALVAGE, &bp,
-			NULL);
+	error = -libxfs_buf_read(mp->m_ddev_targp,
+			XFS_AGB_TO_DADDR(mp, agno, agbno), XFS_FSB_TO_BB(mp, 1),
+			LIBXFS_READBUF_SALVAGE, &bp, NULL);
 	if (error) {
 		do_warn(_("cannot read agbno (%u/%u), disk block %" PRId64 "\n"),
 			agno, agbno, XFS_AGB_TO_DADDR(mp, agno, agbno));
@@ -699,7 +699,7 @@ process_inode_chunk(
 		pftrace("about to read off %llu in AG %d",
 			XFS_AGB_TO_DADDR(mp, agno, agbno), agno);
 
-		error = -libxfs_buf_read(mp->m_dev,
+		error = -libxfs_buf_read(mp->m_ddev_targp,
 				XFS_AGB_TO_DADDR(mp, agno, agbno),
 				XFS_FSB_TO_BB(mp,
 					M_IGEO(mp)->blocks_per_cluster),
diff --git a/repair/dinode.c b/repair/dinode.c
index 48939f8bd159..243fcf7a19f4 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -956,8 +956,8 @@ get_agino_buf(
 		cluster_agino, cluster_daddr, cluster_blks);
 #endif
 
-	error = -libxfs_buf_read(mp->m_dev, cluster_daddr, cluster_blks, 0,
-			&bp, &xfs_inode_buf_ops);
+	error = -libxfs_buf_read(mp->m_ddev_targp, cluster_daddr, cluster_blks,
+			0, &bp, &xfs_inode_buf_ops);
 	if (error) {
 		do_warn(_("cannot read inode (%u/%u), disk block %" PRIu64 "\n"),
 			agno, cluster_agino, cluster_daddr);
@@ -1733,7 +1733,7 @@ process_quota_inode(
 		fsbno = blkmap_get(blkmap, qbno);
 		dqid = (xfs_dqid_t)qbno * dqperchunk;
 
-		error = -libxfs_buf_read(mp->m_dev,
+		error = -libxfs_buf_read(mp->m_ddev_targp,
 				XFS_FSB_TO_DADDR(mp, fsbno), dqchunklen,
 				LIBXFS_READBUF_SALVAGE, &bp,
 				&xfs_dquot_buf_ops);
@@ -1845,7 +1845,7 @@ _("cannot read inode %" PRIu64 ", file block %d, NULL disk block\n"),
 
 		byte_cnt = XFS_FSB_TO_B(mp, blk_cnt);
 
-		error = -libxfs_buf_read(mp->m_dev,
+		error = -libxfs_buf_read(mp->m_ddev_targp,
 				XFS_FSB_TO_DADDR(mp, fsbno), BTOBB(byte_cnt),
 				LIBXFS_READBUF_SALVAGE, &bp,
 				&xfs_symlink_buf_ops);
diff --git a/repair/phase3.c b/repair/phase3.c
index 6ec616d9b31d..64a2c961b080 100644
--- a/repair/phase3.c
+++ b/repair/phase3.c
@@ -30,7 +30,7 @@ process_agi_unlinked(
 	int			agi_dirty = 0;
 	int			error;
 
-	error = -libxfs_buf_read(mp->m_dev,
+	error = -libxfs_buf_read(mp->m_ddev_targp,
 			XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
 			mp->m_sb.sb_sectsize / BBSIZE, LIBXFS_READBUF_SALVAGE,
 			&bp, &xfs_agi_buf_ops);
diff --git a/repair/phase5.c b/repair/phase5.c
index e44c26885717..019772346eb1 100644
--- a/repair/phase5.c
+++ b/repair/phase5.c
@@ -135,7 +135,7 @@ build_agi(
 	int			i;
 	int			error;
 
-	error = -libxfs_buf_get(mp->m_dev,
+	error = -libxfs_buf_get(mp->m_ddev_targp,
 			XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
 			mp->m_sb.sb_sectsize / BBSIZE, &agi_buf);
 	if (error)
@@ -228,7 +228,7 @@ build_agf_agfl(
 	__be32			*freelist;
 	int			error;
 
-	error = -libxfs_buf_get(mp->m_dev,
+	error = -libxfs_buf_get(mp->m_ddev_targp,
 			XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
 			mp->m_sb.sb_sectsize / BBSIZE, &agf_buf);
 	if (error)
@@ -314,7 +314,7 @@ build_agf_agfl(
 		platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);
 
 	/* initialise the AGFL, then fill it if there are blocks left over. */
-	error = -libxfs_buf_get(mp->m_dev,
+	error = -libxfs_buf_get(mp->m_ddev_targp,
 			XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
 			mp->m_sb.sb_sectsize / BBSIZE, &agfl_buf);
 	if (error)
diff --git a/repair/prefetch.c b/repair/prefetch.c
index 8cd3416fa568..3d26636e5e56 100644
--- a/repair/prefetch.c
+++ b/repair/prefetch.c
@@ -121,7 +121,7 @@ pf_queue_io(
 	 * the lock holder is either reading it from disk himself or
 	 * completely overwriting it this behaviour is perfectly fine.
 	 */
-	error = -libxfs_buf_get_map(mp->m_dev, map, nmaps,
+	error = -libxfs_buf_get_map(mp->m_ddev_targp, map, nmaps,
 			LIBXFS_GETBUF_TRYLOCK, &bp);
 	if (error)
 		return;
@@ -275,7 +275,7 @@ pf_scan_lbtree(
 	int			rc;
 	int			error;
 
-	error = -libxfs_buf_read(mp->m_dev, XFS_FSB_TO_DADDR(mp, dbno),
+	error = -libxfs_buf_read(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, dbno),
 			XFS_FSB_TO_BB(mp, 1), LIBXFS_READBUF_SALVAGE, &bp,
 			&xfs_bmbt_buf_ops);
 	if (error)
diff --git a/repair/quotacheck.c b/repair/quotacheck.c
index fc7e3864654c..e13092dfcae8 100644
--- a/repair/quotacheck.c
+++ b/repair/quotacheck.c
@@ -369,7 +369,7 @@ qc_walk_dquot_extent(
 		unsigned int	dqnr;
 		uint64_t	dqid;
 
-		error = -libxfs_buf_read(mp->m_dev,
+		error = -libxfs_buf_read(mp->m_ddev_targp,
 				XFS_FSB_TO_DADDR(mp, map->br_startblock + bno),
 				dqchunklen, 0, &bp, &xfs_dquot_buf_ops);
 		if (error) {
diff --git a/repair/rt.c b/repair/rt.c
index 3e51c9b5eb4b..b5b9d4fdc536 100644
--- a/repair/rt.c
+++ b/repair/rt.c
@@ -255,7 +255,7 @@ check_rtfile_contents(
 			break;
 		}
 
-		error = -libxfs_buf_read_uncached(mp->m_dev,
+		error = -libxfs_buf_read_uncached(mp->m_ddev_targp,
 				XFS_FSB_TO_DADDR(mp, map.br_startblock),
 				XFS_FSB_TO_BB(mp, 1), 0, &bp,
 				xfs_rtblock_ops(mp, type));
diff --git a/repair/scan.c b/repair/scan.c
index 7d22ff378484..865983d6c9e0 100644
--- a/repair/scan.c
+++ b/repair/scan.c
@@ -102,8 +102,9 @@ scan_sbtree(
 	struct xfs_buf	*bp;
 	int		error;
 
-	error = salvage_buffer(mp->m_dev, XFS_AGB_TO_DADDR(mp, agno, root),
-			XFS_FSB_TO_BB(mp, 1), &bp, ops);
+	error = salvage_buffer(mp->m_ddev_targp,
+			XFS_AGB_TO_DADDR(mp, agno, root),XFS_FSB_TO_BB(mp, 1),
+			&bp, ops);
 	if (error) {
 		do_error(_("can't read btree block %d/%d\n"), agno, root);
 		return;
@@ -161,7 +162,7 @@ scan_lbtree(
 	int		dirty = 0;
 	bool		badcrc = false;
 
-	err = salvage_buffer(mp->m_dev, XFS_FSB_TO_DADDR(mp, root),
+	err = salvage_buffer(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, root),
 			XFS_FSB_TO_BB(mp, 1), &bp, ops);
 	if (err) {
 		do_error(_("can't read btree block %d/%d\n"),
@@ -3030,7 +3031,7 @@ scan_freelist(
 	if (be32_to_cpu(agf->agf_flcount) == 0)
 		return;
 
-	error = salvage_buffer(mp->m_dev,
+	error = salvage_buffer(mp->m_ddev_targp,
 			XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
 			XFS_FSS_TO_BB(mp, 1), &agflbuf, &xfs_agfl_buf_ops);
 	if (error) {
@@ -3312,7 +3313,8 @@ scan_ag(
 		return;
 	}
 
-	error = salvage_buffer(mp->m_dev, XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
+	error = salvage_buffer(mp->m_ddev_targp,
+			XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
 			XFS_FSS_TO_BB(mp, 1), &sbbuf, &xfs_sb_buf_ops);
 	if (error) {
 		objname = _("root superblock");
@@ -3322,7 +3324,7 @@ scan_ag(
 		do_warn(_("superblock has bad CRC for ag %d\n"), agno);
 	libxfs_sb_from_disk(sb, sbbuf->b_addr);
 
-	error = salvage_buffer(mp->m_dev,
+	error = salvage_buffer(mp->m_ddev_targp,
 			XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
 			XFS_FSS_TO_BB(mp, 1), &agfbuf, &xfs_agf_buf_ops);
 	if (error) {
@@ -3333,7 +3335,7 @@ scan_ag(
 		do_warn(_("agf has bad CRC for ag %d\n"), agno);
 	agf = agfbuf->b_addr;
 
-	error = salvage_buffer(mp->m_dev,
+	error = salvage_buffer(mp->m_ddev_targp,
 			XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
 			XFS_FSS_TO_BB(mp, 1), &agibuf, &xfs_agi_buf_ops);
 	if (error) {
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 04/10] libxfs: unify buftarg handling with the kernel
  2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2026-09-25  5:12 ` [PATCH 03/10] libxfs: remove buftarg member aliases Christoph Hellwig
@ 2026-09-25  5:12 ` Christoph Hellwig
  2026-09-25 22:37   ` Darrick J. Wong
  2026-09-25  5:12 ` [PATCH 05/10] libxfs: make the size check in rtmount_init internal RT device aware Christoph Hellwig
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

In the kernel, the RT buftarg is set to NULL when not realtime device is
present, but libxfs still allocates one, and all users instead check for
a NULL ->bt_bdev.

Switch to the kernel model of never allocating the buftarg, and check
mp->m_rtdev_targp for NULL instead of just ->bt_bdev.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 db/io.c         |  4 ++--
 db/metadump.c   |  7 +++----
 libxfs/init.c   | 40 +++++++++++++++++++---------------------
 libxfs/rdwr.c   | 25 ++++++++++++++++---------
 mkfs/xfs_mkfs.c |  6 ++----
 5 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/db/io.c b/db/io.c
index fc9a25d41024..6aafe5bd8a15 100644
--- a/db/io.c
+++ b/db/io.c
@@ -651,7 +651,7 @@ set_log_cur(
 	int		ring_flag,
 	bbmap_t		*bbmap)
 {
-	if (mp->m_logdev_targp->bt_bdev == mp->m_ddev_targp->bt_bdev) {
+	if (mp->m_logdev_targp == mp->m_ddev_targp) {
 		fprintf(stderr, "no external log specified\n");
 		exitcode = 1;
 		return;
@@ -668,7 +668,7 @@ set_rt_cur(
 	int		ring_flag,
 	bbmap_t		*bbmap)
 {
-	if (!mp->m_rtdev_targp->bt_bdev) {
+	if (!mp->m_rtdev_targp) {
 		printf(_("realtime device not loaded, use -R.\n"));
 		return ENODEV;
 	}
diff --git a/db/metadump.c b/db/metadump.c
index 39639a0d51b0..6c12a5270fea 100644
--- a/db/metadump.c
+++ b/db/metadump.c
@@ -3344,8 +3344,7 @@ write_metadump_v2(
 	uint64_t		addr;
 
 	addr = off;
-	if (type == TYP_LOG &&
-	    mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
+	if (type == TYP_LOG && mp->m_logdev_targp != mp->m_ddev_targp)
 		addr |= XME_ADDR_LOG_DEVICE;
 	else if (type == TYP_RTSB)
 		addr |= XME_ADDR_RT_DEVICE;
@@ -3464,7 +3463,7 @@ metadump_f(
 		return 0;
 	}
 
-	if (mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
+	if (mp->m_logdev_targp != mp->m_ddev_targp)
 		metadump.external_log = true;
 
 	if (metadump.external_log && !version_opt_set)
@@ -3481,7 +3480,7 @@ metadump_f(
 	 * enabled.
 	 */
 	if (xfs_has_realtime(mp) && xfs_has_rtsb(mp)) {
-		if (mp->m_rtdev_targp->bt_bdev) {
+		if (mp->m_rtdev_targp) {
 			metadump.realtime_data = true;
 			if (!version_opt_set)
 				metadump.version = 2;
diff --git a/libxfs/init.c b/libxfs/init.c
index 1613ce2d14a3..65dadb1a23f7 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -307,7 +307,7 @@ rtmount_init(
 		return -1;
 	}
 
-	if (mp->m_rtdev_targp->bt_bdev == 0 && !xfs_is_debugger(mp)) {
+	if (!mp->m_rtdev_targp && !xfs_is_debugger(mp)) {
 		fprintf(stderr, _("%s: filesystem has a realtime subvolume\n"),
 			progname);
 		return -1;
@@ -541,27 +541,26 @@ libxfs_buftarg_reinit(
 		exit(1);
 	}
 
-	if (!xi->log.dev || xi->log.dev == xi->data.dev) {
-		if (mp->m_logdev_targp != mp->m_ddev_targp) {
+	if (mp->m_logdev_targp != mp->m_ddev_targp) {
+		if ((xi->log.dev && xi->log.dev == xi->data.dev) ||
+		    mp->m_logdev_targp->bt_bdev != xi->log.dev ||
+		    mp->m_logdev_targp->bt_mount != mp) {
 			fprintf(stderr,
-			_("%s: bad buftarg reinit, ldev mismatch\n"),
+				_("%s: bad buftarg reinit, logdev\n"),
 				progname);
 			exit(1);
 		}
-	} else if (mp->m_logdev_targp->bt_bdev != xi->log.dev ||
-		   mp->m_logdev_targp->bt_mount != mp) {
-		fprintf(stderr,
-			_("%s: bad buftarg reinit, logdev\n"),
-			progname);
-		exit(1);
 	}
-	if ((xi->rt.dev || xi->rt.dev == xi->data.dev) &&
-	    (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
-	     mp->m_rtdev_targp->bt_mount != mp)) {
-		fprintf(stderr,
-			_("%s: bad buftarg reinit, rtdev\n"),
-			progname);
-		exit(1);
+
+	if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp) {
+		if ((xi->rt.dev && xi->rt.dev == xi->data.dev) ||
+		    mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
+		    mp->m_rtdev_targp->bt_mount != mp) {
+			fprintf(stderr,
+				_("%s: bad buftarg reinit, rtdev\n"),
+				progname);
+			exit(1);
+		}
 	}
 }
 
@@ -687,7 +686,7 @@ check_many_rtgroups(
 	xfs_daddr_t		d;
 	int			error;
 
-	if (!mp->m_rtdev_targp->bt_bdev) {
+	if (!mp->m_rtdev_targp) {
 		fprintf(stderr, _("%s: no rt device, ignoring rgcount %u\n"),
 				progname, sbp->sb_rgcount);
 		if (!xfs_is_debugger(mp))
@@ -824,8 +823,7 @@ libxfs_mount(
 	} else
 		libxfs_buf_relse(bp);
 
-	if (mp->m_logdev_targp->bt_bdev &&
-	    mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev) {
+	if (mp->m_logdev_targp != mp->m_ddev_targp) {
 		d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
 		if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks ||
 		    libxfs_buf_read(mp->m_logdev_targp,
@@ -1045,7 +1043,7 @@ libxfs_umount(
 	free(mp->m_fsname);
 	mp->m_fsname = NULL;
 
-	if (mp->m_rtdev_targp != mp->m_ddev_targp)
+	if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp)
 		libxfs_buftarg_free(mp->m_rtdev_targp);
 	if (mp->m_logdev_targp != mp->m_ddev_targp)
 		libxfs_buftarg_free(mp->m_logdev_targp);
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 90f2d56687ca..14cfec7a2859 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -171,7 +171,7 @@ libxfs_getrtsb(
 	struct xfs_buf		*bp;
 	int			error;
 
-	if (!mp->m_rtdev_targp->bt_bdev)
+	if (!mp->m_rtdev_targp)
 		return NULL;
 
 	ASSERT(!mp->m_sb.sb_rtstart);
@@ -1028,7 +1028,8 @@ libxfs_bcache_purge(struct xfs_mount *mp)
 		return;
 	cache_purge(mp->m_ddev_targp->bcache);
 	cache_purge(mp->m_logdev_targp->bcache);
-	cache_purge(mp->m_rtdev_targp->bcache);
+	if (mp->m_rtdev_targp)
+		cache_purge(mp->m_rtdev_targp->bcache);
 }
 
 void
@@ -1038,7 +1039,8 @@ libxfs_bcache_flush(struct xfs_mount *mp)
 		return;
 	cache_flush(mp->m_ddev_targp->bcache);
 	cache_flush(mp->m_logdev_targp->bcache);
-	cache_flush(mp->m_rtdev_targp->bcache);
+	if (mp->m_rtdev_targp)
+		cache_flush(mp->m_rtdev_targp->bcache);
 }
 
 int
@@ -1046,7 +1048,8 @@ libxfs_bcache_overflowed(struct xfs_mount *mp)
 {
 	return cache_overflowed(mp->m_ddev_targp->bcache) ||
 		cache_overflowed(mp->m_logdev_targp->bcache) ||
-		cache_overflowed(mp->m_rtdev_targp->bcache);
+		(mp->m_rtdev_targp &&
+		 cache_overflowed(mp->m_rtdev_targp->bcache));
 }
 
 struct cache_operations libxfs_bcache_operations = {
@@ -1185,15 +1188,19 @@ libxfs_log_clear(
 	xfs_daddr_t		end_blk;
 	char			*ptr;
 
-	if (((btp && dptr) || (!btp && !dptr)) ||
-	    (btp && !btp->bt_bdev) || !fs_uuid)
+	if (!fs_uuid)
 		return -EINVAL;
 
-	/* first zero the log */
-	if (btp)
+	if (btp) {
+		if (dptr)
+			return -EINVAL;
+		/* first zero the log */
 		libxfs_device_zero(btp, start, length);
-	else
+	} else {
+		if (!dptr)
+			return -EINVAL;
 		memset(dptr, 0, BBTOB(length));
+	}
 
 	/*
 	 * Initialize the log record length and LSNs. XLOG_INIT_CYCLE is a
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 3ce49a36eaa8..6eca76f0c3c9 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -5632,10 +5632,8 @@ prepare_devices(
 			 &sbp->sb_uuid, cfg->sb_feat.log_version,
 			 lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
 	/* finally, check we can write the last block in the realtime area */
-	if (mp->m_rtdev_targp->bt_bdev &&
-	    mp->m_rtdev_targp != mp->m_ddev_targp &&
-	    cfg->rtblocks > 0 &&
-	    !xfs_has_zoned(mp)) {
+	if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp &&
+	    cfg->rtblocks > 0 && !xfs_has_zoned(mp)) {
 		buf = alloc_write_buf(mp->m_rtdev_targp,
 				XFS_FSB_TO_BB(mp, cfg->rtblocks - 1LL),
 				BTOBB(cfg->blocksize));
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/10] libxfs: make the size check in rtmount_init internal RT device aware
  2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2026-09-25  5:12 ` [PATCH 04/10] libxfs: unify buftarg handling with the kernel Christoph Hellwig
@ 2026-09-25  5:12 ` Christoph Hellwig
  2026-09-25 22:38   ` Darrick J. Wong
  2026-09-25  5:12 ` [PATCH 06/10] libxfs: don't clear ->dev in libxfs_device_close Christoph Hellwig
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

Add rtstart handling.  This is currently masked by broken setup of
the rtdev targp to the ddev one for internal devices.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/init.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libxfs/init.c b/libxfs/init.c
index 65dadb1a23f7..85e0b3402bb2 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -330,7 +330,9 @@ rtmount_init(
 			(unsigned long long) mp->m_sb.sb_rblocks);
 		return -1;
 	}
-	error = libxfs_buf_read(mp->m_rtdev_targp, d - XFS_FSB_TO_BB(mp, 1),
+	error = libxfs_buf_read(mp->m_rtdev_targp,
+			XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart) +
+				d - XFS_FSB_TO_BB(mp, 1),
 			XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
 	if (error) {
 		fprintf(stderr, _("%s: realtime size check failed\n"),
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/10] libxfs: don't clear ->dev in libxfs_device_close
  2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2026-09-25  5:12 ` [PATCH 05/10] libxfs: make the size check in rtmount_init internal RT device aware Christoph Hellwig
@ 2026-09-25  5:12 ` Christoph Hellwig
  2026-09-25 22:39   ` Darrick J. Wong
  2026-09-25  5:12 ` [PATCH 07/10] libxfs: fix buftarg initialization for the RT device Christoph Hellwig
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

struct libxfs_init can't be reused for multiple mounts, so there is no
point in clearing it.  And clearing it defeats the duplicate device
check in libxfs_close_devices, which would lead to flushing a closed
device if this wasn't current masked by another bug.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/init.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libxfs/init.c b/libxfs/init.c
index 85e0b3402bb2..842a2e1e09a9 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -182,7 +182,6 @@ libxfs_device_close(
 	close(dev->fd);
 
 	dev->fd = -1;
-	dev->dev = 0;
 }
 
 /*
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 07/10] libxfs: fix buftarg initialization for the RT device
  2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2026-09-25  5:12 ` [PATCH 06/10] libxfs: don't clear ->dev in libxfs_device_close Christoph Hellwig
@ 2026-09-25  5:12 ` Christoph Hellwig
  2026-09-25 22:42   ` Darrick J. Wong
  2026-09-25  5:12 ` [PATCH 08/10] libxfs: rename bt_bdev* Christoph Hellwig
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

libxfs_buftarg_init currently sets the rtdev targp to the ddev one when
no explicit RT device is provided, which allows tools like repair to
proceed without a specified RT device when they should not, and
potentially can cause data corruption.

Fix this by delaying the RT buftarg initialization to libxfs_mount,
where we can check if the superblock indicates an internal RT device.
This works because all external callers of libxfs_buftarg_init never
need the RT device as they just examine the sb and/or log,

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/init.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/libxfs/init.c b/libxfs/init.c
index 842a2e1e09a9..97c5286c00a9 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -554,8 +554,7 @@ libxfs_buftarg_reinit(
 	}
 
 	if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp) {
-		if ((xi->rt.dev && xi->rt.dev == xi->data.dev) ||
-		    mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
+		if (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
 		    mp->m_rtdev_targp->bt_mount != mp) {
 			fprintf(stderr,
 				_("%s: bad buftarg reinit, rtdev\n"),
@@ -587,10 +586,6 @@ libxfs_buftarg_init(
 		mp->m_logdev_targp = mp->m_ddev_targp;
 	else
 		mp->m_logdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->log);
-	if (!xi->rt.dev || xi->rt.dev == xi->data.dev)
-		mp->m_rtdev_targp = mp->m_ddev_targp;
-	else
-		mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt);
 }
 
 /* Compute maximum possible height for per-AG btree types for this fs. */
@@ -739,6 +734,10 @@ libxfs_mount(
 	if (flags & LIBXFS_MOUNT_REPORT_CORRUPTION)
 		xfs_set_reporting_corruption(mp);
 	libxfs_buftarg_init(mp, xi);
+	if (sb->sb_rtstart)
+		mp->m_rtdev_targp = mp->m_ddev_targp;
+	else if (xi->rt.dev)
+		mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt);
 	libxfs_setup_write_error_injection(mp);
 
 	if (xi->data.name)
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/10] libxfs: rename bt_bdev*
  2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
                   ` (6 preceding siblings ...)
  2026-09-25  5:12 ` [PATCH 07/10] libxfs: fix buftarg initialization for the RT device Christoph Hellwig
@ 2026-09-25  5:12 ` Christoph Hellwig
  2026-09-25 22:43   ` Darrick J. Wong
  2026-09-25  5:12 ` [PATCH 09/10] libfrog: improve ramdisk handling in platform_flush_device Christoph Hellwig
  2026-09-25  5:12 ` [PATCH 10/10] xfs_db: remove a double-whitespace in rdump_regfile_data Christoph Hellwig
  9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

Unlike the kernel, there is no block device concept in libxfs.

Rename the bt_bdev field to bt_dev as it stores a dev_t, and bt_bdev_fd
to just bt_fd to make the naming a bit less confusing.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 libxfs/buf_mem.c   |  4 ++--
 libxfs/init.c      | 10 +++++-----
 libxfs/libxfs_io.h |  4 ++--
 libxfs/rdwr.c      | 12 ++++++------
 repair/prefetch.c  |  2 +-
 repair/zoned.c     |  2 +-
 6 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/libxfs/buf_mem.c b/libxfs/buf_mem.c
index 3c8452de9689..f3db59dfc63e 100644
--- a/libxfs/buf_mem.c
+++ b/libxfs/buf_mem.c
@@ -294,8 +294,8 @@ xmbuf_alloc(
 
 	/* Initialize buffer target */
 	btp->bt_mount = mp;
-	btp->bt_bdev = (dev_t)-1;
-	btp->bt_bdev_fd = -1;
+	btp->bt_dev = (dev_t)-1;
+	btp->bt_fd = -1;
 	btp->bt_xfile = xfile;
 	btp->bcache = cache;
 
diff --git a/libxfs/init.c b/libxfs/init.c
index 97c5286c00a9..5a4b255165ab 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -457,8 +457,8 @@ libxfs_buftarg_alloc(
 		exit(1);
 	}
 	btp->bt_mount = mp;
-	btp->bt_bdev = dev->dev;
-	btp->bt_bdev_fd = dev->fd;
+	btp->bt_dev = dev->dev;
+	btp->bt_fd = dev->fd;
 	btp->bt_xfile = NULL;
 	btp->flags = 0;
 	pthread_mutex_init(&btp->lock, NULL);
@@ -534,7 +534,7 @@ libxfs_buftarg_reinit(
 	struct xfs_mount	*mp,
 	struct libxfs_init	*xi)
 {
-	if (mp->m_ddev_targp->bt_bdev != xi->data.dev ||
+	if (mp->m_ddev_targp->bt_dev != xi->data.dev ||
 	    mp->m_ddev_targp->bt_mount != mp) {
 		fprintf(stderr,
 			_("%s: bad buftarg reinit, ddev\n"),
@@ -544,7 +544,7 @@ libxfs_buftarg_reinit(
 
 	if (mp->m_logdev_targp != mp->m_ddev_targp) {
 		if ((xi->log.dev && xi->log.dev == xi->data.dev) ||
-		    mp->m_logdev_targp->bt_bdev != xi->log.dev ||
+		    mp->m_logdev_targp->bt_dev != xi->log.dev ||
 		    mp->m_logdev_targp->bt_mount != mp) {
 			fprintf(stderr,
 				_("%s: bad buftarg reinit, logdev\n"),
@@ -554,7 +554,7 @@ libxfs_buftarg_reinit(
 	}
 
 	if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp) {
-		if (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
+		if (mp->m_rtdev_targp->bt_dev != xi->rt.dev ||
 		    mp->m_rtdev_targp->bt_mount != mp) {
 			fprintf(stderr,
 				_("%s: bad buftarg reinit, rtdev\n"),
diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h
index 5562e2928254..d861763a2a63 100644
--- a/libxfs/libxfs_io.h
+++ b/libxfs/libxfs_io.h
@@ -25,8 +25,8 @@ struct xfs_buftarg {
 	struct xfs_mount	*bt_mount;
 	pthread_mutex_t		lock;
 	unsigned long		writes_left;
-	dev_t			bt_bdev;
-	int			bt_bdev_fd;
+	dev_t			bt_dev;
+	int			bt_fd;
 	struct xfile		*bt_xfile;
 	unsigned int		flags;
 	struct cache		*bcache;	/* buffer cache */
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 14cfec7a2859..837288be0307 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -62,7 +62,7 @@ static void libxfs_brelse(struct cache_node *node);
 int
 libxfs_device_zero(struct xfs_buftarg *btp, xfs_daddr_t start, uint len)
 {
-	int		fd = btp->bt_bdev_fd;
+	int		fd = btp->bt_fd;
 	xfs_off_t	start_offset, end_offset, offset;
 	ssize_t		zsize, bytes;
 	size_t		len_bytes;
@@ -608,7 +608,7 @@ int
 libxfs_readbufr(struct xfs_buftarg *btp, xfs_daddr_t blkno, struct xfs_buf *bp,
 		int len, int flags)
 {
-	int	fd = btp->bt_bdev_fd;
+	int	fd = btp->bt_fd;
 	int	bytes = BBTOB(len);
 	int	error;
 
@@ -644,7 +644,7 @@ libxfs_readbuf_verify(
 int
 libxfs_readbufr_map(struct xfs_buftarg *btp, struct xfs_buf *bp, int flags)
 {
-	int	fd = btp->bt_bdev_fd;
+	int	fd = btp->bt_fd;
 	int	error = 0;
 	void	*buf;
 	int	i;
@@ -834,7 +834,7 @@ int
 libxfs_bwrite(
 	struct xfs_buf	*bp)
 {
-	int		fd = bp->b_target->bt_bdev_fd;
+	int		fd = bp->b_target->bt_fd;
 
 	/*
 	 * we never write buffers that are marked stale. This indicates they
@@ -1109,10 +1109,10 @@ libxfs_blkdev_issue_flush(
 {
 	int			ret;
 
-	if (btp->bt_bdev == 0)
+	if (btp->bt_dev == 0)
 		return 0;
 
-	ret = platform_flush_device(btp->bt_bdev_fd, btp->bt_bdev);
+	ret = platform_flush_device(btp->bt_fd, btp->bt_dev);
 	return ret ? -errno : 0;
 }
 
diff --git a/repair/prefetch.c b/repair/prefetch.c
index 3d26636e5e56..3e03ae7f0210 100644
--- a/repair/prefetch.c
+++ b/repair/prefetch.c
@@ -878,7 +878,7 @@ init_prefetch(
 	xfs_mount_t		*pmp)
 {
 	mp = pmp;
-	mp_fd = mp->m_ddev_targp->bt_bdev_fd;;
+	mp_fd = mp->m_ddev_targp->bt_fd;;
 	pf_max_bytes = sysconf(_SC_PAGE_SIZE) << 7;
 	pf_max_bbs = pf_max_bytes >> BBSHIFT;
 	pf_max_fsbs = pf_max_bytes >> mp->m_sb.sb_blocklog;
diff --git a/repair/zoned.c b/repair/zoned.c
index 6ab91371d95a..1e949f549583 100644
--- a/repair/zoned.c
+++ b/repair/zoned.c
@@ -50,7 +50,7 @@ void
 check_zones(
 	struct xfs_mount	*mp)
 {
-	int			fd = mp->m_rtdev_targp->bt_bdev_fd;
+	int			fd = mp->m_rtdev_targp->bt_fd;
 	uint64_t		sector = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart);
 	unsigned int		zone_size, zone_capacity;
 	uint64_t		device_size;
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 09/10] libfrog: improve ramdisk handling in platform_flush_device
  2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
                   ` (7 preceding siblings ...)
  2026-09-25  5:12 ` [PATCH 08/10] libxfs: rename bt_bdev* Christoph Hellwig
@ 2026-09-25  5:12 ` Christoph Hellwig
  2026-09-25 22:47   ` Darrick J. Wong
  2026-09-25  5:12 ` [PATCH 10/10] xfs_db: remove a double-whitespace in rdump_regfile_data Christoph Hellwig
  9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

The ramdisk driver was quirky for BLKFLSBUF, but there never was
any reason to skip the fsync.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 copy/xfs_copy.c    |  2 +-
 libfrog/linux.c    | 13 ++++++-------
 libfrog/platform.h |  2 +-
 libxfs/init.c      |  2 +-
 libxfs/rdwr.c      |  6 ++++--
 5 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c
index 5435c87dba38..4692a4ffb961 100644
--- a/copy/xfs_copy.c
+++ b/copy/xfs_copy.c
@@ -141,7 +141,7 @@ check_errors(void)
 
 	for (i = 0; i < num_targets; i++)  {
 		if (target[i].state != INACTIVE) {
-			if (platform_flush_device(target[i].fd, 0)) {
+			if (platform_flush_device(target[i].fd)) {
 				target[i].error = errno;
 				target[i].state = INACTIVE;
 				target[i].err_type = 2;
diff --git a/libfrog/linux.c b/libfrog/linux.c
index 46a5ff39e2eb..5c0d3ed7e935 100644
--- a/libfrog/linux.c
+++ b/libfrog/linux.c
@@ -152,15 +152,11 @@ platform_set_blocksize(int fd, char *path, dev_t device, int blocksize,
  */
 int
 platform_flush_device(
-	int		fd,
-	dev_t		device)
+	int		fd)
 {
 	struct stat	st;
 	int		ret;
 
-	if (major(device) == RAMDISK_MAJOR)
-		return 0;
-
 	ret = fsync(fd);
 	if (ret)
 		return ret;
@@ -169,9 +165,12 @@ platform_flush_device(
 	if (ret)
 		return ret;
 
-	if (S_ISBLK(st.st_mode))
+	/*
+	 * Historically the ram disk driver destroyed all data when BLKFLSBUF
+	 * was called.  That has been fixed a long time, but still be careful.
+	 */
+	if (S_ISBLK(st.st_mode) && major(st.st_rdev) != RAMDISK_MAJOR)
 		return ioctl(fd, BLKFLSBUF, 0);
-
 	return 0;
 }
 
diff --git a/libfrog/platform.h b/libfrog/platform.h
index 20f9bdf5ce5b..39d558f08629 100644
--- a/libfrog/platform.h
+++ b/libfrog/platform.h
@@ -12,7 +12,7 @@ int platform_check_ismounted(char *path, char *block, struct stat *sptr,
 int platform_check_iswritable(char *path, char *block, struct stat *sptr);
 void platform_set_blocksize(int fd, char *path, dev_t device, int bsz,
 		bool fatal);
-int platform_flush_device(int fd, dev_t device);
+int platform_flush_device(int fd);
 int platform_direct_blockdev(void);
 int platform_align_blockdev(void);
 unsigned long platform_physmem(void);	/* in kilobytes */
diff --git a/libxfs/init.c b/libxfs/init.c
index 5a4b255165ab..4c71027d2805 100644
--- a/libxfs/init.c
+++ b/libxfs/init.c
@@ -172,7 +172,7 @@ libxfs_device_close(
 {
 	int			ret;
 
-	ret = platform_flush_device(dev->fd, dev->dev);
+	ret = platform_flush_device(dev->fd);
 	if (ret) {
 		ret = -errno;
 		fprintf(stderr,
diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
index 837288be0307..33a0d144a1aa 100644
--- a/libxfs/rdwr.c
+++ b/libxfs/rdwr.c
@@ -1112,8 +1112,10 @@ libxfs_blkdev_issue_flush(
 	if (btp->bt_dev == 0)
 		return 0;
 
-	ret = platform_flush_device(btp->bt_fd, btp->bt_dev);
-	return ret ? -errno : 0;
+	ret = platform_flush_device(btp->bt_fd);
+	if (ret)
+		return -errno;
+	return 0;
 }
 
 /*
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/10] xfs_db: remove a double-whitespace in rdump_regfile_data
  2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
                   ` (8 preceding siblings ...)
  2026-09-25  5:12 ` [PATCH 09/10] libfrog: improve ramdisk handling in platform_flush_device Christoph Hellwig
@ 2026-09-25  5:12 ` Christoph Hellwig
  2026-09-25 22:47   ` Darrick J. Wong
  9 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-25  5:12 UTC (permalink / raw)
  To: Andrey Albershteyn; +Cc: Darrick J . Wong, linux-xfs

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 db/rdump.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/db/rdump.c b/db/rdump.c
index 7fd171a9d53f..a0177e5bd007 100644
--- a/db/rdump.c
+++ b/db/rdump.c
@@ -643,7 +643,7 @@ rdump_regfile_data(
 
 		fd_pos = XFS_FSB_TO_B(mp, irec.br_startoff);
 		if (XFS_IS_REALTIME_INODE(ip))
-			daddr =  xfs_rtb_to_daddr(mp, irec.br_startblock);
+			daddr = xfs_rtb_to_daddr(mp, irec.br_startblock);
 		else
 			daddr = XFS_FSB_TO_DADDR(mp, irec.br_startblock);
 
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 01/10] libxfs: refactor the reinit case in libxfs_buftarg_init
  2026-09-25  5:12 ` [PATCH 01/10] libxfs: refactor the reinit case in libxfs_buftarg_init Christoph Hellwig
@ 2026-09-25 22:32   ` Darrick J. Wong
  0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-25 22:32 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 07:12:47AM +0200, Christoph Hellwig wrote:
> I had to wade through this to understand what is going on here.  Factor
> the reinit code into a well-name helper and dump the rationale for it
> into a comment to make it easier for the next person to understand the
> logic.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Straightforward hoist, so
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  libxfs/init.c | 75 ++++++++++++++++++++++++++++++---------------------
>  1 file changed, 45 insertions(+), 30 deletions(-)
> 
> diff --git a/libxfs/init.c b/libxfs/init.c
> index b89c9fe360d4..63015badc24e 100644
> --- a/libxfs/init.c
> +++ b/libxfs/init.c
> @@ -487,6 +487,43 @@ static char *wf_opts[] = {
>  	[WF_MAX_OPTS]		= NULL,
>  };
>  
> +static void
> +libxfs_buftarg_reinit(
> +	struct xfs_mount	*mp,
> +	struct libxfs_init	*xi)
> +{
> +	if (mp->m_ddev_targp->bt_bdev != xi->data.dev ||
> +	    mp->m_ddev_targp->bt_mount != mp) {
> +		fprintf(stderr,
> +			_("%s: bad buftarg reinit, ddev\n"),
> +			progname);
> +		exit(1);
> +	}
> +
> +	if (!xi->log.dev || xi->log.dev == xi->data.dev) {
> +		if (mp->m_logdev_targp != mp->m_ddev_targp) {
> +			fprintf(stderr,
> +			_("%s: bad buftarg reinit, ldev mismatch\n"),
> +				progname);
> +			exit(1);
> +		}
> +	} else if (mp->m_logdev_targp->bt_bdev != xi->log.dev ||
> +		   mp->m_logdev_targp->bt_mount != mp) {
> +		fprintf(stderr,
> +			_("%s: bad buftarg reinit, logdev\n"),
> +			progname);
> +		exit(1);
> +	}
> +	if ((xi->rt.dev || xi->rt.dev == xi->data.dev) &&
> +	    (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
> +	     mp->m_rtdev_targp->bt_mount != mp)) {
> +		fprintf(stderr,
> +			_("%s: bad buftarg reinit, rtdev\n"),
> +			progname);
> +		exit(1);
> +	}
> +}
> +
>  void
>  libxfs_buftarg_init(
>  	struct xfs_mount	*mp,
> @@ -532,37 +569,15 @@ libxfs_buftarg_init(
>  		}
>  	}
>  
> +	/*
> +	 * This can happen if the utility called libxfs_buftarg_init manually
> +	 * before libxfs_mount, which calls us again.
> +	 *
> +	 * In this case all buftargs should be initialized already, and we just
> +	 * ensure the values are sane and match the current mount.
> +	 */
>  	if (mp->m_ddev_targp) {
> -		/* should already have all buftargs initialised */
> -		if (mp->m_ddev_targp->bt_bdev != xi->data.dev ||
> -		    mp->m_ddev_targp->bt_mount != mp) {
> -			fprintf(stderr,
> -				_("%s: bad buftarg reinit, ddev\n"),
> -				progname);
> -			exit(1);
> -		}
> -		if (!xi->log.dev || xi->log.dev == xi->data.dev) {
> -			if (mp->m_logdev_targp != mp->m_ddev_targp) {
> -				fprintf(stderr,
> -				_("%s: bad buftarg reinit, ldev mismatch\n"),
> -					progname);
> -				exit(1);
> -			}
> -		} else if (mp->m_logdev_targp->bt_bdev != xi->log.dev ||
> -			   mp->m_logdev_targp->bt_mount != mp) {
> -			fprintf(stderr,
> -				_("%s: bad buftarg reinit, logdev\n"),
> -				progname);
> -			exit(1);
> -		}
> -		if ((xi->rt.dev || xi->rt.dev == xi->data.dev) &&
> -		    (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
> -		     mp->m_rtdev_targp->bt_mount != mp)) {
> -			fprintf(stderr,
> -				_("%s: bad buftarg reinit, rtdev\n"),
> -				progname);
> -			exit(1);
> -		}
> +		libxfs_buftarg_reinit(mp, xi);
>  		return;
>  	}
>  
> -- 
> 2.53.0
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 02/10] libxfs: split error injection option parsing out of libxfs_buftarg_init
  2026-09-25  5:12 ` [PATCH 02/10] libxfs: split error injection option parsing out of libxfs_buftarg_init Christoph Hellwig
@ 2026-09-25 22:33   ` Darrick J. Wong
  0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-25 22:33 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 07:12:48AM +0200, Christoph Hellwig wrote:
> Add a separate helper to keep this debug code separate from the main
> initialization flow, and only set up the error injection once when
> in libxfs_mount, thus skipping it for sb probing.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Much nicer, thanks for cleaning that up :)
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  libxfs/init.c | 102 +++++++++++++++++++++++++-------------------------
>  1 file changed, 51 insertions(+), 51 deletions(-)
> 
> diff --git a/libxfs/init.c b/libxfs/init.c
> index 63015badc24e..1b5e1e1e8ba8 100644
> --- a/libxfs/init.c
> +++ b/libxfs/init.c
> @@ -445,8 +445,7 @@ static struct xfs_buftarg *
>  libxfs_buftarg_alloc(
>  	struct xfs_mount	*mp,
>  	struct libxfs_init	*xi,
> -	struct libxfs_dev	*dev,
> -	unsigned long		write_fails)
> +	struct libxfs_dev	*dev)
>  {
>  	struct xfs_buftarg	*btp;
>  
> @@ -461,10 +460,6 @@ libxfs_buftarg_alloc(
>  	btp->bt_bdev_fd = dev->fd;
>  	btp->bt_xfile = NULL;
>  	btp->flags = 0;
> -	if (write_fails) {
> -		btp->writes_left = write_fails;
> -		btp->flags |= XFS_BUFTARG_INJECT_WRITE_FAIL;
> -	}
>  	pthread_mutex_init(&btp->lock, NULL);
>  
>  	btp->bcache = cache_init(xi->bcache_flags, libxfs_bhash_size,
> @@ -487,6 +482,52 @@ static char *wf_opts[] = {
>  	[WF_MAX_OPTS]		= NULL,
>  };
>  
> +static void
> +setup_buftarg_write_error(
> +	struct xfs_buftarg	*btp,
> +	char			*val)
> +{
> +	if (!val) {
> +		fprintf(stderr, _("write fail requires a parameter\n"));
> +		exit(1);
> +	}
> +	if (!btp)
> +		return;
> +	btp->writes_left = strtoul(val, NULL, 0);
> +	if (btp->writes_left)
> +		btp->flags |= XFS_BUFTARG_INJECT_WRITE_FAIL;
> +}
> +
> +static void
> +libxfs_setup_write_error_injection(
> +	struct xfs_mount	*mp)
> +{
> +	char			*p = getenv("LIBXFS_DEBUG_WRITE_CRASH");
> +
> +	/* Simulate utility crash after a certain number of writes. */
> +	while (p && *p) {
> +		char *val;
> +
> +		switch (getsubopt(&p, wf_opts, &val)) {
> +		case WF_DATA:
> +			setup_buftarg_write_error(mp->m_ddev_targp, val);
> +			break;
> +		case WF_LOG:
> +			setup_buftarg_write_error(mp->m_logdev_targp, val);
> +			break;
> +		case WF_RT:
> +			if (mp->m_rtdev_targp == mp->m_ddev_targp)
> +				break;
> +			setup_buftarg_write_error(mp->m_rtdev_targp, val);
> +			break;
> +		default:
> +			fprintf(stderr, _("unknown write fail type %s\n"), val);
> +			exit(1);
> +			break;
> +		}
> +	}
> +}
> +
>  static void
>  libxfs_buftarg_reinit(
>  	struct xfs_mount	*mp,
> @@ -529,46 +570,6 @@ libxfs_buftarg_init(
>  	struct xfs_mount	*mp,
>  	struct libxfs_init	*xi)
>  {
> -	char			*p = getenv("LIBXFS_DEBUG_WRITE_CRASH");
> -	unsigned long		dfail = 0, lfail = 0, rfail = 0;
> -
> -	/* Simulate utility crash after a certain number of writes. */
> -	while (p && *p) {
> -		char *val;
> -
> -		switch (getsubopt(&p, wf_opts, &val)) {
> -		case WF_DATA:
> -			if (!val) {
> -				fprintf(stderr,
> -		_("ddev write fail requires a parameter\n"));
> -				exit(1);
> -			}
> -			dfail = strtoul(val, NULL, 0);
> -			break;
> -		case WF_LOG:
> -			if (!val) {
> -				fprintf(stderr,
> -		_("logdev write fail requires a parameter\n"));
> -				exit(1);
> -			}
> -			lfail = strtoul(val, NULL, 0);
> -			break;
> -		case WF_RT:
> -			if (!val) {
> -				fprintf(stderr,
> -		_("rtdev write fail requires a parameter\n"));
> -				exit(1);
> -			}
> -			rfail = strtoul(val, NULL, 0);
> -			break;
> -		default:
> -			fprintf(stderr, _("unknown write fail type %s\n"),
> -					val);
> -			exit(1);
> -			break;
> -		}
> -	}
> -
>  	/*
>  	 * This can happen if the utility called libxfs_buftarg_init manually
>  	 * before libxfs_mount, which calls us again.
> @@ -581,17 +582,15 @@ libxfs_buftarg_init(
>  		return;
>  	}
>  
> -	mp->m_ddev_targp = libxfs_buftarg_alloc(mp, xi, &xi->data, dfail);
> +	mp->m_ddev_targp = libxfs_buftarg_alloc(mp, xi, &xi->data);
>  	if (!xi->log.dev || xi->log.dev == xi->data.dev)
>  		mp->m_logdev_targp = mp->m_ddev_targp;
>  	else
> -		mp->m_logdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->log,
> -				lfail);
> +		mp->m_logdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->log);
>  	if (!xi->rt.dev || xi->rt.dev == xi->data.dev)
>  		mp->m_rtdev_targp = mp->m_ddev_targp;
>  	else
> -		mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt,
> -				rfail);
> +		mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt);
>  }
>  
>  /* Compute maximum possible height for per-AG btree types for this fs. */
> @@ -740,6 +739,7 @@ libxfs_mount(
>  	if (flags & LIBXFS_MOUNT_REPORT_CORRUPTION)
>  		xfs_set_reporting_corruption(mp);
>  	libxfs_buftarg_init(mp, xi);
> +	libxfs_setup_write_error_injection(mp);
>  
>  	if (xi->data.name)
>  		mp->m_fsname = strdup(xi->data.name);
> -- 
> 2.53.0
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 04/10] libxfs: unify buftarg handling with the kernel
  2026-09-25  5:12 ` [PATCH 04/10] libxfs: unify buftarg handling with the kernel Christoph Hellwig
@ 2026-09-25 22:37   ` Darrick J. Wong
  2026-09-26  5:59     ` Christoph Hellwig
  0 siblings, 1 reply; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-25 22:37 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 07:12:50AM +0200, Christoph Hellwig wrote:
> In the kernel, the RT buftarg is set to NULL when not realtime device is
> present, but libxfs still allocates one, and all users instead check for
> a NULL ->bt_bdev.
> 
> Switch to the kernel model of never allocating the buftarg, and check
> mp->m_rtdev_targp for NULL instead of just ->bt_bdev.

Might want to mention that xfsprogs now matches what the kernel does.

> Signed-off-by: Christoph Hellwig <hch@lst.de>

With that added in,
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  db/io.c         |  4 ++--
>  db/metadump.c   |  7 +++----
>  libxfs/init.c   | 40 +++++++++++++++++++---------------------
>  libxfs/rdwr.c   | 25 ++++++++++++++++---------
>  mkfs/xfs_mkfs.c |  6 ++----
>  5 files changed, 42 insertions(+), 40 deletions(-)
> 
> diff --git a/db/io.c b/db/io.c
> index fc9a25d41024..6aafe5bd8a15 100644
> --- a/db/io.c
> +++ b/db/io.c
> @@ -651,7 +651,7 @@ set_log_cur(
>  	int		ring_flag,
>  	bbmap_t		*bbmap)
>  {
> -	if (mp->m_logdev_targp->bt_bdev == mp->m_ddev_targp->bt_bdev) {
> +	if (mp->m_logdev_targp == mp->m_ddev_targp) {
>  		fprintf(stderr, "no external log specified\n");
>  		exitcode = 1;
>  		return;
> @@ -668,7 +668,7 @@ set_rt_cur(
>  	int		ring_flag,
>  	bbmap_t		*bbmap)
>  {
> -	if (!mp->m_rtdev_targp->bt_bdev) {
> +	if (!mp->m_rtdev_targp) {
>  		printf(_("realtime device not loaded, use -R.\n"));
>  		return ENODEV;
>  	}
> diff --git a/db/metadump.c b/db/metadump.c
> index 39639a0d51b0..6c12a5270fea 100644
> --- a/db/metadump.c
> +++ b/db/metadump.c
> @@ -3344,8 +3344,7 @@ write_metadump_v2(
>  	uint64_t		addr;
>  
>  	addr = off;
> -	if (type == TYP_LOG &&
> -	    mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
> +	if (type == TYP_LOG && mp->m_logdev_targp != mp->m_ddev_targp)
>  		addr |= XME_ADDR_LOG_DEVICE;
>  	else if (type == TYP_RTSB)
>  		addr |= XME_ADDR_RT_DEVICE;
> @@ -3464,7 +3463,7 @@ metadump_f(
>  		return 0;
>  	}
>  
> -	if (mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev)
> +	if (mp->m_logdev_targp != mp->m_ddev_targp)
>  		metadump.external_log = true;
>  
>  	if (metadump.external_log && !version_opt_set)
> @@ -3481,7 +3480,7 @@ metadump_f(
>  	 * enabled.
>  	 */
>  	if (xfs_has_realtime(mp) && xfs_has_rtsb(mp)) {
> -		if (mp->m_rtdev_targp->bt_bdev) {
> +		if (mp->m_rtdev_targp) {
>  			metadump.realtime_data = true;
>  			if (!version_opt_set)
>  				metadump.version = 2;
> diff --git a/libxfs/init.c b/libxfs/init.c
> index 1613ce2d14a3..65dadb1a23f7 100644
> --- a/libxfs/init.c
> +++ b/libxfs/init.c
> @@ -307,7 +307,7 @@ rtmount_init(
>  		return -1;
>  	}
>  
> -	if (mp->m_rtdev_targp->bt_bdev == 0 && !xfs_is_debugger(mp)) {
> +	if (!mp->m_rtdev_targp && !xfs_is_debugger(mp)) {
>  		fprintf(stderr, _("%s: filesystem has a realtime subvolume\n"),
>  			progname);
>  		return -1;
> @@ -541,27 +541,26 @@ libxfs_buftarg_reinit(
>  		exit(1);
>  	}
>  
> -	if (!xi->log.dev || xi->log.dev == xi->data.dev) {
> -		if (mp->m_logdev_targp != mp->m_ddev_targp) {
> +	if (mp->m_logdev_targp != mp->m_ddev_targp) {
> +		if ((xi->log.dev && xi->log.dev == xi->data.dev) ||
> +		    mp->m_logdev_targp->bt_bdev != xi->log.dev ||
> +		    mp->m_logdev_targp->bt_mount != mp) {
>  			fprintf(stderr,
> -			_("%s: bad buftarg reinit, ldev mismatch\n"),
> +				_("%s: bad buftarg reinit, logdev\n"),
>  				progname);
>  			exit(1);
>  		}
> -	} else if (mp->m_logdev_targp->bt_bdev != xi->log.dev ||
> -		   mp->m_logdev_targp->bt_mount != mp) {
> -		fprintf(stderr,
> -			_("%s: bad buftarg reinit, logdev\n"),
> -			progname);
> -		exit(1);
>  	}
> -	if ((xi->rt.dev || xi->rt.dev == xi->data.dev) &&
> -	    (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
> -	     mp->m_rtdev_targp->bt_mount != mp)) {
> -		fprintf(stderr,
> -			_("%s: bad buftarg reinit, rtdev\n"),
> -			progname);
> -		exit(1);
> +
> +	if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp) {
> +		if ((xi->rt.dev && xi->rt.dev == xi->data.dev) ||
> +		    mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
> +		    mp->m_rtdev_targp->bt_mount != mp) {
> +			fprintf(stderr,
> +				_("%s: bad buftarg reinit, rtdev\n"),
> +				progname);
> +			exit(1);
> +		}
>  	}
>  }
>  
> @@ -687,7 +686,7 @@ check_many_rtgroups(
>  	xfs_daddr_t		d;
>  	int			error;
>  
> -	if (!mp->m_rtdev_targp->bt_bdev) {
> +	if (!mp->m_rtdev_targp) {
>  		fprintf(stderr, _("%s: no rt device, ignoring rgcount %u\n"),
>  				progname, sbp->sb_rgcount);
>  		if (!xfs_is_debugger(mp))
> @@ -824,8 +823,7 @@ libxfs_mount(
>  	} else
>  		libxfs_buf_relse(bp);
>  
> -	if (mp->m_logdev_targp->bt_bdev &&
> -	    mp->m_logdev_targp->bt_bdev != mp->m_ddev_targp->bt_bdev) {
> +	if (mp->m_logdev_targp != mp->m_ddev_targp) {
>  		d = (xfs_daddr_t) XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
>  		if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks ||
>  		    libxfs_buf_read(mp->m_logdev_targp,
> @@ -1045,7 +1043,7 @@ libxfs_umount(
>  	free(mp->m_fsname);
>  	mp->m_fsname = NULL;
>  
> -	if (mp->m_rtdev_targp != mp->m_ddev_targp)
> +	if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp)
>  		libxfs_buftarg_free(mp->m_rtdev_targp);
>  	if (mp->m_logdev_targp != mp->m_ddev_targp)
>  		libxfs_buftarg_free(mp->m_logdev_targp);
> diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
> index 90f2d56687ca..14cfec7a2859 100644
> --- a/libxfs/rdwr.c
> +++ b/libxfs/rdwr.c
> @@ -171,7 +171,7 @@ libxfs_getrtsb(
>  	struct xfs_buf		*bp;
>  	int			error;
>  
> -	if (!mp->m_rtdev_targp->bt_bdev)
> +	if (!mp->m_rtdev_targp)
>  		return NULL;
>  
>  	ASSERT(!mp->m_sb.sb_rtstart);
> @@ -1028,7 +1028,8 @@ libxfs_bcache_purge(struct xfs_mount *mp)
>  		return;
>  	cache_purge(mp->m_ddev_targp->bcache);
>  	cache_purge(mp->m_logdev_targp->bcache);
> -	cache_purge(mp->m_rtdev_targp->bcache);
> +	if (mp->m_rtdev_targp)
> +		cache_purge(mp->m_rtdev_targp->bcache);
>  }
>  
>  void
> @@ -1038,7 +1039,8 @@ libxfs_bcache_flush(struct xfs_mount *mp)
>  		return;
>  	cache_flush(mp->m_ddev_targp->bcache);
>  	cache_flush(mp->m_logdev_targp->bcache);
> -	cache_flush(mp->m_rtdev_targp->bcache);
> +	if (mp->m_rtdev_targp)
> +		cache_flush(mp->m_rtdev_targp->bcache);
>  }
>  
>  int
> @@ -1046,7 +1048,8 @@ libxfs_bcache_overflowed(struct xfs_mount *mp)
>  {
>  	return cache_overflowed(mp->m_ddev_targp->bcache) ||
>  		cache_overflowed(mp->m_logdev_targp->bcache) ||
> -		cache_overflowed(mp->m_rtdev_targp->bcache);
> +		(mp->m_rtdev_targp &&
> +		 cache_overflowed(mp->m_rtdev_targp->bcache));
>  }
>  
>  struct cache_operations libxfs_bcache_operations = {
> @@ -1185,15 +1188,19 @@ libxfs_log_clear(
>  	xfs_daddr_t		end_blk;
>  	char			*ptr;
>  
> -	if (((btp && dptr) || (!btp && !dptr)) ||
> -	    (btp && !btp->bt_bdev) || !fs_uuid)
> +	if (!fs_uuid)
>  		return -EINVAL;
>  
> -	/* first zero the log */
> -	if (btp)
> +	if (btp) {
> +		if (dptr)
> +			return -EINVAL;
> +		/* first zero the log */
>  		libxfs_device_zero(btp, start, length);
> -	else
> +	} else {
> +		if (!dptr)
> +			return -EINVAL;
>  		memset(dptr, 0, BBTOB(length));
> +	}
>  
>  	/*
>  	 * Initialize the log record length and LSNs. XLOG_INIT_CYCLE is a
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index 3ce49a36eaa8..6eca76f0c3c9 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -5632,10 +5632,8 @@ prepare_devices(
>  			 &sbp->sb_uuid, cfg->sb_feat.log_version,
>  			 lsunit, XLOG_FMT, XLOG_INIT_CYCLE, false);
>  	/* finally, check we can write the last block in the realtime area */
> -	if (mp->m_rtdev_targp->bt_bdev &&
> -	    mp->m_rtdev_targp != mp->m_ddev_targp &&
> -	    cfg->rtblocks > 0 &&
> -	    !xfs_has_zoned(mp)) {
> +	if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp &&
> +	    cfg->rtblocks > 0 && !xfs_has_zoned(mp)) {
>  		buf = alloc_write_buf(mp->m_rtdev_targp,
>  				XFS_FSB_TO_BB(mp, cfg->rtblocks - 1LL),
>  				BTOBB(cfg->blocksize));
> -- 
> 2.53.0
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 05/10] libxfs: make the size check in rtmount_init internal RT device aware
  2026-09-25  5:12 ` [PATCH 05/10] libxfs: make the size check in rtmount_init internal RT device aware Christoph Hellwig
@ 2026-09-25 22:38   ` Darrick J. Wong
  0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-25 22:38 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 07:12:51AM +0200, Christoph Hellwig wrote:
> Add rtstart handling.  This is currently masked by broken setup of
> the rtdev targp to the ddev one for internal devices.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Urrrk. :(
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  libxfs/init.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/libxfs/init.c b/libxfs/init.c
> index 65dadb1a23f7..85e0b3402bb2 100644
> --- a/libxfs/init.c
> +++ b/libxfs/init.c
> @@ -330,7 +330,9 @@ rtmount_init(
>  			(unsigned long long) mp->m_sb.sb_rblocks);
>  		return -1;
>  	}
> -	error = libxfs_buf_read(mp->m_rtdev_targp, d - XFS_FSB_TO_BB(mp, 1),
> +	error = libxfs_buf_read(mp->m_rtdev_targp,
> +			XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart) +
> +				d - XFS_FSB_TO_BB(mp, 1),
>  			XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL);
>  	if (error) {
>  		fprintf(stderr, _("%s: realtime size check failed\n"),
> -- 
> 2.53.0
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 06/10] libxfs: don't clear ->dev in libxfs_device_close
  2026-09-25  5:12 ` [PATCH 06/10] libxfs: don't clear ->dev in libxfs_device_close Christoph Hellwig
@ 2026-09-25 22:39   ` Darrick J. Wong
  0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-25 22:39 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 07:12:52AM +0200, Christoph Hellwig wrote:
> struct libxfs_init can't be reused for multiple mounts, so there is no
> point in clearing it.  And clearing it defeats the duplicate device
> check in libxfs_close_devices, which would lead to flushing a closed
> device if this wasn't current masked by another bug.

Jeez.

> Signed-off-by: Christoph Hellwig <hch@lst.de>

Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  libxfs/init.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/libxfs/init.c b/libxfs/init.c
> index 85e0b3402bb2..842a2e1e09a9 100644
> --- a/libxfs/init.c
> +++ b/libxfs/init.c
> @@ -182,7 +182,6 @@ libxfs_device_close(
>  	close(dev->fd);
>  
>  	dev->fd = -1;
> -	dev->dev = 0;
>  }
>  
>  /*
> -- 
> 2.53.0
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 07/10] libxfs: fix buftarg initialization for the RT device
  2026-09-25  5:12 ` [PATCH 07/10] libxfs: fix buftarg initialization for the RT device Christoph Hellwig
@ 2026-09-25 22:42   ` Darrick J. Wong
  0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-25 22:42 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 07:12:53AM +0200, Christoph Hellwig wrote:
> libxfs_buftarg_init currently sets the rtdev targp to the ddev one when
> no explicit RT device is provided, which allows tools like repair to
> proceed without a specified RT device when they should not, and
> potentially can cause data corruption.
> 
> Fix this by delaying the RT buftarg initialization to libxfs_mount,
> where we can check if the superblock indicates an internal RT device.
> This works because all external callers of libxfs_buftarg_init never
> need the RT device as they just examine the sb and/or log,
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

😬😬😬
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  libxfs/init.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/libxfs/init.c b/libxfs/init.c
> index 842a2e1e09a9..97c5286c00a9 100644
> --- a/libxfs/init.c
> +++ b/libxfs/init.c
> @@ -554,8 +554,7 @@ libxfs_buftarg_reinit(
>  	}
>  
>  	if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp) {
> -		if ((xi->rt.dev && xi->rt.dev == xi->data.dev) ||
> -		    mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
> +		if (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
>  		    mp->m_rtdev_targp->bt_mount != mp) {
>  			fprintf(stderr,
>  				_("%s: bad buftarg reinit, rtdev\n"),
> @@ -587,10 +586,6 @@ libxfs_buftarg_init(
>  		mp->m_logdev_targp = mp->m_ddev_targp;
>  	else
>  		mp->m_logdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->log);
> -	if (!xi->rt.dev || xi->rt.dev == xi->data.dev)
> -		mp->m_rtdev_targp = mp->m_ddev_targp;
> -	else
> -		mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt);
>  }
>  
>  /* Compute maximum possible height for per-AG btree types for this fs. */
> @@ -739,6 +734,10 @@ libxfs_mount(
>  	if (flags & LIBXFS_MOUNT_REPORT_CORRUPTION)
>  		xfs_set_reporting_corruption(mp);
>  	libxfs_buftarg_init(mp, xi);
> +	if (sb->sb_rtstart)
> +		mp->m_rtdev_targp = mp->m_ddev_targp;
> +	else if (xi->rt.dev)
> +		mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt);
>  	libxfs_setup_write_error_injection(mp);
>  
>  	if (xi->data.name)
> -- 
> 2.53.0
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 08/10] libxfs: rename bt_bdev*
  2026-09-25  5:12 ` [PATCH 08/10] libxfs: rename bt_bdev* Christoph Hellwig
@ 2026-09-25 22:43   ` Darrick J. Wong
  0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-25 22:43 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 07:12:54AM +0200, Christoph Hellwig wrote:
> Unlike the kernel, there is no block device concept in libxfs.
> 
> Rename the bt_bdev field to bt_dev as it stores a dev_t, and bt_bdev_fd
> to just bt_fd to make the naming a bit less confusing.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Make sense to me;
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  libxfs/buf_mem.c   |  4 ++--
>  libxfs/init.c      | 10 +++++-----
>  libxfs/libxfs_io.h |  4 ++--
>  libxfs/rdwr.c      | 12 ++++++------
>  repair/prefetch.c  |  2 +-
>  repair/zoned.c     |  2 +-
>  6 files changed, 17 insertions(+), 17 deletions(-)
> 
> diff --git a/libxfs/buf_mem.c b/libxfs/buf_mem.c
> index 3c8452de9689..f3db59dfc63e 100644
> --- a/libxfs/buf_mem.c
> +++ b/libxfs/buf_mem.c
> @@ -294,8 +294,8 @@ xmbuf_alloc(
>  
>  	/* Initialize buffer target */
>  	btp->bt_mount = mp;
> -	btp->bt_bdev = (dev_t)-1;
> -	btp->bt_bdev_fd = -1;
> +	btp->bt_dev = (dev_t)-1;
> +	btp->bt_fd = -1;
>  	btp->bt_xfile = xfile;
>  	btp->bcache = cache;
>  
> diff --git a/libxfs/init.c b/libxfs/init.c
> index 97c5286c00a9..5a4b255165ab 100644
> --- a/libxfs/init.c
> +++ b/libxfs/init.c
> @@ -457,8 +457,8 @@ libxfs_buftarg_alloc(
>  		exit(1);
>  	}
>  	btp->bt_mount = mp;
> -	btp->bt_bdev = dev->dev;
> -	btp->bt_bdev_fd = dev->fd;
> +	btp->bt_dev = dev->dev;
> +	btp->bt_fd = dev->fd;
>  	btp->bt_xfile = NULL;
>  	btp->flags = 0;
>  	pthread_mutex_init(&btp->lock, NULL);
> @@ -534,7 +534,7 @@ libxfs_buftarg_reinit(
>  	struct xfs_mount	*mp,
>  	struct libxfs_init	*xi)
>  {
> -	if (mp->m_ddev_targp->bt_bdev != xi->data.dev ||
> +	if (mp->m_ddev_targp->bt_dev != xi->data.dev ||
>  	    mp->m_ddev_targp->bt_mount != mp) {
>  		fprintf(stderr,
>  			_("%s: bad buftarg reinit, ddev\n"),
> @@ -544,7 +544,7 @@ libxfs_buftarg_reinit(
>  
>  	if (mp->m_logdev_targp != mp->m_ddev_targp) {
>  		if ((xi->log.dev && xi->log.dev == xi->data.dev) ||
> -		    mp->m_logdev_targp->bt_bdev != xi->log.dev ||
> +		    mp->m_logdev_targp->bt_dev != xi->log.dev ||
>  		    mp->m_logdev_targp->bt_mount != mp) {
>  			fprintf(stderr,
>  				_("%s: bad buftarg reinit, logdev\n"),
> @@ -554,7 +554,7 @@ libxfs_buftarg_reinit(
>  	}
>  
>  	if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp) {
> -		if (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
> +		if (mp->m_rtdev_targp->bt_dev != xi->rt.dev ||
>  		    mp->m_rtdev_targp->bt_mount != mp) {
>  			fprintf(stderr,
>  				_("%s: bad buftarg reinit, rtdev\n"),
> diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h
> index 5562e2928254..d861763a2a63 100644
> --- a/libxfs/libxfs_io.h
> +++ b/libxfs/libxfs_io.h
> @@ -25,8 +25,8 @@ struct xfs_buftarg {
>  	struct xfs_mount	*bt_mount;
>  	pthread_mutex_t		lock;
>  	unsigned long		writes_left;
> -	dev_t			bt_bdev;
> -	int			bt_bdev_fd;
> +	dev_t			bt_dev;
> +	int			bt_fd;
>  	struct xfile		*bt_xfile;
>  	unsigned int		flags;
>  	struct cache		*bcache;	/* buffer cache */
> diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
> index 14cfec7a2859..837288be0307 100644
> --- a/libxfs/rdwr.c
> +++ b/libxfs/rdwr.c
> @@ -62,7 +62,7 @@ static void libxfs_brelse(struct cache_node *node);
>  int
>  libxfs_device_zero(struct xfs_buftarg *btp, xfs_daddr_t start, uint len)
>  {
> -	int		fd = btp->bt_bdev_fd;
> +	int		fd = btp->bt_fd;
>  	xfs_off_t	start_offset, end_offset, offset;
>  	ssize_t		zsize, bytes;
>  	size_t		len_bytes;
> @@ -608,7 +608,7 @@ int
>  libxfs_readbufr(struct xfs_buftarg *btp, xfs_daddr_t blkno, struct xfs_buf *bp,
>  		int len, int flags)
>  {
> -	int	fd = btp->bt_bdev_fd;
> +	int	fd = btp->bt_fd;
>  	int	bytes = BBTOB(len);
>  	int	error;
>  
> @@ -644,7 +644,7 @@ libxfs_readbuf_verify(
>  int
>  libxfs_readbufr_map(struct xfs_buftarg *btp, struct xfs_buf *bp, int flags)
>  {
> -	int	fd = btp->bt_bdev_fd;
> +	int	fd = btp->bt_fd;
>  	int	error = 0;
>  	void	*buf;
>  	int	i;
> @@ -834,7 +834,7 @@ int
>  libxfs_bwrite(
>  	struct xfs_buf	*bp)
>  {
> -	int		fd = bp->b_target->bt_bdev_fd;
> +	int		fd = bp->b_target->bt_fd;
>  
>  	/*
>  	 * we never write buffers that are marked stale. This indicates they
> @@ -1109,10 +1109,10 @@ libxfs_blkdev_issue_flush(
>  {
>  	int			ret;
>  
> -	if (btp->bt_bdev == 0)
> +	if (btp->bt_dev == 0)
>  		return 0;
>  
> -	ret = platform_flush_device(btp->bt_bdev_fd, btp->bt_bdev);
> +	ret = platform_flush_device(btp->bt_fd, btp->bt_dev);
>  	return ret ? -errno : 0;
>  }
>  
> diff --git a/repair/prefetch.c b/repair/prefetch.c
> index 3d26636e5e56..3e03ae7f0210 100644
> --- a/repair/prefetch.c
> +++ b/repair/prefetch.c
> @@ -878,7 +878,7 @@ init_prefetch(
>  	xfs_mount_t		*pmp)
>  {
>  	mp = pmp;
> -	mp_fd = mp->m_ddev_targp->bt_bdev_fd;;
> +	mp_fd = mp->m_ddev_targp->bt_fd;;
>  	pf_max_bytes = sysconf(_SC_PAGE_SIZE) << 7;
>  	pf_max_bbs = pf_max_bytes >> BBSHIFT;
>  	pf_max_fsbs = pf_max_bytes >> mp->m_sb.sb_blocklog;
> diff --git a/repair/zoned.c b/repair/zoned.c
> index 6ab91371d95a..1e949f549583 100644
> --- a/repair/zoned.c
> +++ b/repair/zoned.c
> @@ -50,7 +50,7 @@ void
>  check_zones(
>  	struct xfs_mount	*mp)
>  {
> -	int			fd = mp->m_rtdev_targp->bt_bdev_fd;
> +	int			fd = mp->m_rtdev_targp->bt_fd;
>  	uint64_t		sector = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart);
>  	unsigned int		zone_size, zone_capacity;
>  	uint64_t		device_size;
> -- 
> 2.53.0
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] libfrog: improve ramdisk handling in platform_flush_device
  2026-09-25  5:12 ` [PATCH 09/10] libfrog: improve ramdisk handling in platform_flush_device Christoph Hellwig
@ 2026-09-25 22:47   ` Darrick J. Wong
  2026-09-26  6:02     ` Christoph Hellwig
  0 siblings, 1 reply; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-25 22:47 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 07:12:55AM +0200, Christoph Hellwig wrote:
> The ramdisk driver was quirky for BLKFLSBUF, but there never was
> any reason to skip the fsync.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  copy/xfs_copy.c    |  2 +-
>  libfrog/linux.c    | 13 ++++++-------
>  libfrog/platform.h |  2 +-
>  libxfs/init.c      |  2 +-
>  libxfs/rdwr.c      |  6 ++++--
>  5 files changed, 13 insertions(+), 12 deletions(-)
> 
> diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c
> index 5435c87dba38..4692a4ffb961 100644
> --- a/copy/xfs_copy.c
> +++ b/copy/xfs_copy.c
> @@ -141,7 +141,7 @@ check_errors(void)
>  
>  	for (i = 0; i < num_targets; i++)  {
>  		if (target[i].state != INACTIVE) {
> -			if (platform_flush_device(target[i].fd, 0)) {
> +			if (platform_flush_device(target[i].fd)) {
>  				target[i].error = errno;
>  				target[i].state = INACTIVE;
>  				target[i].err_type = 2;
> diff --git a/libfrog/linux.c b/libfrog/linux.c
> index 46a5ff39e2eb..5c0d3ed7e935 100644
> --- a/libfrog/linux.c
> +++ b/libfrog/linux.c
> @@ -152,15 +152,11 @@ platform_set_blocksize(int fd, char *path, dev_t device, int blocksize,
>   */
>  int
>  platform_flush_device(
> -	int		fd,
> -	dev_t		device)
> +	int		fd)
>  {
>  	struct stat	st;
>  	int		ret;
>  
> -	if (major(device) == RAMDISK_MAJOR)
> -		return 0;
> -
>  	ret = fsync(fd);
>  	if (ret)
>  		return ret;
> @@ -169,9 +165,12 @@ platform_flush_device(
>  	if (ret)
>  		return ret;
>  
> -	if (S_ISBLK(st.st_mode))
> +	/*
> +	 * Historically the ram disk driver destroyed all data when BLKFLSBUF
> +	 * was called.  That has been fixed a long time, but still be careful.
> +	 */
> +	if (S_ISBLK(st.st_mode) && major(st.st_rdev) != RAMDISK_MAJOR)
>  		return ioctl(fd, BLKFLSBUF, 0);

BLKFLSBUF support on ramdisks hasn't been in the kernel since commit
ff26956875c2f0 ("brd: remove support for BLKFLSBUF") which was merged in
4.10 in late 2016.  Maybe we should remove it?

Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> -
>  	return 0;
>  }
>  
> diff --git a/libfrog/platform.h b/libfrog/platform.h
> index 20f9bdf5ce5b..39d558f08629 100644
> --- a/libfrog/platform.h
> +++ b/libfrog/platform.h
> @@ -12,7 +12,7 @@ int platform_check_ismounted(char *path, char *block, struct stat *sptr,
>  int platform_check_iswritable(char *path, char *block, struct stat *sptr);
>  void platform_set_blocksize(int fd, char *path, dev_t device, int bsz,
>  		bool fatal);
> -int platform_flush_device(int fd, dev_t device);
> +int platform_flush_device(int fd);
>  int platform_direct_blockdev(void);
>  int platform_align_blockdev(void);
>  unsigned long platform_physmem(void);	/* in kilobytes */
> diff --git a/libxfs/init.c b/libxfs/init.c
> index 5a4b255165ab..4c71027d2805 100644
> --- a/libxfs/init.c
> +++ b/libxfs/init.c
> @@ -172,7 +172,7 @@ libxfs_device_close(
>  {
>  	int			ret;
>  
> -	ret = platform_flush_device(dev->fd, dev->dev);
> +	ret = platform_flush_device(dev->fd);
>  	if (ret) {
>  		ret = -errno;
>  		fprintf(stderr,
> diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c
> index 837288be0307..33a0d144a1aa 100644
> --- a/libxfs/rdwr.c
> +++ b/libxfs/rdwr.c
> @@ -1112,8 +1112,10 @@ libxfs_blkdev_issue_flush(
>  	if (btp->bt_dev == 0)
>  		return 0;
>  
> -	ret = platform_flush_device(btp->bt_fd, btp->bt_dev);
> -	return ret ? -errno : 0;
> +	ret = platform_flush_device(btp->bt_fd);
> +	if (ret)
> +		return -errno;
> +	return 0;
>  }
>  
>  /*
> -- 
> 2.53.0
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 10/10] xfs_db: remove a double-whitespace in rdump_regfile_data
  2026-09-25  5:12 ` [PATCH 10/10] xfs_db: remove a double-whitespace in rdump_regfile_data Christoph Hellwig
@ 2026-09-25 22:47   ` Darrick J. Wong
  0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-25 22:47 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 07:12:56AM +0200, Christoph Hellwig wrote:
> Signed-off-by: Christoph Hellwig <hch@lst.de>

Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  db/rdump.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/db/rdump.c b/db/rdump.c
> index 7fd171a9d53f..a0177e5bd007 100644
> --- a/db/rdump.c
> +++ b/db/rdump.c
> @@ -643,7 +643,7 @@ rdump_regfile_data(
>  
>  		fd_pos = XFS_FSB_TO_B(mp, irec.br_startoff);
>  		if (XFS_IS_REALTIME_INODE(ip))
> -			daddr =  xfs_rtb_to_daddr(mp, irec.br_startblock);
> +			daddr = xfs_rtb_to_daddr(mp, irec.br_startblock);
>  		else
>  			daddr = XFS_FSB_TO_DADDR(mp, irec.br_startblock);
>  
> -- 
> 2.53.0
> 
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 04/10] libxfs: unify buftarg handling with the kernel
  2026-09-25 22:37   ` Darrick J. Wong
@ 2026-09-26  5:59     ` Christoph Hellwig
  2026-09-27 15:18       ` Darrick J. Wong
  0 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-26  5:59 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 03:37:16PM -0700, Darrick J. Wong wrote:
> On Fri, Sep 25, 2026 at 07:12:50AM +0200, Christoph Hellwig wrote:
> > In the kernel, the RT buftarg is set to NULL when not realtime device is
> > present, but libxfs still allocates one, and all users instead check for
> > a NULL ->bt_bdev.
> > 
> > Switch to the kernel model of never allocating the buftarg, and check
> > mp->m_rtdev_targp for NULL instead of just ->bt_bdev.
> 
> Might want to mention that xfsprogs now matches what the kernel does.

That's what I mean to say with "Switch to the kernel model".  But if
that was to subtle I'm open to suggestions for a better wording.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] libfrog: improve ramdisk handling in platform_flush_device
  2026-09-25 22:47   ` Darrick J. Wong
@ 2026-09-26  6:02     ` Christoph Hellwig
  2026-09-27 15:22       ` Darrick J. Wong
  0 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2026-09-26  6:02 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, Andrey Albershteyn, linux-xfs

On Fri, Sep 25, 2026 at 03:47:20PM -0700, Darrick J. Wong wrote:
> > +	 * Historically the ram disk driver destroyed all data when BLKFLSBUF
> > +	 * was called.  That has been fixed a long time, but still be careful.
> > +	 */
> > +	if (S_ISBLK(st.st_mode) && major(st.st_rdev) != RAMDISK_MAJOR)
> >  		return ioctl(fd, BLKFLSBUF, 0);
> 
> BLKFLSBUF support on ramdisks hasn't been in the kernel since commit
> ff26956875c2f0 ("brd: remove support for BLKFLSBUF") which was merged in
> 4.10 in late 2016.  Maybe we should remove it?

People use xfsprogs on really old kernels.  Now no one really should
care about data integrity on a ramdisk, but there's not too much downside
of just keeping it, so I'd rather leave it alone.

The real question to be is why we even bother with BLKFLSBUF at all.
It seems to come from e2fsprogs, where that is optionally called from
ext2fs_sync_device with a a comment:

	... and optionally attempt to
	flush the buffer cache.  The latter is basically only useful for
	system benchmarks and for torturing systems in burn-in tests.  :)

but despite that comment, all caller do set that flag.

btrfsprogs and f2fs-tool do not have any calls to BLKFLSBUF.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 04/10] libxfs: unify buftarg handling with the kernel
  2026-09-26  5:59     ` Christoph Hellwig
@ 2026-09-27 15:18       ` Darrick J. Wong
  0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-27 15:18 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Sat, Sep 26, 2026 at 07:59:12AM +0200, Christoph Hellwig wrote:
> On Fri, Sep 25, 2026 at 03:37:16PM -0700, Darrick J. Wong wrote:
> > On Fri, Sep 25, 2026 at 07:12:50AM +0200, Christoph Hellwig wrote:
> > > In the kernel, the RT buftarg is set to NULL when not realtime device is
> > > present, but libxfs still allocates one, and all users instead check for
> > > a NULL ->bt_bdev.
> > > 
> > > Switch to the kernel model of never allocating the buftarg, and check
> > > mp->m_rtdev_targp for NULL instead of just ->bt_bdev.
> > 
> > Might want to mention that xfsprogs now matches what the kernel does.
> 
> That's what I mean to say with "Switch to the kernel model".  But if
> that was to subtle I'm open to suggestions for a better wording.

Apparently it was too subtle for me, but on second reading, it's
correct.  Comment withdrawn. :)

--D

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] libfrog: improve ramdisk handling in platform_flush_device
  2026-09-26  6:02     ` Christoph Hellwig
@ 2026-09-27 15:22       ` Darrick J. Wong
  0 siblings, 0 replies; 24+ messages in thread
From: Darrick J. Wong @ 2026-09-27 15:22 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Andrey Albershteyn, linux-xfs

On Sat, Sep 26, 2026 at 08:02:54AM +0200, Christoph Hellwig wrote:
> On Fri, Sep 25, 2026 at 03:47:20PM -0700, Darrick J. Wong wrote:
> > > +	 * Historically the ram disk driver destroyed all data when BLKFLSBUF
> > > +	 * was called.  That has been fixed a long time, but still be careful.
> > > +	 */
> > > +	if (S_ISBLK(st.st_mode) && major(st.st_rdev) != RAMDISK_MAJOR)
> > >  		return ioctl(fd, BLKFLSBUF, 0);
> > 
> > BLKFLSBUF support on ramdisks hasn't been in the kernel since commit
> > ff26956875c2f0 ("brd: remove support for BLKFLSBUF") which was merged in
> > 4.10 in late 2016.  Maybe we should remove it?
> 
> People use xfsprogs on really old kernels.  Now no one really should
> care about data integrity on a ramdisk, but there's not too much downside
> of just keeping it, so I'd rather leave it alone.
> 
> The real question to be is why we even bother with BLKFLSBUF at all.
> It seems to come from e2fsprogs, where that is optionally called from
> ext2fs_sync_device with a a comment:
> 
> 	... and optionally attempt to
> 	flush the buffer cache.  The latter is basically only useful for
> 	system benchmarks and for torturing systems in burn-in tests.  :)
> 
> but despite that comment, all caller do set that flag.
> 
> btrfsprogs and f2fs-tool do not have any calls to BLKFLSBUF.

Yeah, I don't see much point in invalidating the bdev buffer cache after
flushing its contents to disk.

--D

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2026-09-27 15:22 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-25  5:12 fix missing RT detection in libxfs v2 Christoph Hellwig
2026-09-25  5:12 ` [PATCH 01/10] libxfs: refactor the reinit case in libxfs_buftarg_init Christoph Hellwig
2026-09-25 22:32   ` Darrick J. Wong
2026-09-25  5:12 ` [PATCH 02/10] libxfs: split error injection option parsing out of libxfs_buftarg_init Christoph Hellwig
2026-09-25 22:33   ` Darrick J. Wong
2026-09-25  5:12 ` [PATCH 03/10] libxfs: remove buftarg member aliases Christoph Hellwig
2026-09-25  5:12 ` [PATCH 04/10] libxfs: unify buftarg handling with the kernel Christoph Hellwig
2026-09-25 22:37   ` Darrick J. Wong
2026-09-26  5:59     ` Christoph Hellwig
2026-09-27 15:18       ` Darrick J. Wong
2026-09-25  5:12 ` [PATCH 05/10] libxfs: make the size check in rtmount_init internal RT device aware Christoph Hellwig
2026-09-25 22:38   ` Darrick J. Wong
2026-09-25  5:12 ` [PATCH 06/10] libxfs: don't clear ->dev in libxfs_device_close Christoph Hellwig
2026-09-25 22:39   ` Darrick J. Wong
2026-09-25  5:12 ` [PATCH 07/10] libxfs: fix buftarg initialization for the RT device Christoph Hellwig
2026-09-25 22:42   ` Darrick J. Wong
2026-09-25  5:12 ` [PATCH 08/10] libxfs: rename bt_bdev* Christoph Hellwig
2026-09-25 22:43   ` Darrick J. Wong
2026-09-25  5:12 ` [PATCH 09/10] libfrog: improve ramdisk handling in platform_flush_device Christoph Hellwig
2026-09-25 22:47   ` Darrick J. Wong
2026-09-26  6:02     ` Christoph Hellwig
2026-09-27 15:22       ` Darrick J. Wong
2026-09-25  5:12 ` [PATCH 10/10] xfs_db: remove a double-whitespace in rdump_regfile_data Christoph Hellwig
2026-09-25 22:47   ` Darrick J. Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox