set_sd_state: Correct the conditions for bringing up empty or

initialized subdisks.

Tidy up some comments.

Eliminate sddownstate(); it wasn't being used any more.  Return
REQUEST_DOWN instead.

Add setstate_by_force() to implement the VINUM_SETSTATE_FORCE ioctl
for diddling individual object states.  This is a repair tool which
can also be used for panicing the system.  Use with utmost care if at
all.
This commit is contained in:
grog 1999-08-24 02:29:41 +00:00
parent ce932f0fb9
commit 685c3b6c7f

View File

@ -174,18 +174,22 @@ set_sd_state(int sdno, enum sdstate newstate, enum setstateflags flags)
/* FALLTHROUGH */
case sd_empty:
case sd_initialized:
/*
* If we're associated with a plex which is down, or which is
* the only one in the 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 we're associated with a plex which
* is down, or which is the only one in
* the 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))))
&& ((PLEX[sd->plexno].state < plex_firstup)
|| (PLEX[sd->plexno].volno < 0)
|| (VOL[PLEX[sd->plexno].volno].plexes == 1)))
break;
/* Otherwise it's just out of date */
/* FALLTHROUGH */
@ -193,20 +197,31 @@ set_sd_state(int sdno, enum sdstate newstate, enum setstateflags flags)
case sd_stale: /* out of date info, need reviving */
case sd_obsolete:
/*
* 1. If the subdisk is not part of a plex, bring it up, don't revive.
* 1. If the subdisk is not part of a
* plex, bring it up, don't revive.
*
* 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
* 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.
*
* 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,
* but the state doesn't change (FWIW).
* 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,
* but the state doesn't change
* (FWIW).
*/
if (sd->plexno < 0) /* no plex associated, */
break; /* bring it up */
@ -581,24 +596,6 @@ update_volume_state(int volno)
}
}
/*
* Helper for checksdstate. If this is a write
* operation, it's no necessarily the end of the
* world that we can't write: there could be
* another plex which can satisfy the operation.
* We must write everything we can, though, so we
* don't want to stop when we hit a subdisk which
* is down. Return a separate indication instead.
*/
enum requeststatus
sddownstate(struct request *rq)
{
if (rq->bp->b_flags & B_READ) /* read operation? */
return REQUEST_DOWN; /* OK, can't do it */
else
return REQUEST_DEGRADED;
}
/*
* Called from request routines when they find
* a subdisk which is not kosher. Decide whether
@ -640,11 +637,11 @@ checksdstate(struct sd *sd, struct request *rq, daddr_t diskaddr, daddr_t disken
* subdisk is down
*/
if (plex->state == plex_striped) /* plex is striped, */
return sddownstate(rq);
return REQUEST_DOWN;
else if (plex->state == plex_raid5) { /* RAID5 plex */
if (plex->sddowncount > 1) /* with more than one sd down, */
return sddownstate(rq);
return REQUEST_DOWN;
else
/*
* XXX We shouldn't do this if we can find a
@ -657,13 +654,13 @@ checksdstate(struct sd *sd, struct request *rq, daddr_t diskaddr, daddr_t disken
if (diskaddr > (sd->revived
+ sd->plexoffset
+ (sd->revive_blocksize >> DEV_BSHIFT))) /* we're beyond the end */
return sddownstate(rq);
return REQUEST_DOWN;
else if (diskend > (sd->revived + sd->plexoffset)) { /* we finish beyond the end */
if (writeop) {
rq->flags |= XFR_REVIVECONFLICT; /* note a potential conflict */
rq->sdno = sd->sdno; /* and which sd last caused it */
} else
return sddownstate(rq);
return REQUEST_DOWN;
}
return REQUEST_OK;
@ -676,20 +673,20 @@ checksdstate(struct sd *sd, struct request *rq, daddr_t diskaddr, daddr_t disken
* a read request to a reborn subdisk if that's
* all we have. XXX
*/
return sddownstate(rq);
return REQUEST_DOWN;
case sd_down:
if (writeop) /* writing to a consistent down disk */
set_sd_state(sd->sdno, sd_obsolete, setstate_force); /* it's not consistent now */
return sddownstate(rq);
return REQUEST_DOWN;
case sd_crashed:
if (writeop) /* writing to a consistent down disk */
set_sd_state(sd->sdno, sd_stale, setstate_force); /* it's not consistent now */
return sddownstate(rq);
return REQUEST_DOWN;
default:
return sddownstate(rq);
return REQUEST_DOWN;
}
}
@ -1036,6 +1033,38 @@ setstate(struct vinum_ioctl_msg *msg)
start_object(msg);
}
}
/*
* Brute force set state function. Don't look at
* any dependencies, just do it. This is mainly
* intended for testing and recovery.
*/
void
setstate_by_force(struct vinum_ioctl_msg *msg)
{
struct _ioctl_reply *ioctl_reply = (struct _ioctl_reply *) msg; /* format for returning replies */
switch (msg->type) {
case drive_object:
DRIVE[msg->index].state = msg->state;
break;
case sd_object:
SD[msg->index].state = msg->state;
break;
case plex_object:
PLEX[msg->index].state = msg->state;
break;
case volume_object:
VOL[msg->index].state = msg->state;
break;
default:
}
ioctl_reply->error = 0;
}
/* Local Variables: */
/* fill-column: 50 */
/* End: */