diff options
author | sos <sos@FreeBSD.org> | 2001-03-21 11:48:14 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2001-03-21 11:48:14 +0000 |
commit | 988827577e34a2577a31ddbe6da7d7bfdb177b46 (patch) | |
tree | e83e00b4cacc42b4e20c19b3c45c1d1acc2884f3 /sys/dev/ata/ata-raid.c | |
parent | d4ebcec25e7a8c35da00c6cd7ac6616cc53b7da6 (diff) | |
download | FreeBSD-src-988827577e34a2577a31ddbe6da7d7bfdb177b46.zip FreeBSD-src-988827577e34a2577a31ddbe6da7d7bfdb177b46.tar.gz |
Handle the case where the last piece of a RAID0 (striped) disk is
not of interleave size.
Diffstat (limited to 'sys/dev/ata/ata-raid.c')
-rw-r--r-- | sys/dev/ata/ata-raid.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index 075c91d..0dfa263 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -187,10 +187,22 @@ arstrategy(struct bio *bp) else if (rdp->flags & AR_F_RAID_0) { plba = lba / rdp->interleave; chunk = lba % rdp->interleave; - buf1->drive = plba % rdp->num_subdisks; - buf1->bp.bio_pblkno = - ((plba / rdp->num_subdisks) * rdp->interleave) + chunk; - chunk = min(rdp->interleave - chunk, count); + if (plba == rdp->total_secs / rdp->interleave) { + int lastblksize = + (rdp->total_secs-(plba*rdp->interleave))/rdp->num_subdisks; + + buf1->drive = chunk / lastblksize; + buf1->bp.bio_pblkno = + ((plba / rdp->num_subdisks) * rdp->interleave) + + chunk % lastblksize; + chunk = min(count, lastblksize); + } + else { + buf1->drive = plba % rdp->num_subdisks; + buf1->bp.bio_pblkno = + ((plba / rdp->num_subdisks) * rdp->interleave) + chunk; + chunk = min(count, rdp->interleave - chunk); + } } else { buf1->bp.bio_pblkno = lba; |