git: f65f02ccf2a5 - stable/14 - geom_stripe: Cascade cantrim just like we do for gmirror

From: Warner Losh <imp_at_FreeBSD.org>
Date: Mon, 20 May 2024 20:06:41 UTC
The branch stable/14 has been updated by imp:

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

commit f65f02ccf2a5656e96b32705bad52b11fbc3177c
Author:     Matthew Grooms <mgrooms@shrew.net>
AuthorDate: 2024-05-03 15:01:21 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-05-20 19:23:40 +0000

    geom_stripe: Cascade cantrim just like we do for gmirror
    
    If any of the disks can support trim, cascade that up the
    stack. Otherwise, trims won't pass through striped raid setups.
    
    PR: 277673
    Reviewed by: imp (minor style tweaks from bug report)
    
    (cherry picked from commit ea2d874cca7cdfe6133c1835dadd8f0672723fa6)
---
 sys/geom/stripe/g_stripe.c | 21 ++++++++++++++++++++-
 sys/geom/stripe/g_stripe.h |  3 +++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/sys/geom/stripe/g_stripe.c b/sys/geom/stripe/g_stripe.c
index ca3fbcbb30b2..2708284a8091 100644
--- a/sys/geom/stripe/g_stripe.c
+++ b/sys/geom/stripe/g_stripe.c
@@ -592,7 +592,12 @@ g_stripe_start(struct bio *bp)
 		g_stripe_pushdown(sc, bp);
 		return;
 	case BIO_GETATTR:
-		/* To which provider it should be delivered? */
+		if (!strcmp(bp->bio_attribute, "GEOM::candelete")) {
+			int val = (sc->sc_flags & G_STRIPE_FLAG_CANDELETE) != 0;
+			g_handleattr(bp, "GEOM::candelete", &val, sizeof(val));
+			return;
+		}
+		/* otherwise: To which provider it should be delivered? */
 	default:
 		g_io_deliver(bp, EOPNOTSUPP);
 		return;
@@ -795,6 +800,20 @@ g_stripe_add_disk(struct g_stripe_softc *sc, struct g_provider *pp, u_int no)
 	}
 
 	sc->sc_disks[no] = cp;
+
+	/* cascade candelete */
+	error = g_access(cp, 1, 0, 0);
+	if (error == 0) {
+		int can_delete;
+
+		error = g_getattr("GEOM::candelete", cp, &can_delete);
+		if (error == 0 && can_delete != 0)
+			sc->sc_flags |= G_STRIPE_FLAG_CANDELETE;
+		G_STRIPE_DEBUG(1, "Provider %s candelete %i.", pp->name,
+		    can_delete);
+		g_access(cp, -1, 0, 0);
+	}
+
 	G_STRIPE_DEBUG(0, "Disk %s attached to %s.", pp->name, sc->sc_name);
 	g_stripe_check_and_run(sc);
 
diff --git a/sys/geom/stripe/g_stripe.h b/sys/geom/stripe/g_stripe.h
index 4c5430275350..1075a176b9b3 100644
--- a/sys/geom/stripe/g_stripe.h
+++ b/sys/geom/stripe/g_stripe.h
@@ -47,6 +47,8 @@
 #define	G_STRIPE_TYPE_MANUAL	0
 #define	G_STRIPE_TYPE_AUTOMATIC	1
 
+#define	G_STRIPE_FLAG_CANDELETE	0x00000001UL
+
 #define	G_STRIPE_DEBUG(lvl, ...) \
     _GEOM_DEBUG("GEOM_STRIPE", g_stripe_debug, (lvl), NULL, __VA_ARGS__)
 #define	G_STRIPE_LOGREQ(bp, ...) \
@@ -62,6 +64,7 @@ struct g_stripe_softc {
 	off_t		 sc_stripesize;
 	uint32_t	 sc_stripebits;
 	struct mtx	 sc_lock;
+	int		 sc_flags;
 };
 #define	sc_name	sc_geom->name
 #endif	/* _KERNEL */