diff options
author | mav <mav@FreeBSD.org> | 2012-10-29 18:04:38 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2012-10-29 18:04:38 +0000 |
commit | a43d540d9efdfd22157e434662f6be55d1437f32 (patch) | |
tree | 3057436f0446cd34f89a0161970b65aabfad7947 /sys/geom/raid/g_raid.c | |
parent | 76f8fadfa80a4732a2670b0032c3ac3fc89da8c7 (diff) | |
download | FreeBSD-src-a43d540d9efdfd22157e434662f6be55d1437f32.zip FreeBSD-src-a43d540d9efdfd22157e434662f6be55d1437f32.tar.gz |
Add basic BIO_DELETE support to GEOM RAID class for all RAID levels.
If at least one subdisk in the volume supports it, BIO_DELETE requests
will be propagated down. Unfortunatelly, for RAID levels with redundancy
unmapped blocks will be mapped back during first rebuild/resync process.
Sponsored by: iXsystems, Inc.
MFC after: 1 month
Diffstat (limited to 'sys/geom/raid/g_raid.c')
-rw-r--r-- | sys/geom/raid/g_raid.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/sys/geom/raid/g_raid.c b/sys/geom/raid/g_raid.c index e720c07..19b6d9b 100644 --- a/sys/geom/raid/g_raid.c +++ b/sys/geom/raid/g_raid.c @@ -499,6 +499,34 @@ g_raid_get_diskname(struct g_raid_disk *disk) } void +g_raid_get_disk_info(struct g_raid_disk *disk) +{ + struct g_consumer *cp = disk->d_consumer; + int error, len; + + /* Read kernel dumping information. */ + disk->d_kd.offset = 0; + disk->d_kd.length = OFF_MAX; + len = sizeof(disk->d_kd); + error = g_io_getattr("GEOM::kerneldump", cp, &len, &disk->d_kd); + if (error) + disk->d_kd.di.dumper = NULL; + if (disk->d_kd.di.dumper == NULL) + G_RAID_DEBUG1(2, disk->d_softc, + "Dumping not supported by %s: %d.", + cp->provider->name, error); + + /* Read BIO_DELETE support. */ + error = g_getattr("GEOM::candelete", cp, &disk->d_candelete); + if (error) + disk->d_candelete = 0; + if (!disk->d_candelete) + G_RAID_DEBUG1(2, disk->d_softc, + "BIO_DELETE not supported by %s: %d.", + cp->provider->name, error); +} + +void g_raid_report_disk_state(struct g_raid_disk *disk) { struct g_raid_subdisk *sd; @@ -1052,6 +1080,31 @@ g_raid_kerneldump(struct g_raid_softc *sc, struct bio *bp) } static void +g_raid_candelete(struct g_raid_softc *sc, struct bio *bp) +{ + struct g_provider *pp; + struct g_raid_volume *vol; + struct g_raid_subdisk *sd; + int *val; + int i; + + val = (int *)bp->bio_data; + pp = bp->bio_to; + vol = pp->private; + *val = 0; + for (i = 0; i < vol->v_disks_count; i++) { + sd = &vol->v_subdisks[i]; + if (sd->sd_state == G_RAID_SUBDISK_S_NONE) + continue; + if (sd->sd_disk->d_candelete) { + *val = 1; + break; + } + } + g_io_deliver(bp, 0); +} + +static void g_raid_start(struct bio *bp) { struct g_raid_softc *sc; @@ -1073,7 +1126,9 @@ g_raid_start(struct bio *bp) case BIO_FLUSH: break; case BIO_GETATTR: - if (!strcmp(bp->bio_attribute, "GEOM::kerneldump")) + if (!strcmp(bp->bio_attribute, "GEOM::candelete")) + g_raid_candelete(sc, bp); + else if (!strcmp(bp->bio_attribute, "GEOM::kerneldump")) g_raid_kerneldump(sc, bp); else g_io_deliver(bp, EOPNOTSUPP); |