mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-17 15:27:36 +00:00
Add support for writing blocks to the loader's disk cache.
PR: kern/32389 Submitted by: Jonathan Mini <mini@haikugeek.com> Sponsored by: ClickArray, Inc.
This commit is contained in:
parent
3c3a6fe0e0
commit
4543c86ece
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=87634
@ -63,6 +63,7 @@ static u_int bcache_hits, bcache_misses, bcache_ops, bcache_bypasses;
|
||||
static u_int bcache_flushes;
|
||||
static u_int bcache_bcount;
|
||||
|
||||
static void bcache_invalidate(daddr_t blkno);
|
||||
static void bcache_insert(caddr_t buf, daddr_t blkno);
|
||||
static int bcache_lookup(caddr_t buf, daddr_t blkno);
|
||||
|
||||
@ -116,16 +117,45 @@ bcache_flush(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a transfer request; fill in parts of the request that can
|
||||
/*
|
||||
* Handle a write request; write directly to the disk, and populate the
|
||||
* cache with the new values.
|
||||
*/
|
||||
static int
|
||||
write_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size,
|
||||
char *buf, size_t *rsize)
|
||||
{
|
||||
struct bcache_devdata *dd = (struct bcache_devdata *)devdata;
|
||||
daddr_t i, nblk;
|
||||
int err;
|
||||
|
||||
nblk = size / bcache_blksize;
|
||||
|
||||
/* Invalidate the blocks being written */
|
||||
for (i = 0; i < nblk; i++) {
|
||||
bcache_invalidate(blk + i);
|
||||
}
|
||||
|
||||
/* Write the blocks */
|
||||
err = dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize);
|
||||
|
||||
/* Populate the block cache with the new data */
|
||||
if (err == 0) {
|
||||
for (i = 0; i < nblk; i++) {
|
||||
bcache_insert(buf + (i * bcache_blksize),blk + i);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a read request; fill in parts of the request that can
|
||||
* be satisfied by the cache, use the supplied strategy routine to do
|
||||
* device I/O and then use the I/O results to populate the cache.
|
||||
*
|
||||
* Requests larger than 1/2 the cache size will be bypassed and go
|
||||
* directly to the disk. XXX tune this.
|
||||
*/
|
||||
int
|
||||
bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size,
|
||||
static int
|
||||
read_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size,
|
||||
char *buf, size_t *rsize)
|
||||
{
|
||||
static int bcache_unit = -1;
|
||||
@ -134,20 +164,6 @@ bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size,
|
||||
daddr_t p_blk, i, j, nblk;
|
||||
caddr_t p_buf;
|
||||
|
||||
bcache_ops++;
|
||||
|
||||
if(bcache_unit != unit) {
|
||||
bcache_flush();
|
||||
bcache_unit = unit;
|
||||
}
|
||||
|
||||
/* bypass large requests, or when the cache is inactive */
|
||||
if ((bcache_data == NULL) || ((size * 2 / bcache_blksize) > bcache_nblks)) {
|
||||
DEBUG("bypass %d from %d", size / bcache_blksize, blk);
|
||||
bcache_bypasses++;
|
||||
return(dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize));
|
||||
}
|
||||
|
||||
nblk = size / bcache_blksize;
|
||||
result = 0;
|
||||
|
||||
@ -201,6 +217,43 @@ bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size,
|
||||
return(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Requests larger than 1/2 the cache size will be bypassed and go
|
||||
* directly to the disk. XXX tune this.
|
||||
*/
|
||||
int
|
||||
bcache_strategy(void *devdata, int unit, int rw, daddr_t blk, size_t size,
|
||||
char *buf, size_t *rsize)
|
||||
{
|
||||
static int bcache_unit = -1;
|
||||
struct bcache_devdata *dd = (struct bcache_devdata *)devdata;
|
||||
int p_size, result;
|
||||
daddr_t p_blk, i, j, nblk;
|
||||
caddr_t p_buf;
|
||||
|
||||
bcache_ops++;
|
||||
|
||||
if(bcache_unit != unit) {
|
||||
bcache_flush();
|
||||
bcache_unit = unit;
|
||||
}
|
||||
|
||||
/* bypass large requests, or when the cache is inactive */
|
||||
if ((bcache_data == NULL) || ((size * 2 / bcache_blksize) > bcache_nblks)) {
|
||||
DEBUG("bypass %d from %d", size / bcache_blksize, blk);
|
||||
bcache_bypasses++;
|
||||
return(dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize));
|
||||
}
|
||||
|
||||
switch (rw) {
|
||||
case F_READ:
|
||||
return read_strategy(devdata, unit, rw, blk, size, buf, rsize);
|
||||
case F_WRITE:
|
||||
return write_strategy(devdata, unit, rw, blk, size, buf, rsize);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Insert a block into the cache. Retire the oldest block to do so, if required.
|
||||
@ -261,6 +314,24 @@ bcache_lookup(caddr_t buf, daddr_t blkno)
|
||||
return(ENOENT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Invalidate a block from the cache.
|
||||
*/
|
||||
static void
|
||||
bcache_invalidate(daddr_t blkno)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < bcache_nblks; i++) {
|
||||
if (bcache_ctl[i].bc_blkno == blkno) {
|
||||
bcache_ctl[i].bc_count = -1;
|
||||
bcache_ctl[i].bc_blkno = -1;
|
||||
DEBUG("invalidate blk %d", blkno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
COMMAND_SET(bcachestat, "bcachestat", "get disk block cache stats", command_bcache);
|
||||
|
||||
static int
|
||||
|
Loading…
Reference in New Issue
Block a user