diff options
author | le <le@FreeBSD.org> | 2004-03-19 10:28:34 +0000 |
---|---|---|
committer | le <le@FreeBSD.org> | 2004-03-19 10:28:34 +0000 |
commit | 9594cbf80177fc0be18e4e86999a7245729d2658 (patch) | |
tree | 71c76a01a83ed3994c0915df88b8aa6e8a0bb941 /sys/dev | |
parent | b893e6c496141ad1b9c9ac7424743d98fc89da5e (diff) | |
download | FreeBSD-src-9594cbf80177fc0be18e4e86999a7245729d2658.zip FreeBSD-src-9594cbf80177fc0be18e4e86999a7245729d2658.tar.gz |
When doing round-robin reads from a multi-plex volume, only switch to the
next plex if the sector to be read isn't nearby the last read sector.
Submitted by: Vsevolod Lobko <seva@ip.net.ua> via ru@
Approved by: grog (mentor)
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/vinum/vinumobj.h | 1 | ||||
-rw-r--r-- | sys/dev/vinum/vinumrequest.c | 16 | ||||
-rw-r--r-- | sys/dev/vinum/vinumvar.h | 7 |
3 files changed, 20 insertions, 4 deletions
diff --git a/sys/dev/vinum/vinumobj.h b/sys/dev/vinum/vinumobj.h index 81087f3..0d5b800 100644 --- a/sys/dev/vinum/vinumobj.h +++ b/sys/dev/vinum/vinumobj.h @@ -275,6 +275,7 @@ struct _plex #ifdef _KERNEL struct rangelock *lock; /* ranges of locked addresses */ struct mtx *lockmtx; /* lock mutex, one of plexmutex [] */ + daddr_t last_addr; /* last address read from this plex */ dev_t dev; /* associated device */ #endif }; diff --git a/sys/dev/vinum/vinumrequest.c b/sys/dev/vinum/vinumrequest.c index eda4c2a..0915f8c 100644 --- a/sys/dev/vinum/vinumrequest.c +++ b/sys/dev/vinum/vinumrequest.c @@ -234,10 +234,18 @@ vinumstart(struct buf *bp, int reviveok) if (vol != NULL) { plexno = vol->preferred_plex; /* get the plex to use */ if (plexno < 0) { /* round robin */ - plexno = vol->last_plex_read; - vol->last_plex_read++; - if (vol->last_plex_read >= vol->plexes) /* got the the end? */ - vol->last_plex_read = 0; /* wrap around */ + for (plexno = 0; plexno < vol->plexes; plexno++) + if (abs(bp->b_blkno - PLEX[vol->plex[plexno]].last_addr) <= ROUNDROBIN_SWITCH) + break; + if (plexno >= vol->plexes) { + vol->last_plex_read++; + if (vol->last_plex_read >= vol->plexes) + vol->last_plex_read = 0; + plexno = vol->last_plex_read; + } else { + vol->last_plex_read = plexno; + }; + PLEX[vol->plex[plexno]].last_addr = bp->b_blkno; } status = build_read_request(rq, plexno); /* build a request */ } else { diff --git a/sys/dev/vinum/vinumvar.h b/sys/dev/vinum/vinumvar.h index 807439c..8e7edd8 100644 --- a/sys/dev/vinum/vinumvar.h +++ b/sys/dev/vinum/vinumvar.h @@ -361,6 +361,13 @@ enum parityop { rebuildandcheckparity, /* rebuildparity with the -v option */ }; +/* + * When doing round-robin reads from a multi-plex volume, switch to the + * next plex if the difference of the last read sector and the next sector + * to be read is this many sectors. + */ +#define ROUNDROBIN_SWITCH 128 /* 64k */ + #ifdef VINUMDEBUG /* Debugging stuff */ enum debugflags { |