summaryrefslogtreecommitdiffstats
path: root/sys/geom/raid3
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2004-11-05 17:18:39 +0000
committerpjd <pjd@FreeBSD.org>2004-11-05 17:18:39 +0000
commitd62be2e0d6a48f1e3716b0bc39451b2d6359e657 (patch)
tree101bc7696977a70648e0607972b1730f80021033 /sys/geom/raid3
parentb004592010cec9accc33d6a1fb047e0abc18c1b5 (diff)
downloadFreeBSD-src-d62be2e0d6a48f1e3716b0bc39451b2d6359e657.zip
FreeBSD-src-d62be2e0d6a48f1e3716b0bc39451b2d6359e657.tar.gz
Don't forget to make sure that there are no not-finished requests before
marking components as clean. Pointed out by: scottl
Diffstat (limited to 'sys/geom/raid3')
-rw-r--r--sys/geom/raid3/g_raid3.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/sys/geom/raid3/g_raid3.c b/sys/geom/raid3/g_raid3.c
index eb35397..446c282 100644
--- a/sys/geom/raid3/g_raid3.c
+++ b/sys/geom/raid3/g_raid3.c
@@ -783,6 +783,32 @@ g_raid3_unidle(struct g_raid3_softc *sc)
g_topology_unlock();
}
+/*
+ * Return 1 if we should check if RAID3 device is idling.
+ */
+static int
+g_raid3_check_idle(struct g_raid3_softc *sc)
+{
+ struct g_raid3_disk *disk;
+ u_int i;
+
+ if (sc->sc_idle)
+ return (0);
+ if (sc->sc_provider != NULL && sc->sc_provider->acw == 0)
+ return (0);
+ /*
+ * Check if there are no in-flight requests.
+ */
+ for (i = 0; i < sc->sc_ndisks; i++) {
+ disk = &sc->sc_disks[i];
+ if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE)
+ continue;
+ if (disk->d_consumer->index > 0)
+ return (0);
+ }
+ return (1);
+}
+
/*
* Treat bio_driver1 field in parent bio as list head and field bio_caller1
* in child bio as pointer to the next element on the list.
@@ -1754,18 +1780,7 @@ g_raid3_worker(void *arg)
goto sleep;
}
if (bp == NULL) {
-#define G_RAID3_IS_IDLE(sc) ((sc)->sc_idle || \
- ((sc)->sc_provider != NULL && \
- (sc)->sc_provider->acw == 0))
- if (G_RAID3_IS_IDLE(sc)) {
- /*
- * If we're already in idle state, sleep without
- * a timeout.
- */
- MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
- "r3:w1", 0);
- G_RAID3_DEBUG(5, "%s: I'm here 3.", __func__);
- } else {
+ if (g_raid3_check_idle(sc)) {
u_int idletime;
idletime = g_raid3_idletime;
@@ -1773,8 +1788,8 @@ g_raid3_worker(void *arg)
idletime = 1;
idletime *= hz;
if (msleep(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
- "r3:w2", idletime) == EWOULDBLOCK) {
- G_RAID3_DEBUG(5, "%s: I'm here 4.",
+ "r3:w1", idletime) == EWOULDBLOCK) {
+ G_RAID3_DEBUG(5, "%s: I'm here 3.",
__func__);
/*
* No I/O requests in 'idletime'
@@ -1782,6 +1797,10 @@ g_raid3_worker(void *arg)
*/
g_raid3_idle(sc);
}
+ G_RAID3_DEBUG(5, "%s: I'm here 4.", __func__);
+ } else {
+ MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
+ "r3:w2", 0);
G_RAID3_DEBUG(5, "%s: I'm here 5.", __func__);
}
continue;
OpenPOWER on IntegriCloud