summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorgrog <grog@FreeBSD.org>1999-03-28 08:54:48 +0000
committergrog <grog@FreeBSD.org>1999-03-28 08:54:48 +0000
commitb76a5a44e6d9845f486212a90fbb5380039ae35d (patch)
treee21685258f8d6a14d739ef5ec39080723d3f30b4 /sys
parent4e4c94e91034dd0d3a19c94da23508eab1e45017 (diff)
downloadFreeBSD-src-b76a5a44e6d9845f486212a90fbb5380039ae35d.zip
FreeBSD-src-b76a5a44e6d9845f486212a90fbb5380039ae35d.tar.gz
set_sd_state: Handle sd_empty correctly. In particular, require
force to bring a subdisk of a RAID-5 plex out of this state. update_plex_state: Rewrite yet again.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/vinum/vinumstate.c152
1 files changed, 80 insertions, 72 deletions
diff --git a/sys/dev/vinum/vinumstate.c b/sys/dev/vinum/vinumstate.c
index 854b128..be12fc9 100644
--- a/sys/dev/vinum/vinumstate.c
+++ b/sys/dev/vinum/vinumstate.c
@@ -163,10 +163,14 @@ set_sd_state(int sdno, enum sdstate newstate, enum setstateflags flags)
/*
* If we're associated with a plex which
* is down, or which is the only one in the
- * volume, we can come up without being
- * inconsistent.
+ * volume, and we're not a RAID-5 plex, we
+ * can come up without being inconsistent.
+ * Internally, we use the force flag to bring
+ * up a RAID-5 plex after initialization.
*/
if ((sd->plexno >= 0)
+ && ((PLEX[sd->plexno].organization != plex_raid5)
+ || (flags & setstate_force))
&& (((PLEX[sd->plexno].state < plex_firstup)
|| (PLEX[sd->plexno].subdisks > 1))))
break;
@@ -181,11 +185,11 @@ set_sd_state(int sdno, enum sdstate newstate, enum setstateflags flags)
* 2. If the subdisk is part of a one-plex volume or an unattached plex,
* and it's not RAID-5, we *can't revive*. The subdisk doesn't
* change its state.
- *
+ *
* 3. If the subdisk is part of a one-plex volume or an unattached plex,
* and it's RAID-5, but more than one subdisk is down, we *still
* can't revive*. The subdisk doesn't change its state.
- *
+ *
* 4. If the subdisk is part of a multi-plex volume, we'll change to
* reviving and let the revive routines find out whether it will work
* or not. If they don't, the revive stops with an error message,
@@ -221,7 +225,7 @@ set_sd_state(int sdno, enum sdstate newstate, enum setstateflags flags)
* initializing, but not from the user. We
* use the same ioctl in each case, but Vinum(8)
* doesn't supply the -f flag, so we use that
- * to decide whether to do it or not
+ * to decide whether to do it or not
*/
case sd_initializing:
if (flags & setstate_force)
@@ -237,7 +241,7 @@ set_sd_state(int sdno, enum sdstate newstate, enum setstateflags flags)
/*
* There's no way to bring subdisks up directly from
* other states. First they need to be initialized
- * or revived
+ * or revived
*/
return 0;
}
@@ -298,7 +302,7 @@ set_plex_state(int plexno, enum plexstate state, enum setstateflags flags)
/*
* We can't bring the plex up, even by force,
* unless it's ready. update_plex_state
- * checks that
+ * checks that
*/
case plex_up: /* bring the plex up */
update_plex_state(plex->plexno); /* it'll come up if it can */
@@ -319,7 +323,7 @@ set_plex_state(int plexno, enum plexstate state, enum setstateflags flags)
/*
* This is only requested internally.
- * Trust ourselves
+ * Trust ourselves
*/
case plex_faulty:
plex->state = state; /* do it */
@@ -344,7 +348,7 @@ set_plex_state(int plexno, enum plexstate state, enum setstateflags flags)
plex_state(plex->state));
/*
* Now see what we have left, and whether
- * we're taking the volume down
+ * we're taking the volume down
*/
if (plex->volno >= 0) /* we have a volume */
update_volume_state(plex->volno); /* update its state */
@@ -424,80 +428,82 @@ update_sd_state(int sdno)
update_plex_state(sd->plexno); /* update its state */
}
+/*
+ * Force a plex and all its subdisks
+ * into an 'up' state. This is a helper
+ * for update_plex_state.
+ */
+void
+forceup(int plexno)
+{
+ struct plex *plex;
+ int sdno;
+
+ plex = &PLEX[plexno]; /* point to the plex */
+ plex->state = plex_up; /* and bring it up */
+
+ /* change the subdisks to up state */
+ for (sdno = 0; sdno < plex->subdisks; sdno++) {
+ SD[plex->sdnos[sdno]].state = sd_up;
+ log(LOG_INFO, /* tell them about it */
+ "vinum: %s is up\n",
+ SD[plex->sdnos[sdno]].name);
+ }
+}
+
/* Set the state of a plex based on its environment */
void
update_plex_state(int plexno)
{
struct plex *plex; /* point to our plex */
enum plexstate oldstate;
- enum volplexstate vps; /* how do we compare with the other plexes? */
enum sdstates statemap; /* get a map of the subdisk states */
+ enum volplexstate vps; /* how do we compare with the other plexes? */
plex = &PLEX[plexno]; /* point to our plex */
oldstate = plex->state;
-
- vps = vpstate(plex); /* how do we compare with the other plexes? */
statemap = sdstatemap(plex); /* get a map of the subdisk states */
+ vps = vpstate(plex); /* how do we compare with the other plexes? */
+
+ if ((statemap == sd_emptystate) /* all subdisks empty */
+&&((vps & volplex_otherup) == 0) /* and no other plex is up */ &&((plex->organization == plex_concat) /* and we're not RAID-5 */
+ ||(plex->organization == plex_striped))) {
+ struct volume *vol = &VOL[plex->volno]; /* possible volume to which it points */
- if (statemap == sd_upstate) /* all subdisks ready for action */
/*
- * All the subdisks are up. This also means that
- * they are consistent, so we can just bring
- * the plex up
+ * If we're a striped or concat plex associated with a
+ * volume, none of whose plexes are up, and we're new and
+ * untested, and the volume has the setupstate bit set, we
+ * can pretend to be in a consistent state.
+ *
+ * We need to do this in one swell foop: on the next call
+ * we will no longer be just empty.
+ *
+ * This code assumes that all the other plexes are also
+ * capable of coming up (i.e. all the sds are up), but
+ * that's OK: we'll come back to this function for the
+ * remaining plexes in the volume.
*/
- plex->state = plex_up; /* go for it */
- else if (statemap == sd_emptystate) { /* nothing done yet */
- if ((plex->organization == plex_concat) /* only change this for concat and struped */
- ||(plex->organization == plex_striped)) {
- /*
- * If we're associated with a volume, none of whose
- * plexes are up, and we're new and untested, and
- * the volume has the setupstate bit set, we can
- * pretend to be in a consistent state.
- */
- if (((vps & (volplex_otherup | volplex_onlyus)) == 0)
- && (plex->state == plex_init)
- && (plex->volno >= 0)
- && (VOL[plex->volno].flags & VF_CONFIG_SETUPSTATE)) {
- /*
- * Conceptually, an empty plex does not contain valid data,
- * but normally we'll see this state when we have just
- * created a plex, and it's either consistent from earlier,
- * or we don't care about the previous contents (we're going
- * to create a file system or use it for swap).
- *
- * We need to do this in one swell foop: on the next call
- * we will no longer be just empty.
- *
- * This code assumes that all the other plexes are also
- * capable of coming up (i.e. all the sds are up), but
- * that's OK: we'll come back to this function for the
- * remaining plexes in the volume.
- */
- struct volume *vol = &VOL[plex->volno];
- int plexno;
-
- for (plexno = 0; plexno < vol->plexes; plexno++)
- PLEX[vol->plex[plexno]].state = plex_up;
- } else if ((vps & volplex_otherup) == 0) { /* no other plexes up */
- int sdno;
-
- plex->state = plex_up; /* we can call that up */
- for (sdno = 0; sdno < plex->subdisks; sdno++) { /* change the subdisks to up state */
- SD[plex->sdnos[sdno]].state = sd_up;
- log(LOG_INFO, /* tell them about it */
- "vinum: %s is up\n",
- SD[plex->sdnos[sdno]].name);
- }
- } else
- plex->state = plex_faulty; /* no, it's down */
- } else /* invalid or RAID-5 organization */
- plex->state = plex_faulty; /* it's down */
- } else if ((statemap & (sd_upstate | sd_rebornstate)) == statemap) /* all up or reborn */
+
+ if ((plex->state == plex_init)
+ && (plex->volno >= 0)
+ && (vol->flags & VF_CONFIG_SETUPSTATE)) {
+ for (plexno = 0; plexno < vol->plexes; plexno++)
+ forceup(VOL[plex->volno].plex[plexno]);
+ } else
+ forceup(plexno); /* we'll do it */
+ } else if (statemap == sd_upstate)
+ /*
+ * All the subdisks are up. This also means that
+ * they are consistent, so we can just bring
+ * the plex up
+ */
+ plex->state = plex_up;
+ else if ((statemap & (sd_upstate | sd_rebornstate)) == statemap) /* all up or reborn */
plex->state = plex_flaky;
else if (statemap & (sd_upstate | sd_rebornstate)) /* some up or reborn */
plex->state = plex_corrupt; /* corrupt */
- else if (statemap & sd_initstate) /* some subdisks initializing */
+ else if (statemap & (sd_initstate | sd_emptystate)) /* some subdisks empty or initializing */
plex->state = plex_initializing;
else /* nothing at all up */
plex->state = plex_faulty;
@@ -543,14 +549,14 @@ update_volume_state(int volno)
* a subdisk which is not kosher. Decide whether
* it warrants changing the state. Return
* REQUEST_DOWN if we can't use the subdisk,
- * REQUEST_OK if we can.
+ * REQUEST_OK if we can.
*/
/*
* A prior version of this function checked the plex
* state as well. At the moment, consider plex states
* information for the user only. We'll ignore them
* and use the subdisk state only. The last version of
- * this file with the old logic was 2.7. XXX
+ * this file with the old logic was 2.7. XXX
*/
enum requeststatus
checksdstate(struct sd *sd, struct request *rq, daddr_t diskaddr, daddr_t diskend)
@@ -576,7 +582,7 @@ checksdstate(struct sd *sd, struct request *rq, daddr_t diskaddr, daddr_t disken
* - if it's striped, we can't do it (we could do some hairy
* calculations, but it's unlikely to work).
* - if it's RAID-5, we can do it as long as only one
- * subdisk is down
+ * subdisk is down
*/
if (plex->state == plex_striped) /* plex is striped, */
return REQUEST_DOWN; /* can't access it now */
@@ -600,7 +606,7 @@ checksdstate(struct sd *sd, struct request *rq, daddr_t diskaddr, daddr_t disken
/*
* Handle the mapping. We don't want to reject
* a read request to a reborn subdisk if that's
- * all we have. XXX
+ * all we have. XXX
*/
return REQUEST_DOWN;
@@ -677,6 +683,7 @@ sdstatemap(struct plex *plex)
case sd_unallocated:
case sd_uninit:
case sd_reviving:
+ case sd_referenced:
statemap |= sd_otherstate;
(plex->sddowncount)++; /* another unusable subdisk */
}
@@ -738,6 +745,7 @@ invalidate_subdisks(struct plex *plex, enum sdstate state)
case sd_stale:
case sd_crashed:
case sd_down:
+ case sd_referenced:
break;
case sd_reviving:
@@ -816,7 +824,7 @@ start_object(struct vinum_ioctl_msg *data)
}
/*
* There's no point in saying anything here:
- * the userland program does it better
+ * the userland program does it better
*/
ioctl_reply->msg[0] = '\0';
}
@@ -864,7 +872,7 @@ stop_object(struct vinum_ioctl_msg *data)
/*
* VINUM_SETSTATE ioctl: set an object state
- * msg is the message passed by the user
+ * msg is the message passed by the user
*/
void
setstate(struct vinum_ioctl_msg *msg)
OpenPOWER on IntegriCloud