The branch stable/15 has been updated by khng: URL: https://cgit.FreeBSD.org/src/commit/?id=112c453ba91012f19ed140c56a3ac8fc929ddabb
commit 112c453ba91012f19ed140c56a3ac8fc929ddabb Author: Ka Ho Ng <[email protected]> AuthorDate: 2025-12-21 22:45:03 +0000 Commit: Ka Ho Ng <[email protected]> CommitDate: 2025-12-22 00:37:40 +0000 geom(9): struct bio KBI fix The struct bio was changed after cb85c2e2e995 on the branch. To fix this, move BIO_ERROR flag to another value, and now BIO_ERROR_COMPAT occupies 0x1 instead. Also, introduce b_error_compat field at the place where the old bio_error was. This allows non-CAM(9) disk drivers and software volume manager modules compiled against 15.0-RELEASE kernel to work on 15-STABLE kernel again. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D54327 Approved by: re (cperciva) --- sys/geom/geom_io.c | 1 + sys/kern/vfs_bio.c | 21 ++++++++++++++++++++- sys/sys/bio.h | 4 +++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c index 247a623bf1bf..3a58b3ec9d00 100644 --- a/sys/geom/geom_io.c +++ b/sys/geom/geom_io.c @@ -545,6 +545,7 @@ g_io_request(struct bio *bp, struct g_consumer *cp) bp->bio_from = cp; bp->bio_to = pp; bp->bio_error = 0; + bp->bio_error_compat = 0; bp->bio_completed = 0; KASSERT(!(bp->bio_flags & BIO_ONQUEUE), diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 880cc6b99951..c02aa30fb03a 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -4474,6 +4474,14 @@ biodone(struct bio *bp) biotrack(bp, __func__); + if ((bp->bio_flags & BIO_ERROR_COMPAT) != 0) { + /* The caller of this KPI is using the old bio(9) KBI */ + bp->bio_error = bp->bio_error_compat; + bp->bio_flags |= BIO_ERROR; + bp->bio_error_compat = 0; + bp->bio_flags &= BIO_ERROR_COMPAT; + } + /* * Avoid completing I/O when dumping after a panic since that may * result in a deadlock in the filesystem or pager code. Note that @@ -4505,8 +4513,19 @@ biodone(struct bio *bp) bp->bio_flags |= BIO_DONE; wakeup(bp); mtx_unlock(mtxp); - } else + } else { + if ((bp->bio_flags & BIO_ERROR) != 0) { + /* + * Provide compatibility with the consumers of the old + * bio(9) KBI filled in bio_done callback handler. + */ + bp->bio_error_compat = bp->bio_error; + bp->bio_flags |= BIO_ERROR_COMPAT; + } done(bp); + bp->bio_error_compat = 0; + bp->bio_flags &= BIO_ERROR_COMPAT; + } } /* diff --git a/sys/sys/bio.h b/sys/sys/bio.h index 5c12c858f3e5..ae59c659e661 100644 --- a/sys/sys/bio.h +++ b/sys/sys/bio.h @@ -54,7 +54,7 @@ #define BIO_SPEEDUP 0x0a /* Upper layers face shortage */ /* bio_flags */ -#define BIO_ERROR 0x01 /* An error occurred processing this bio. */ +#define BIO_ERROR_COMPAT 0x01 /* KBI compat on stable/15. */ #define BIO_DONE 0x02 /* This bio is finished. */ #define BIO_ONQUEUE 0x04 /* This bio is in a queue & not yet taken. */ /* @@ -66,6 +66,7 @@ #define BIO_TRANSIENT_MAPPING 0x20 #define BIO_VLIST 0x40 #define BIO_SWAP 0x200 /* Swap-related I/O */ +#define BIO_ERROR 0x1000 /* An error occurred processing this bio. */ #define BIO_EXTERR 0x2000 #define BIO_SPEEDUP_WRITE 0x4000 /* Resource shortage at upper layers */ #define BIO_SPEEDUP_TRIM 0x8000 /* Resource shortage at upper layers */ @@ -97,6 +98,7 @@ struct bio { struct vm_page **bio_ma; /* Or unmapped. */ int bio_ma_offset; /* Offset in the first page of bio_ma. */ int bio_ma_n; /* Number of pages in bio_ma. */ + int bio_error_compat; /* Error for KBI compat on stable/15 */ long bio_resid; /* Remaining I/O in bytes. */ void (*bio_done)(struct bio *); void *bio_driver1; /* Private use by the provider. */
