git: f73fe9a23c9a - main - geom_linux_lvm: Add BIO_FLUSH support

From: Alexander Motin <mav_at_FreeBSD.org>
Date: Tue, 01 Sep 2026 17:22:38 UTC
The branch main has been updated by mav:

URL: https://cgit.FreeBSD.org/src/commit/?id=f73fe9a23c9a158075ba33eb4d0cff21b90bc769

commit f73fe9a23c9a158075ba33eb4d0cff21b90bc769
Author:     Alexander Motin <mav@FreeBSD.org>
AuthorDate: 2026-09-01 17:21:35 +0000
Commit:     Alexander Motin <mav@FreeBSD.org>
CommitDate: 2026-09-01 17:22:23 +0000

    geom_linux_lvm: Add BIO_FLUSH support
---
 sys/geom/linux_lvm/g_linux_lvm.c | 50 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/sys/geom/linux_lvm/g_linux_lvm.c b/sys/geom/linux_lvm/g_linux_lvm.c
index f333c08f45d9..84e206dea4c6 100644
--- a/sys/geom/linux_lvm/g_linux_lvm.c
+++ b/sys/geom/linux_lvm/g_linux_lvm.c
@@ -188,6 +188,48 @@ g_llvm_done(struct bio *b)
 	g_destroy_bio(b);
 }
 
+/*
+ * Called for both BIO_FLUSH and BIO_SPEEDUP.  Walk the PVs of the volume
+ * group rather than the segments of the logical volume, so that a PV holding
+ * more than one segment of this LV gets only a single request.
+ */
+static void
+g_llvm_passdown(struct g_llvm_vg *vg, struct g_llvm_lv *lv, struct bio *bp)
+{
+	struct bio_queue_head bq;
+	struct g_llvm_segment *sg;
+	struct g_llvm_pv *pv;
+	struct bio *cb;
+
+	bioq_init(&bq);
+	LIST_FOREACH(pv, &vg->vg_pvs, pv_next) {
+		LIST_FOREACH(sg, &lv->lv_segs, sg_next) {
+			if (sg->sg_pv == pv)
+				break;
+		}
+		if (sg == NULL)
+			continue;
+		cb = g_clone_bio(bp);
+		if (cb == NULL) {
+			bioq_dismantle(&bq);
+			if (bp->bio_error == 0)
+				bp->bio_error = ENOMEM;
+			g_io_deliver(bp, bp->bio_error);
+			return;
+		}
+		cb->bio_done = g_llvm_done;
+		cb->bio_caller1 = pv;
+		bioq_insert_tail(&bq, cb);
+	}
+
+	while ((cb = bioq_takefirst(&bq)) != NULL) {
+		pv = cb->bio_caller1;
+		cb->bio_caller1 = NULL;
+		G_LLVM_DEBUG(6, "firing bio to %s", pv->pv_gprov->name);
+		g_io_request(cb, pv->pv_gcons);
+	}
+}
+
 static void
 g_llvm_start(struct bio *bp)
 {
@@ -213,11 +255,11 @@ g_llvm_start(struct bio *bp)
 	case BIO_DELETE:
 	/* XXX BIO_GETATTR allowed? */
 		break;
+	case BIO_SPEEDUP:
+	case BIO_FLUSH:
+		g_llvm_passdown(vg, lv, bp);
+		return;
 	default:
-		/*
-		 * BIO_SPEEDUP and BIO_FLUSH should pass through to all sg
-		 * elements, but aren't.
-		 */
 		g_io_deliver(bp, EOPNOTSUPP);
 		return;
 	}