svn commit: r249661 - stable/9/sys/cam/ata
Kenneth D. Merry
ken at FreeBSD.org
Fri Apr 19 21:09:27 UTC 2013
Author: ken
Date: Fri Apr 19 21:09:27 2013
New Revision: 249661
URL: http://svnweb.freebsd.org/changeset/base/249661
Log:
MFC r249347:
------------------------------------------------------------------------
r249347 | ken | 2013-04-10 16:12:21 -0600 (Wed, 10 Apr 2013) | 22 lines
Add a callback to the ada(4) driver so that it knows when GEOM has released
references to it.
This is the functional equivalent to change r237518, which added this
functionality to the cd(4) and da(4) drivers.
This fix prevents a panic caused by GEOM calling adaopen() while the device
is going away. We now keep the device around until GEOM has finished
cleaning up its state.
ata_da.c: In adaregister(), add a d_gone callback to the GEOM disk
structure registered for the ada driver. Increment the
peripheral reference count for GEOM.
Add a new callback, adadiskgonecb(), that GEOM calls when
it is done with its resources. This callback releases the
reference acquired in adaregister().
Submitted by: Po-Li Soong
Sponsored by: Spectra Logic
Modified:
stable/9/sys/cam/ata/ata_da.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/cam/ata/ata_da.c
==============================================================================
--- stable/9/sys/cam/ata/ata_da.c Fri Apr 19 21:08:56 2013 (r249660)
+++ stable/9/sys/cam/ata/ata_da.c Fri Apr 19 21:09:27 2013 (r249661)
@@ -792,6 +792,20 @@ adainit(void)
}
}
+/*
+ * Callback from GEOM, called when it has finished cleaning up its
+ * resources.
+ */
+static void
+adadiskgonecb(struct disk *dp)
+{
+ struct cam_periph *periph;
+
+ periph = (struct cam_periph *)dp->d_drv1;
+
+ cam_periph_release(periph);
+}
+
static void
adaoninvalidate(struct cam_periph *periph)
{
@@ -1131,6 +1145,7 @@ adaregister(struct cam_periph *periph, v
softc->disk->d_strategy = adastrategy;
softc->disk->d_getattr = adagetattr;
softc->disk->d_dump = adadump;
+ softc->disk->d_gone = adadiskgonecb;
softc->disk->d_name = "ada";
softc->disk->d_drv1 = periph;
maxio = cpi.maxio; /* Honor max I/O size of SIM */
@@ -1194,6 +1209,17 @@ adaregister(struct cam_periph *periph, v
}
} else
legacy_id = -1;
+ /*
+ * Acquire a reference to the periph before we register with GEOM.
+ * We'll release this reference once GEOM calls us back (via
+ * adadiskgonecb()) telling us that our provider has been freed.
+ */
+ if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
+ xpt_print(periph->path, "%s: lost periph during "
+ "registration!\n", __func__);
+ cam_periph_lock(periph);
+ return (CAM_REQ_CMP_ERR);
+ }
disk_create(softc->disk, DISK_VERSION);
cam_periph_lock(periph);
cam_periph_unhold(periph);
More information about the svn-src-stable-9
mailing list