git: e61e072f3bdf - main - gconcat: Switch array to TAILQ to prepare for online append

Warner Losh imp at FreeBSD.org
Wed Jun 2 22:03:58 UTC 2021


The branch main has been updated by imp:

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

commit e61e072f3bdfd2016b87c255c9bdc880bb1aa2f9
Author:     Noah Bergbauer <noah.bergbauer at tum.de>
AuthorDate: 2020-12-27 21:01:37 +0000
Commit:     Warner Losh <imp at FreeBSD.org>
CommitDate: 2021-06-02 21:50:27 +0000

    gconcat: Switch array to TAILQ to prepare for online append
    
    Reviewed by:            imp@
    Pull Request:           https://github.com/freebsd/freebsd-src/pull/447
    Sponsored by:           Netflix
---
 sys/geom/concat/g_concat.c | 70 +++++++++++++++++++++++++---------------------
 sys/geom/concat/g_concat.h |  3 +-
 2 files changed, 40 insertions(+), 33 deletions(-)

diff --git a/sys/geom/concat/g_concat.c b/sys/geom/concat/g_concat.c
index dfa7b97a1806..b3f912a3013c 100644
--- a/sys/geom/concat/g_concat.c
+++ b/sys/geom/concat/g_concat.c
@@ -102,11 +102,12 @@ lcm(u_int a, u_int b)
 static u_int
 g_concat_nvalid(struct g_concat_softc *sc)
 {
-	u_int i, no;
+	u_int no;
+	struct g_concat_disk *disk;
 
 	no = 0;
-	for (i = 0; i < sc->sc_ndisks; i++) {
-		if (sc->sc_disks[i].d_consumer != NULL)
+	TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+		if (disk->d_consumer != NULL)
 			no++;
 	}
 
@@ -210,15 +211,14 @@ g_concat_candelete(struct bio *bp)
 {
 	struct g_concat_softc *sc;
 	struct g_concat_disk *disk;
-	int i, val;
+	int val;
 
 	sc = bp->bio_to->geom->softc;
-	for (i = 0; i < sc->sc_ndisks; i++) {
-		disk = &sc->sc_disks[i];
+	TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
 		if (!disk->d_removed && disk->d_candelete)
 			break;
 	}
-	val = i < sc->sc_ndisks;
+	val = disk != NULL;
 	g_handleattr(bp, "GEOM::candelete", &val, sizeof(val));
 }
 
@@ -229,20 +229,19 @@ g_concat_kernel_dump(struct bio *bp)
 	struct g_concat_disk *disk;
 	struct bio *cbp;
 	struct g_kerneldump *gkd;
-	u_int i;
 
 	sc = bp->bio_to->geom->softc;
 	gkd = (struct g_kerneldump *)bp->bio_data;
-	for (i = 0; i < sc->sc_ndisks; i++) {
-		if (sc->sc_disks[i].d_start <= gkd->offset &&
-		    sc->sc_disks[i].d_end > gkd->offset)
+	TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
+		if (disk->d_start <= gkd->offset &&
+		    disk->d_end > gkd->offset)
 			break;
 	}
-	if (i == sc->sc_ndisks) {
+	if (disk == NULL) {
 		g_io_deliver(bp, EOPNOTSUPP);
 		return;
 	}
-	disk = &sc->sc_disks[i];
+
 	gkd->offset -= disk->d_start;
 	if (gkd->length > disk->d_end - disk->d_start - gkd->offset)
 		gkd->length = disk->d_end - disk->d_start - gkd->offset;
@@ -287,10 +286,10 @@ g_concat_passdown(struct g_concat_softc *sc, struct bio *bp)
 	struct bio_queue_head queue;
 	struct g_consumer *cp;
 	struct bio *cbp;
-	u_int no;
+	struct g_concat_disk *disk;
 
 	bioq_init(&queue);
-	for (no = 0; no < sc->sc_ndisks; no++) {
+	TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
 		cbp = g_clone_bio(bp);
 		if (cbp == NULL) {
 			while ((cbp = bioq_takefirst(&queue)) != NULL)
@@ -302,8 +301,8 @@ g_concat_passdown(struct g_concat_softc *sc, struct bio *bp)
 		}
 		bioq_insert_tail(&queue, cbp);
 		cbp->bio_done = g_concat_done;
-		cbp->bio_caller1 = sc->sc_disks[no].d_consumer;
-		cbp->bio_to = sc->sc_disks[no].d_consumer->provider;
+		cbp->bio_caller1 = disk->d_consumer;
+		cbp->bio_to = disk->d_consumer->provider;
 	}
 	while ((cbp = bioq_takefirst(&queue)) != NULL) {
 		G_CONCAT_LOGREQ(cbp, "Sending request.");
@@ -323,7 +322,6 @@ g_concat_start(struct bio *bp)
 	off_t offset, end, length, off, len;
 	struct bio *cbp;
 	char *addr;
-	u_int no;
 
 	pp = bp->bio_to;
 	sc = pp->geom->softc;
@@ -370,8 +368,7 @@ g_concat_start(struct bio *bp)
 	end = offset + length;
 
 	bioq_init(&queue);
-	for (no = 0; no < sc->sc_ndisks; no++) {
-		disk = &sc->sc_disks[no];
+	TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
 		if (disk->d_end <= offset)
 			continue;
 		if (disk->d_start >= end)
@@ -432,7 +429,7 @@ g_concat_check_and_run(struct g_concat_softc *sc)
 {
 	struct g_concat_disk *disk;
 	struct g_provider *dp, *pp;
-	u_int no, sectorsize = 0;
+	u_int sectorsize = 0;
 	off_t start;
 	int error;
 
@@ -444,8 +441,7 @@ g_concat_check_and_run(struct g_concat_softc *sc)
 	pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE |
 	    G_PF_ACCEPT_UNMAPPED;
 	start = 0;
-	for (no = 0; no < sc->sc_ndisks; no++) {
-		disk = &sc->sc_disks[no];
+	TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
 		dp = disk->d_consumer->provider;
 		disk->d_start = start;
 		disk->d_end = disk->d_start + dp->mediasize;
@@ -462,7 +458,7 @@ g_concat_check_and_run(struct g_concat_softc *sc)
 		} else
 			G_CONCAT_DEBUG(1, "Failed to access disk %s, error %d.",
 			    dp->name, error);
-		if (no == 0)
+		if (disk == TAILQ_FIRST(&sc->sc_disks))
 			sectorsize = dp->sectorsize;
 		else
 			sectorsize = lcm(sectorsize, dp->sectorsize);
@@ -477,8 +473,9 @@ g_concat_check_and_run(struct g_concat_softc *sc)
 	pp->sectorsize = sectorsize;
 	/* We have sc->sc_disks[sc->sc_ndisks - 1].d_end in 'start'. */
 	pp->mediasize = start;
-	pp->stripesize = sc->sc_disks[0].d_consumer->provider->stripesize;
-	pp->stripeoffset = sc->sc_disks[0].d_consumer->provider->stripeoffset;
+	dp = TAILQ_FIRST(&sc->sc_disks)->d_consumer->provider;
+	pp->stripesize = dp->stripesize;
+	pp->stripeoffset = dp->stripeoffset;
 	sc->sc_provider = pp;
 	g_error_provider(pp, 0);
 
@@ -529,7 +526,10 @@ g_concat_add_disk(struct g_concat_softc *sc, struct g_provider *pp, u_int no)
 	if (no >= sc->sc_ndisks)
 		return (EINVAL);
 
-	disk = &sc->sc_disks[no];
+	for (disk = TAILQ_FIRST(&sc->sc_disks); no > 0; no--) {
+		disk = TAILQ_NEXT(disk, d_next);
+	}
+
 	/* Check if disk is not already attached. */
 	if (disk->d_consumer != NULL)
 		return (EEXIST);
@@ -594,6 +594,7 @@ g_concat_create(struct g_class *mp, const struct g_concat_metadata *md,
     u_int type)
 {
 	struct g_concat_softc *sc;
+	struct g_concat_disk *disk;
 	struct g_geom *gp;
 	u_int no;
 
@@ -623,10 +624,11 @@ g_concat_create(struct g_class *mp, const struct g_concat_metadata *md,
 
 	sc->sc_id = md->md_id;
 	sc->sc_ndisks = md->md_all;
-	sc->sc_disks = malloc(sizeof(struct g_concat_disk) * sc->sc_ndisks,
-	    M_CONCAT, M_WAITOK | M_ZERO);
-	for (no = 0; no < sc->sc_ndisks; no++)
-		sc->sc_disks[no].d_consumer = NULL;
+	TAILQ_INIT(&sc->sc_disks);
+	for (no = 0; no < sc->sc_ndisks; no++) {
+		disk = malloc(sizeof(*disk), M_CONCAT, M_WAITOK | M_ZERO);
+		TAILQ_INSERT_TAIL(&sc->sc_disks, disk, d_next);
+	}
 	sc->sc_type = type;
 	mtx_init(&sc->sc_lock, "gconcat lock", NULL, MTX_DEF);
 
@@ -645,6 +647,7 @@ g_concat_destroy(struct g_concat_softc *sc, boolean_t force)
 	struct g_provider *pp;
 	struct g_consumer *cp, *cp1;
 	struct g_geom *gp;
+	struct g_concat_disk *disk;
 
 	g_topology_assert();
 
@@ -676,7 +679,10 @@ g_concat_destroy(struct g_concat_softc *sc, boolean_t force)
 	gp->softc = NULL;
 	KASSERT(sc->sc_provider == NULL, ("Provider still exists? (device=%s)",
 	    gp->name));
-	free(sc->sc_disks, M_CONCAT);
+	while ((disk = TAILQ_FIRST(&sc->sc_disks)) != NULL) {
+		TAILQ_REMOVE(&sc->sc_disks, disk, d_next);
+		free(disk, M_CONCAT);
+	}
 	mtx_destroy(&sc->sc_lock);
 	free(sc, M_CONCAT);
 
diff --git a/sys/geom/concat/g_concat.h b/sys/geom/concat/g_concat.h
index 32e60b1b4cb2..31fb45d73f5a 100644
--- a/sys/geom/concat/g_concat.h
+++ b/sys/geom/concat/g_concat.h
@@ -55,6 +55,7 @@
     _GEOM_DEBUG("GEOM_CONCAT", g_concat_debug, 2, (bp), __VA_ARGS__)
 
 struct g_concat_disk {
+	TAILQ_ENTRY(g_concat_disk) d_next;
 	struct g_consumer	*d_consumer;
 	struct g_concat_softc	*d_softc;
 	off_t			 d_start;
@@ -69,9 +70,9 @@ struct g_concat_softc {
 	struct g_provider *sc_provider;
 	uint32_t	 sc_id;		/* concat unique ID */
 
-	struct g_concat_disk *sc_disks;
 	uint16_t	 sc_ndisks;
 	struct mtx	 sc_lock;
+	TAILQ_HEAD(g_concat_disks, g_concat_disk) sc_disks;
 };
 #define	sc_name	sc_geom->name
 #endif	/* _KERNEL */


More information about the dev-commits-src-all mailing list