svn commit: r218449 - projects/graid/head/sys/geom/raid
Alexander Motin
mav at FreeBSD.org
Tue Feb 8 19:28:14 UTC 2011
Author: mav
Date: Tue Feb 8 19:28:13 2011
New Revision: 218449
URL: http://svn.freebsd.org/changeset/base/218449
Log:
Make sure that the disk is present. Generally it is a task of
transformation layers to not send requests to absent disks, but
it is better to be safe and report non-fatal error then panic.
Modified:
projects/graid/head/sys/geom/raid/g_raid.c
Modified: projects/graid/head/sys/geom/raid/g_raid.c
==============================================================================
--- projects/graid/head/sys/geom/raid/g_raid.c Tue Feb 8 18:31:28 2011 (r218448)
+++ projects/graid/head/sys/geom/raid/g_raid.c Tue Feb 8 19:28:13 2011 (r218449)
@@ -1072,11 +1072,35 @@ void
g_raid_subdisk_iostart(struct g_raid_subdisk *sd, struct bio *bp)
{
struct g_consumer *cp;
+ struct g_raid_disk *disk;
- cp = sd->sd_disk->d_consumer;
- bp->bio_from = sd->sd_disk->d_consumer;
- bp->bio_to = sd->sd_disk->d_consumer->provider;
bp->bio_caller1 = sd;
+
+ /*
+ * Make sure that the disk is present. Generally it is a task of
+ * transformation layers to not send requests to absent disks, but
+ * it is better to be safe and report situation then sorry.
+ */
+ if (sd->sd_disk == NULL) {
+ G_RAID_LOGREQ(0, bp, "Warning! I/O request to an absent disk!");
+nodisk:
+ bp->bio_from = NULL;
+ bp->bio_to = NULL;
+ bp->bio_error = ENXIO;
+ g_raid_disk_done(bp);
+ return;
+ }
+ disk = sd->sd_disk;
+ if (disk->d_state != G_RAID_DISK_S_ACTIVE &&
+ disk->d_state != G_RAID_DISK_S_FAILED) {
+ G_RAID_LOGREQ(0, bp, "Warning! I/O request to a disk in a "
+ "wrong state (%s)!", g_raid_disk_state2str(disk->d_state));
+ goto nodisk;
+ }
+
+ cp = disk->d_consumer;
+ bp->bio_from = cp;
+ bp->bio_to = cp->provider;
cp->index++;
if (dumping) {
G_RAID_LOGREQ(3, bp, "Sending dumping request.");
@@ -1113,8 +1137,10 @@ static void
g_raid_disk_done(struct bio *bp)
{
struct g_raid_softc *sc;
+ struct g_raid_subdisk *sd;
- sc = bp->bio_from->geom->softc;
+ sd = bp->bio_caller1;
+ sc = sd->sd_softc;
mtx_lock(&sc->sc_queue_mtx);
bioq_disksort(&sc->sc_queue, bp);
mtx_unlock(&sc->sc_queue_mtx);
@@ -1136,12 +1162,14 @@ g_raid_disk_done_request(struct bio *bp)
sd = bp->bio_caller1;
sc = sd->sd_softc;
vol = sd->sd_volume;
- bp->bio_from->index--;
- disk = bp->bio_from->private;
- if (disk == NULL) {
- g_topology_lock();
- g_raid_kill_consumer(sc, bp->bio_from);
- g_topology_unlock();
+ if (bp->bio_from != NULL) {
+ bp->bio_from->index--;
+ disk = bp->bio_from->private;
+ if (disk == NULL) {
+ g_topology_lock();
+ g_raid_kill_consumer(sc, bp->bio_from);
+ g_topology_unlock();
+ }
}
bp->bio_offset -= sd->sd_offset;
@@ -1225,8 +1253,8 @@ process:
if (ep != NULL)
g_raid_handle_event(sc, ep);
if (bp != NULL) {
- if (bp->bio_from == NULL ||
- bp->bio_from->geom != sc->sc_geom)
+ if (bp->bio_to != NULL &&
+ bp->bio_to->geom == sc->sc_geom)
g_raid_start_request(bp);
else
g_raid_disk_done_request(bp);
More information about the svn-src-projects
mailing list