Modify the manner in which we lock RAID-5 plexes. This appears to

solve some of the elusive panics we have seen with corrupted buffer
headers (specifically the zeroed-out b_iodone field).

Submitted-by:	      Bernd Walter <ticso@cicely.de>
This commit is contained in:
Greg Lehey 2000-01-05 06:09:43 +00:00
parent dbd8153d5e
commit 984e8b9ada
3 changed files with 15 additions and 7 deletions

View file

@ -33,7 +33,7 @@
* otherwise) arising in any way out of the use of this software, even if
* advised of the possibility of such damage.
*
* $Id: request.h,v 1.16 1999/10/12 04:33:24 grog Exp grog $
* $Id: request.h,v 1.17 1999/12/27 02:18:05 grog Exp grog $
* $FreeBSD$
*/
@ -118,6 +118,7 @@ struct rqgroup {
int badsdno; /* index of bad subdisk or -1 */
enum xferinfo flags; /* description of transfer */
struct rangelock *lock; /* lock for this transfer */
daddr_t lockbase; /* and lock address */
struct rqelement rqe[0]; /* and the elements of this request */
};

View file

@ -39,7 +39,7 @@
* otherwise) arising in any way out of the use of this software, even if
* advised of the possibility of such damage.
*
* $Id$
* $Id: vinuminterrupt.c,v 1.8 1999/12/27 02:20:45 grog Exp grog $
* $FreeBSD$
*/
@ -153,8 +153,13 @@ complete_rqe(struct buf *bp)
} else if ((rqg->flags & (XFR_NORMAL_WRITE | XFR_DEGRADED_WRITE)) /* RAID 5 group write operation */
&&(rqg->active == 0)) /* and we've finished phase 1 */
complete_raid5_write(rqe);
if (rqg->active == 0) /* request group finished, */
if (rqg->active == 0) { /* request group finished, */
rq->active--; /* one less */
if (rqg->lock) { /* got a lock? */
unlockrange(rqg->plexno, rqg->lock); /* yes, free it */
rqg->lock = 0;
}
}
if (rq->active == 0) { /* request finished, */
#if VINUMDEBUG
if (debug & DEBUG_RESID) {

View file

@ -38,6 +38,7 @@
* otherwise) arising in any way out of the use of this software, even if
* advised of the possibility of such damage.
*
* $Id: vinumraid5.c,v 1.17 1999/12/27 02:23:32 grog Exp grog $
* $FreeBSD$
*/
#include <dev/vinum/vinumhdr.h>
@ -113,7 +114,7 @@ void setrqebounds(struct rqelement *rqe, struct metrics *mp);
* we use, and not looking at the others (index >=
* prq->requests).
*/
enum requeststatus
enum requeststatus
bre5(struct request *rq,
int plexno,
daddr_t * diskaddr,
@ -581,9 +582,10 @@ bre5(struct request *rq,
* doing anything. We don't have to be
* performing a recovery operation: somebody
* else could be doing so, and the results could
* influence us.
* influence us. Note the fact here, we'll perform
* the lock in launch_requests.
*/
rqg->lock = lockrange(m.stripebase, bp, plex); /* lock the stripe */
rqg->lockbase = m.stripebase;
if (*diskaddr < diskend) /* didn't finish the request on this stripe */
plex->multistripe++; /* count another one */
}
@ -623,7 +625,7 @@ bre5(struct request *rq,
* rôle. Select this case by setting the
* parameter forparity != 0
*/
void
void
setrqebounds(struct rqelement *rqe, struct metrics *mp)
{
/* parity block of a normal write */