summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/geom/raid/g_raid.c17
-rw-r--r--sys/geom/raid/g_raid_ctl.c2
2 files changed, 8 insertions, 11 deletions
diff --git a/sys/geom/raid/g_raid.c b/sys/geom/raid/g_raid.c
index 0d7ac49..fd6d69c 100644
--- a/sys/geom/raid/g_raid.c
+++ b/sys/geom/raid/g_raid.c
@@ -2171,7 +2171,7 @@ g_raid_destroy_disk(struct g_raid_disk *disk)
int
g_raid_destroy(struct g_raid_softc *sc, int how)
{
- int opens;
+ int error, opens;
g_topology_assert_not();
if (sc == NULL)
@@ -2188,11 +2188,13 @@ g_raid_destroy(struct g_raid_softc *sc, int how)
G_RAID_DEBUG1(1, sc,
"%d volumes are still open.",
opens);
+ sx_xunlock(&sc->sc_lock);
return (EBUSY);
case G_RAID_DESTROY_DELAYED:
G_RAID_DEBUG1(1, sc,
"Array will be destroyed on last close.");
sc->sc_stopping = G_RAID_DESTROY_DELAYED;
+ sx_xunlock(&sc->sc_lock);
return (EBUSY);
case G_RAID_DESTROY_HARD:
G_RAID_DEBUG1(1, sc,
@@ -2206,9 +2208,9 @@ g_raid_destroy(struct g_raid_softc *sc, int how)
/* Wake up worker to let it selfdestruct. */
g_raid_event_send(sc, G_RAID_NODE_E_WAKE, 0);
/* Sleep until node destroyed. */
- sx_sleep(&sc->sc_stopping, &sc->sc_lock,
- PRIBIO | PDROP, "r:destroy", 0);
- return (0);
+ error = sx_sleep(&sc->sc_stopping, &sc->sc_lock,
+ PRIBIO | PDROP, "r:destroy", hz * 3);
+ return (error == EWOULDBLOCK ? EBUSY : 0);
}
static void
@@ -2303,8 +2305,6 @@ g_raid_destroy_geom(struct gctl_req *req __unused,
sx_xlock(&sc->sc_lock);
g_cancel_event(sc);
error = g_raid_destroy(gp->softc, G_RAID_DESTROY_SOFT);
- if (error != 0)
- sx_xunlock(&sc->sc_lock);
g_topology_lock();
return (error);
}
@@ -2469,7 +2469,6 @@ g_raid_shutdown_post_sync(void *arg, int howto)
struct g_geom *gp, *gp2;
struct g_raid_softc *sc;
struct g_raid_volume *vol;
- int error;
mp = arg;
DROP_GIANT();
@@ -2483,9 +2482,7 @@ g_raid_shutdown_post_sync(void *arg, int howto)
TAILQ_FOREACH(vol, &sc->sc_volumes, v_next)
g_raid_clean(vol, -1);
g_cancel_event(sc);
- error = g_raid_destroy(sc, G_RAID_DESTROY_DELAYED);
- if (error != 0)
- sx_xunlock(&sc->sc_lock);
+ g_raid_destroy(sc, G_RAID_DESTROY_DELAYED);
g_topology_lock();
}
g_topology_unlock();
diff --git a/sys/geom/raid/g_raid_ctl.c b/sys/geom/raid/g_raid_ctl.c
index 428f315..dc1536a 100644
--- a/sys/geom/raid/g_raid_ctl.c
+++ b/sys/geom/raid/g_raid_ctl.c
@@ -181,7 +181,7 @@ g_raid_ctl_stop(struct gctl_req *req, struct g_class *mp)
sx_xlock(&sc->sc_lock);
error = g_raid_destroy(sc, how);
if (error != 0)
- sx_xunlock(&sc->sc_lock);
+ gctl_error(req, "Array is busy.");
g_topology_lock();
}
OpenPOWER on IntegriCloud