svn commit: r327760 - head/sys/geom/mirror
Mark Johnston
markj at FreeBSD.org
Wed Jan 10 05:06:22 UTC 2018
Author: markj
Date: Wed Jan 10 05:06:21 2018
New Revision: 327760
URL: https://svnweb.freebsd.org/changeset/base/327760
Log:
Avoid referencing a possibly freed consumer after r327496.
g_mirror_regular_request() may free the gmirror consumer for a disk
if that disk is being disconnected, after which we must not dereference
the consumer pointer.
CID: 1384280
X-MFC with: r327496
Modified:
head/sys/geom/mirror/g_mirror.c
Modified: head/sys/geom/mirror/g_mirror.c
==============================================================================
--- head/sys/geom/mirror/g_mirror.c Wed Jan 10 02:57:22 2018 (r327759)
+++ head/sys/geom/mirror/g_mirror.c Wed Jan 10 05:06:21 2018 (r327760)
@@ -906,16 +906,12 @@ g_mirror_done(struct bio *bp)
}
static void
-g_mirror_regular_request_error(struct g_mirror_softc *sc, struct bio *bp)
+g_mirror_regular_request_error(struct g_mirror_softc *sc,
+ struct g_mirror_disk *disk, struct bio *bp)
{
- struct g_mirror_disk *disk;
- disk = bp->bio_from->private;
-
if (bp->bio_cmd == BIO_FLUSH && bp->bio_error == EOPNOTSUPP)
return;
- if (disk == NULL)
- return;
if ((disk->d_flags & G_MIRROR_DISK_FLAG_BROKEN) == 0) {
disk->d_flags |= G_MIRROR_DISK_FLAG_BROKEN;
@@ -942,6 +938,7 @@ g_mirror_regular_request_error(struct g_mirror_softc *
static void
g_mirror_regular_request(struct g_mirror_softc *sc, struct bio *bp)
{
+ struct g_mirror_disk *disk;
struct bio *pbp;
g_topology_assert_not();
@@ -952,7 +949,8 @@ g_mirror_regular_request(struct g_mirror_softc *sc, st
bp->bio_from->index--;
if (bp->bio_cmd == BIO_WRITE || bp->bio_cmd == BIO_DELETE)
sc->sc_writes--;
- if (bp->bio_from->private == NULL) {
+ disk = bp->bio_from->private;
+ if (disk == NULL) {
g_topology_lock();
g_mirror_kill_consumer(sc, bp->bio_from);
g_topology_unlock();
@@ -999,7 +997,8 @@ g_mirror_regular_request(struct g_mirror_softc *sc, st
} else if (bp->bio_error != 0) {
if (pbp->bio_error == 0)
pbp->bio_error = bp->bio_error;
- g_mirror_regular_request_error(sc, bp);
+ if (disk != NULL)
+ g_mirror_regular_request_error(sc, disk, bp);
switch (pbp->bio_cmd) {
case BIO_DELETE:
case BIO_WRITE:
More information about the svn-src-head
mailing list