FreeBSD/sys/geom/vinum/geom_vinum_raid5.c
/*
 * Calculate the offsets in the various subdisks for a RAID5 request. Also take
 * care of new subdisks in an expanded RAID5 array. 
 * XXX: This assumes that the new subdisks are inserted after the others (which
 * is okay as long as plex_offset is larger). If subdisks are inserted into the
 * plexlist before, we get problems.
 */
Calculate the offsets in the various subdisks for a RAID5 request. Also take
care of new subdisks in an expanded RAID5 array.
XXX: This assumes that the new subdisks are inserted after the others (which
is okay as long as plex_offset is larger). If subdisks are inserted into the
plexlist before, we get problems.
Calculate the offsets in the various subdisks for a RAID5 request . Also take care of new subdisks in an expanded RAID5 array . XXX : This assumes that the new subdisks are inserted after the others ( which is okay as long as plex_offset is larger ) . If subdisks are inserted into the plexlist before we get problems .
static int
gv_raid5_offset(struct gv_plex *p, off_t boff, off_t bcount, off_t *real_off,
    off_t *real_len, int *sdno, int *psdno, int growing)
{
	struct gv_sd *s;
	int sd, psd, sdcount;
	off_t len_left, stripeend, stripeoff, stripestart;
	sdcount = p->sdcount;
	if (growing) {
		LIST_FOREACH(s, &p->subdisks, in_plex) {
			if (s->flags & GV_SD_GROW)
				sdcount--;
		}
	}
	psd = sdcount - 1 - ( boff / (p->stripesize * (sdcount - 1))) %
	    sdcount;
	KASSERT(psdno >= 0, ("gv_raid5_offset: psdno < 0"));
	stripeoff = boff % (p->stripesize * (sdcount - 1));
	KASSERT(stripeoff >= 0, ("gv_raid5_offset: stripeoff < 0"));
	sd = stripeoff / p->stripesize;
	KASSERT(sdno >= 0, ("gv_raid5_offset: sdno < 0"));
	if (sd >= psd)
		sd++;
	stripestart = (boff - stripeoff) / (sdcount - 1);
	KASSERT(stripestart >= 0, ("gv_raid5_offset: stripestart < 0"));
	stripeoff %= p->stripesize;
	*real_off = stripestart + stripeoff;
	stripeend = stripestart + p->stripesize;
	len_left = stripeend - *real_off;
	KASSERT(len_left >= 0, ("gv_raid5_offset: len_left < 0"));
	*real_len = (bcount <= len_left) ? bcount : len_left;
	if (sdno != NULL)
		*sdno = sd;
	if (psdno != NULL)
		*psdno = psd;
	return (0);
}
static int gv_raid5_offset ( struct gv_plex * p , off_t boff , off_t bcount , off_t * real_off , off_t * real_len , int * sdno , int * psdno , int growing ) { struct gv_sd * s ; int sd , psd , sdcount ; off_t len_left , stripeend , stripeoff , stripestart ; sdcount = p -> sdcount ; if ( growing ) { LIST_FOREACH ( s , & p -> subdisks , in_plex ) { if ( s -> flags & GV_SD_GROW ) sdcount -- ; } } psd = sdcount - 1 - ( boff / ( p -> stripesize * ( sdcount - 1 ) ) ) % sdcount ; KASSERT ( psdno >= 0 , ( " " ) ) ; stripeoff = boff % ( p -> stripesize * ( sdcount - 1 ) ) ; KASSERT ( stripeoff >= 0 , ( " " ) ) ; sd = stripeoff / p -> stripesize ; KASSERT ( sdno >= 0 , ( " " ) ) ; if ( sd >= psd ) sd ++ ; stripestart = ( boff - stripeoff ) / ( sdcount - 1 ) ; KASSERT ( stripestart >= 0 , ( " " ) ) ; stripeoff %= p -> stripesize ; * real_off = stripestart + stripeoff ; stripeend = stripestart + p -> stripesize ; len_left = stripeend - * real_off ; KASSERT ( len_left >= 0 , ( " " ) ) ; * real_len = ( bcount <= len_left ) ? bcount : len_left ; if ( sdno != NULL ) * sdno = sd ; if ( psdno != NULL ) * psdno = psd ; return ( 0 ) ; }
Calculate the offsets in the various subdisks for a RAID5 request.
Calculate the offsets in the various subdisks for a RAID5 request .
/* The number of the subdisk containing the parity stripe. */ /* Offset of the start address from the start of the stripe. */ /* The number of the subdisk where the stripe resides. */ /* At or past parity subdisk. */ /* The offset of the stripe on this subdisk. */ /* The offset of the request on this subdisk. */