From nobody Tue Nov 04 04:11:57 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4d0w5B0QK3z653Wv; Tue, 04 Nov 2025 04:11:58 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4d0w594lNnz4H22; Tue, 04 Nov 2025 04:11:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1762229517; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=YeBiWN7DUHid6PkPceFE62MZdzow9hhGW7z06cnUgn8=; b=AyYHOp3FQm0GZ3bN1JhHXeWQ4VgylGKCGscg33rIpY8GtccjEYlT+dzw+7BvwhEMY960R2 JdFDyFbnxC9oA1pYwnlOw1oAxJNB/xSQ/RYM3pkQAsZ/eo4Mk06aXI+7sCrXqPL8RamkgR fE7HHYa0c8lR7Oc3yqlrvcj1XlyB87ARoFRRLE1ZUP0/p5bb+qnG43kJmcLWRn3boaRNko f1ih9aaDBYzLzSveQchVrU36wCD60hlJ+DkBFOoetE34sSTDBaCOsoOLAZEkUwXy2Er9TV 3iznZLoMym7fEKBmQvwyPBSrSYPhGSycrnl8OoUnUg+9x59bbWXGhqB9YDl2+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1762229517; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=YeBiWN7DUHid6PkPceFE62MZdzow9hhGW7z06cnUgn8=; b=u58NBUWDTdbFEKE/sPj8AopdwZEklfMpESn5cBvO5s5vDf9tExqWVWVZGKD+2zpkTFZRH2 ptGF8fX/LundJJvI4mx1CKVNpYNcyAOognh5pnwuxpW2ZnTVeIIF9iW8P0Ob3ZrPrh+l7e KX7BQNSLwpFO1ANPaYy0vB4stZpWhTaaaqK07eczmPhc5CZ78Tv52rIuH+LyhKK0vy2+eu OQRaPi+/bmjhZEQDEotqans6ZLQ9bChUoltSVDVI9jkcZX8toWBhD3rcv1+sqL5wxeglby fi6Ba0562KQEz/BnT3hcZnXxOEmuYNsphJ4/Jixiv9pxLi9n7GHbXSMSRpIRxg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1762229517; a=rsa-sha256; cv=none; b=ABnayg3qdmlnar4dMKkLOc6RjVewnOb0P0I8VtfA30HY0adJmxKjl+REPQKoCtU/DKS803 TJ7Na1Zftug31tIH1Toijiz63PvNJIEfdbC6T+/ymbqzOVn9Nhk64etTWvqd8XnjlM+jMA tB3fsBlpNcL+Yw+QqBODtG9bnniq1Am592svjmbqtQoCrRHDnDc9W4t8kMyZz5TFRhh5OH tLy4dZBIAvmJPdzTqvdaPtHgEOPV50efUresrVHbWEOzYUCeucoK5ffh7/cideUS/beiwc l2tdyBCXlwhCGZcXCOMb7BvExJoxf43tjtnODV5DbQF81swsRTEJR42gf59Spw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4d0w594DPzzj5g; Tue, 04 Nov 2025 04:11:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 5A44Bvxm034636; Tue, 4 Nov 2025 04:11:57 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 5A44BvgW034633; Tue, 4 Nov 2025 04:11:57 GMT (envelope-from git) Date: Tue, 4 Nov 2025 04:11:57 GMT Message-Id: <202511040411.5A44BvgW034633@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 6c406b5b9312 - main - exterror(9): add infra for bufs and bios List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 6c406b5b93125d030f0e63716ff389ce1a6ec4c5 Auto-Submitted: auto-generated The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=6c406b5b93125d030f0e63716ff389ce1a6ec4c5 commit 6c406b5b93125d030f0e63716ff389ce1a6ec4c5 Author: Konstantin Belousov AuthorDate: 2025-10-25 09:18:28 +0000 Commit: Konstantin Belousov CommitDate: 2025-11-04 04:11:12 +0000 exterror(9): add infra for bufs and bios The extended error can be stored in either struct bio or struct buf, indicated by BIO_EXTERR bio_flag. At some strategic places, it is copied into the current thread extended error. This structure is required because io request from the top might pass down through several io threads and the context that can report meaningful extended error does not belong to the thread that initiated the io. Sizes before the change, on amd64 nodebug: sizeof(struct buf) = 456 sizeof(struct bio) = 376 after: sizeof(struct buf) = 496 sizeof(struct bio) = 408 WIP: more geom providers should handle BIO_EXTERR when passing cloned bios down and then handling completions. Reviewed by: mckusick Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D53351 --- sys/geom/geom_dev.c | 4 ++++ sys/geom/geom_disk.c | 10 ++++++++-- sys/geom/geom_subr.c | 10 ++++++++-- sys/geom/geom_vfs.c | 7 ++++++- sys/kern/vfs_bio.c | 15 +++++++++++---- sys/sys/bio.h | 7 ++++++- sys/sys/buf.h | 10 +++++++++- sys/sys/exterr_cat.h | 2 ++ 8 files changed, 54 insertions(+), 11 deletions(-) diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index db0bc77a752f..a723d06334a0 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -734,6 +734,10 @@ g_dev_done(struct bio *bp2) g_trace(G_T_BIO, "g_dev_done(%p) had error %d", bp2, bp2->bio_error); bp->bio_flags |= BIO_ERROR; + if ((bp2->bio_flags & BIO_EXTERR) != 0) { + bp->bio_flags |= BIO_EXTERR; + bp->bio_exterr = bp2->bio_exterr; + } } else { if (bp->bio_cmd == BIO_READ) KNOTE_UNLOCKED(&sc->sc_selinfo.si_note, NOTE_READ); diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c index 9dbf00371dba..b267130d1e0c 100644 --- a/sys/geom/geom_disk.c +++ b/sys/geom/geom_disk.c @@ -235,8 +235,14 @@ g_disk_done(struct bio *bp) bp2 = bp->bio_parent; binuptime(&now); mtx_lock(&sc->done_mtx); - if (bp2->bio_error == 0) - bp2->bio_error = bp->bio_error; + if (bp2->bio_error == 0) { + if ((bp->bio_flags & BIO_EXTERR) != 0) { + bp2->bio_flags |= BIO_EXTERR; + bp2->bio_exterr = bp->bio_exterr; + } else { + bp2->bio_error = bp->bio_error; + } + } bp2->bio_completed += bp->bio_length - bp->bio_resid; if (bp->bio_cmd == BIO_READ) diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c index 2a6ce1ab6486..c70d55c6c321 100644 --- a/sys/geom/geom_subr.c +++ b/sys/geom/geom_subr.c @@ -1162,8 +1162,14 @@ g_std_done(struct bio *bp) struct bio *bp2; bp2 = bp->bio_parent; - if (bp2->bio_error == 0) - bp2->bio_error = bp->bio_error; + if (bp2->bio_error == 0) { + if ((bp->bio_flags & BIO_EXTERR) != 0) { + bp2->bio_flags |= BIO_EXTERR; + bp2->bio_exterr = bp->bio_exterr; + } else { + bp2->bio_error = bp->bio_error; + } + } bp2->bio_completed += bp->bio_completed; g_destroy_bio(bp); bp2->bio_inbed++; diff --git a/sys/geom/geom_vfs.c b/sys/geom/geom_vfs.c index 9b5e5a84191f..f074ac43d245 100644 --- a/sys/geom/geom_vfs.c +++ b/sys/geom/geom_vfs.c @@ -26,9 +26,11 @@ * SUCH DAMAGE. */ +#define EXTERR_CATEGORY EXTERR_CAT_GEOMVFS #include #include #include +#include #include #include #include @@ -156,10 +158,13 @@ g_vfs_done(struct bio *bip) " suppressing further ENXIO"); } } - bp->b_error = bip->bio_error; bp->b_ioflags = bip->bio_flags; if (bip->bio_error) bp->b_ioflags |= BIO_ERROR; + if ((bp->b_ioflags & BIO_EXTERR) != 0) + bp->b_exterr = bip->bio_exterr; + else + bp->b_error = bip->bio_error; bp->b_resid = bp->b_bcount - bip->bio_completed; g_destroy_bio(bip); diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 19c39e42bafa..22b7fe8d059a 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -44,6 +44,7 @@ * see man buf(9) for more info. */ +#define EXTERR_CATEGORY EXTERR_CAT_VFSBIO #include #include #include @@ -55,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -1775,7 +1777,6 @@ buf_alloc(struct bufdomain *bd) bp->b_blkno = bp->b_lblkno = 0; bp->b_offset = NOOFFSET; bp->b_iodone = 0; - bp->b_error = 0; bp->b_resid = 0; bp->b_bcount = 0; bp->b_npages = 0; @@ -1785,6 +1786,7 @@ buf_alloc(struct bufdomain *bd) bp->b_fsprivate1 = NULL; bp->b_fsprivate2 = NULL; bp->b_fsprivate3 = NULL; + exterr_clear(&bp->b_exterr); LIST_INIT(&bp->b_dep); return (bp); @@ -2276,7 +2278,7 @@ breadn_flags(struct vnode *vp, daddr_t blkno, daddr_t dblkno, int size, } if ((flags & GB_CVTENXIO) != 0) bp->b_xflags |= BX_CVTENXIO; - bp->b_ioflags &= ~BIO_ERROR; + bp->b_ioflags &= ~(BIO_ERROR | BIO_EXTERR); if (bp->b_rcred == NOCRED && cred != NOCRED) bp->b_rcred = crhold(cred); vfs_busy_pages(bp, 0); @@ -2353,7 +2355,7 @@ bufwrite(struct buf *bp) bundirty(bp); bp->b_flags &= ~B_DONE; - bp->b_ioflags &= ~BIO_ERROR; + bp->b_ioflags &= ~(BIO_ERROR | BIO_EXTERR); bp->b_flags |= B_CACHE; bp->b_iocmd = BIO_WRITE; @@ -4520,8 +4522,11 @@ biowait(struct bio *bp, const char *wmesg) while ((bp->bio_flags & BIO_DONE) == 0) msleep(bp, mtxp, PRIBIO, wmesg, 0); mtx_unlock(mtxp); - if (bp->bio_error != 0) + if (bp->bio_error != 0) { + if ((bp->bio_flags & BIO_EXTERR) != 0) + return (exterr_set_from(&bp->bio_exterr)); return (bp->bio_error); + } if (!(bp->bio_flags & BIO_ERROR)) return (0); return (EIO); @@ -4568,6 +4573,8 @@ bufwait(struct buf *bp) return (EINTR); } if (bp->b_ioflags & BIO_ERROR) { + if ((bp->b_ioflags & BIO_EXTERR) != 0) + exterr_set_from(&bp->b_exterr); return (bp->b_error ? bp->b_error : EIO); } else { return (0); diff --git a/sys/sys/bio.h b/sys/sys/bio.h index 74d2b03bd180..fa7f19961ebd 100644 --- a/sys/sys/bio.h +++ b/sys/sys/bio.h @@ -37,6 +37,7 @@ #ifndef _SYS_BIO_H_ #define _SYS_BIO_H_ +#include #include #include @@ -65,6 +66,7 @@ #define BIO_TRANSIENT_MAPPING 0x20 #define BIO_VLIST 0x40 #define BIO_SWAP 0x200 /* Swap-related I/O */ +#define BIO_EXTERR 0x2000 #define BIO_SPEEDUP_WRITE 0x4000 /* Resource shortage at upper layers */ #define BIO_SPEEDUP_TRIM 0x8000 /* Resource shortage at upper layers */ @@ -94,7 +96,6 @@ 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; /* Errno for BIO_ERROR. */ long bio_resid; /* Remaining I/O in bytes. */ void (*bio_done)(struct bio *); void *bio_driver1; /* Private use by the provider. */ @@ -130,8 +131,12 @@ struct bio { /* XXX: these go away when bio chaining is introduced */ daddr_t bio_pblkno; /* physical block number */ + struct kexterr bio_exterr; }; +/* Errno for BIO_ERROR. */ +#define bio_error bio_exterr.error + struct uio; struct devstat; diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 064d5cb05214..f08f05e6d50f 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -37,6 +37,7 @@ #ifndef _SYS_BUF_H_ #define _SYS_BUF_H_ +#include #include #include #include @@ -98,7 +99,6 @@ struct buf { long b_bcount; void *b_caller1; caddr_t b_data; - int b_error; uint16_t b_iocmd; /* BIO_* bio_cmd from bio.h */ uint16_t b_ioflags; /* BIO_* bio_flags from bio.h */ off_t b_iooffset; @@ -153,10 +153,12 @@ struct buf { #elif defined(BUF_TRACKING) const char *b_io_tracking; #endif + struct kexterr b_exterr; struct vm_page *b_pages[]; }; #define b_object b_bufobj->bo_object +#define b_error b_exterr.error /* * These flags are kept in b_flags. @@ -390,6 +392,12 @@ struct buf { _lockmgr_disown(&(bp)->b_lock, LOCK_FILE, LOCK_LINE) #endif +#define BUF_EXTERR_FROM_CURTHR(bp) \ + bp->b_exterr = curthread->td_kexterr + +#define BUF_EXTERR_TO_CURTHR(bp) \ + curthread->td_kexterr = bp->b_exterr + #endif /* _KERNEL */ struct buf_queue_head { diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h index 43f31e1d5dd6..34a4b9f86694 100644 --- a/sys/sys/exterr_cat.h +++ b/sys/sys/exterr_cat.h @@ -21,6 +21,8 @@ #define EXTERR_CAT_BRIDGE 7 #define EXTERR_CAT_SWAP 8 #define EXTERR_CAT_VFSSYSCALL 9 +#define EXTERR_CAT_VFSBIO 10 +#define EXTERR_CAT_GEOMVFS 11 #endif