* 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
* 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
* [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
* 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
* [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
* 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 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 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
* [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
* 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
* [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
* 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
* [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
* 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
* [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
* 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
* [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
* 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 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 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
* [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 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
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