ext2: use new secondary cache method

This gets rid of the ! emitted by VM when using ext2
This commit is contained in:
Thomas Veerman 2012-07-26 15:20:16 +00:00
parent 6c597561bc
commit 48237f1730
4 changed files with 58 additions and 36 deletions

View File

@ -28,7 +28,9 @@
static void rm_lru(struct buf *bp);
static void rw_block(struct buf *, int);
static int vmcache_avail = -1; /* 0 if not available, >0 if available. */
int vmcache = 0; /* are we using vm's secondary cache? (initially not) */
static block_t super_start = 0, super_end = 0;
/*===========================================================================*
* get_block *
@ -57,27 +59,11 @@ struct buf *get_block(
int b;
static struct buf *bp, *prev_ptr;
u64_t yieldid = VM_BLOCKID_NONE, getid = make64(dev, block);
int vmcache = 0;
assert(buf_hash);
assert(buf);
assert(nr_bufs > 0);
if(vmcache_avail < 0) {
/* Test once for the availability of the vm yield block feature. */
if(vm_forgetblock(VM_BLOCKID_NONE) == ENOSYS) {
vmcache_avail = 0;
} else {
vmcache_avail = 1;
}
}
/* use vmcache if it's available, and allowed, and we're not doing
* i/o on a ram disk device.
*/
if(vmcache_avail && may_use_vmcache && major(dev) != MEMORY_MAJOR)
vmcache = 1;
ASSERT(fs_block_size > 0);
/* Search the hash chain for (dev, block). Do_read() can use
@ -499,16 +485,16 @@ static void rm_lru(
}
/*===========================================================================*
* set_blocksize *
* cache_resize *
*===========================================================================*/
void set_blocksize(unsigned int blocksize, u32_t blocks,
u32_t freeblocks, dev_t majordev)
static void cache_resize(unsigned int blocksize, unsigned int bufs)
{
struct buf *bp;
struct inode *rip;
int new_nr_bufs;
ASSERT(blocksize > 0);
#define MINBUFS 10
assert(blocksize > 0);
assert(bufs >= MINBUFS);
for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++)
if(bp->b_count != 0) panic("change blocksize with buffer in use");
@ -516,10 +502,49 @@ void set_blocksize(unsigned int blocksize, u32_t blocks,
for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++)
if (rip->i_count > 0) panic("change blocksize with inode in use");
new_nr_bufs = fs_bufs_heuristic(10, blocks, freeblocks, blocksize, majordev);
buf_pool(bufs);
buf_pool(new_nr_bufs);
fs_block_size = blocksize;
super_start = SUPER_BLOCK_BYTES / fs_block_size;
super_end = (SUPER_BLOCK_BYTES + _MIN_BLOCK_SIZE - 1) / fs_block_size;
}
/*===========================================================================*
* bufs_heuristic *
*===========================================================================*/
static int bufs_heuristic(struct super_block *sp)
{
u32_t btotal, bfree;
btotal = sp->s_blocks_count;
bfree = sp->s_free_blocks_count;
return fs_bufs_heuristic(MINBUFS, btotal, bfree,
sp->s_block_size, major(sp->s_dev));
}
/*===========================================================================*
* set_blocksize *
*===========================================================================*/
void set_blocksize(struct super_block *sp)
{
int bufs;
cache_resize(sp->s_block_size, MINBUFS);
bufs = bufs_heuristic(sp);
cache_resize(sp->s_block_size, bufs);
/* Decide whether to use seconday cache or not.
* Only do this if
* - it's available, and
* - use of it hasn't been disabled for this fs, and
* - our main FS device isn't a memory device
*/
vmcache = 0;
if(vm_forgetblock(VM_BLOCKID_NONE) != ENOSYS &&
may_use_vmcache && major(sp->s_dev) != MEMORY_MAJOR) {
vmcache = 1;
}
}
/*===========================================================================*
@ -530,12 +555,12 @@ void buf_pool(int new_nr_bufs)
/* Initialize the buffer pool. */
register struct buf *bp;
assert(new_nr_bufs > 0);
assert(new_nr_bufs >= MINBUFS);
if(nr_bufs > 0) {
assert(buf);
(void) fs_sync();
for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++) {
for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++) {
if(bp->bp) {
assert(bp->b_bytes > 0);
free_contig(bp->bp, bp->b_bytes);
@ -568,11 +593,12 @@ void buf_pool(int new_nr_bufs)
bp->bp = NULL;
bp->b_bytes = 0;
}
buf[0].b_prev = NULL;
buf[nr_bufs - 1].b_next = NULL;
front->b_prev = NULL;
rear->b_next = NULL;
for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++) bp->b_hash = bp->b_next;
buf_hash[0] = front;
vm_forgetblocks();
}

View File

@ -107,17 +107,14 @@ int fs_readsuper()
}
if (superblock->s_state == EXT2_ERROR_FS) {
printf("ext2: filesystem wasn't cleanly unmounted previous time\n");
printf("ext2: filesystem wasn't cleanly unmounted last time\n");
superblock->s_dev = NO_DEV;
bdev_close(fs_dev);
return(EINVAL);
}
set_blocksize(superblock->s_block_size,
superblock->s_blocks_count,
superblock->s_free_blocks_count,
major(fs_dev));
set_blocksize(superblock);
/* Get the root inode of the mounted file system. */
if ( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL) {

View File

@ -21,8 +21,7 @@ void flushall(dev_t dev);
struct buf *get_block(dev_t dev, block_t block,int only_search);
void invalidate(dev_t device);
void put_block(struct buf *bp, int block_type);
void set_blocksize(unsigned int blocksize, u32_t blocks, u32_t
freeblocks, dev_t major);
void set_blocksize(struct super_block *sp);
void rw_scattered(dev_t dev, struct buf **bufq, int bufqsize, int
rw_flag);

View File

@ -399,7 +399,7 @@ void read_ahead()
rdahed_inode = NULL; /* turn off read ahead */
if ( (b = read_map(rip, rdahedpos)) == NO_BLOCK) return; /* at EOF */
assert(rdahedpos > 0); /* So we can safely cast it to unsigned below */
assert(rdahedpos >= 0); /* So we can safely cast it to unsigned below */
bp = rahead(rip, b, cvul64((unsigned long) rdahedpos), block_size);
put_block(bp, PARTIAL_DATA_BLOCK);