aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Grooms <mgrooms@shrew.net>2024-05-03 15:01:21 +0000
committerWarner Losh <imp@FreeBSD.org>2024-05-20 19:23:40 +0000
commitf65f02ccf2a5656e96b32705bad52b11fbc3177c (patch)
treef144c7b418d945607ad4029a1fb38687bf331eb8
parent4c2ea6e26d210d07d29c845addeb0c2a103f5904 (diff)
downloadsrc-f65f02ccf2a5656e96b32705bad52b11fbc3177c.tar.gz
src-f65f02ccf2a5656e96b32705bad52b11fbc3177c.zip
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)
-rw-r--r--sys/geom/stripe/g_stripe.c21
-rw-r--r--sys/geom/stripe/g_stripe.h3
2 files changed, 23 insertions, 1 deletions
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 */