aboutsummaryrefslogtreecommitdiff
path: root/sys/geom/concat
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2018-10-30 00:22:14 +0000
committerMark Johnston <markj@FreeBSD.org>2018-10-30 00:22:14 +0000
commit25c9cca75768bbbd1f970d5b5da5d3773e20b080 (patch)
treeb659454b421b03ea7c34f949db5fc2c9fae66a7a /sys/geom/concat
parent68d0cda6618fed0bf55c1012694346f85e399d39 (diff)
downloadsrc-25c9cca75768bbbd1f970d5b5da5d3773e20b080.tar.gz
src-25c9cca75768bbbd1f970d5b5da5d3773e20b080.zip
Have gconcat advertise delete support if one of its disks does.
This follows the example set by other multi-disk GEOM classes. PR: 232676 Tested by: noah.bergbauer@tum.de MFC after: 1 month
Notes
Notes: svn path=/head/; revision=339900
Diffstat (limited to 'sys/geom/concat')
-rw-r--r--sys/geom/concat/g_concat.c35
-rw-r--r--sys/geom/concat/g_concat.h1
2 files changed, 36 insertions, 0 deletions
diff --git a/sys/geom/concat/g_concat.c b/sys/geom/concat/g_concat.c
index 8e1a5dd60698..f9be59101592 100644
--- a/sys/geom/concat/g_concat.c
+++ b/sys/geom/concat/g_concat.c
@@ -206,6 +206,27 @@ fail:
}
static void
+g_concat_candelete(struct bio *bp)
+{
+ struct g_concat_softc *sc;
+ struct g_concat_disk *disk;
+ int i, *val;
+
+ val = (int *)bp->bio_data;
+ *val = 0;
+
+ sc = bp->bio_to->geom->softc;
+ for (i = 0; i < sc->sc_ndisks; i++) {
+ disk = &sc->sc_disks[i];
+ if (!disk->d_removed && disk->d_candelete) {
+ *val = 1;
+ break;
+ }
+ }
+ g_io_deliver(bp, 0);
+}
+
+static void
g_concat_kernel_dump(struct bio *bp)
{
struct g_concat_softc *sc;
@@ -327,6 +348,9 @@ g_concat_start(struct bio *bp)
if (strcmp("GEOM::kerneldump", bp->bio_attribute) == 0) {
g_concat_kernel_dump(bp);
return;
+ } else if (strcmp("GEOM::candelete", bp->bio_attribute) == 0) {
+ g_concat_candelete(bp);
+ return;
}
/* To which provider it should be delivered? */
/* FALLTHROUGH */
@@ -408,6 +432,7 @@ g_concat_check_and_run(struct g_concat_softc *sc)
struct g_provider *dp, *pp;
u_int no, sectorsize = 0;
off_t start;
+ int error;
g_topology_assert();
if (g_concat_nvalid(sc) != sc->sc_ndisks)
@@ -425,6 +450,16 @@ g_concat_check_and_run(struct g_concat_softc *sc)
if (sc->sc_type == G_CONCAT_TYPE_AUTOMATIC)
disk->d_end -= dp->sectorsize;
start = disk->d_end;
+ error = g_access(disk->d_consumer, 1, 0, 0);
+ if (error == 0) {
+ error = g_getattr("GEOM::candelete", disk->d_consumer,
+ &disk->d_candelete);
+ if (error != 0)
+ disk->d_candelete = 0;
+ (void)g_access(disk->d_consumer, -1, 0, 0);
+ } else
+ G_CONCAT_DEBUG(1, "Failed to access disk %s, error %d.",
+ dp->name, error);
if (no == 0)
sectorsize = dp->sectorsize;
else
diff --git a/sys/geom/concat/g_concat.h b/sys/geom/concat/g_concat.h
index 09cc554b1968..da7b6ff72202 100644
--- a/sys/geom/concat/g_concat.h
+++ b/sys/geom/concat/g_concat.h
@@ -74,6 +74,7 @@ struct g_concat_disk {
struct g_concat_softc *d_softc;
off_t d_start;
off_t d_end;
+ int d_candelete;
int d_removed;
};