From 48237f1730e944cc5d12ec77c675082e943780ba Mon Sep 17 00:00:00 2001 From: Thomas Veerman Date: Thu, 26 Jul 2012 15:20:16 +0000 Subject: [PATCH] ext2: use new secondary cache method This gets rid of the ! emitted by VM when using ext2 --- servers/ext2/cache.c | 82 +++++++++++++++++++++++++++++--------------- servers/ext2/mount.c | 7 ++-- servers/ext2/proto.h | 3 +- servers/ext2/read.c | 2 +- 4 files changed, 58 insertions(+), 36 deletions(-) diff --git a/servers/ext2/cache.c b/servers/ext2/cache.c index 149267e32..b0bc1d3f3 100644 --- a/servers/ext2/cache.c +++ b/servers/ext2/cache.c @@ -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(); } + diff --git a/servers/ext2/mount.c b/servers/ext2/mount.c index e5daa22c2..c421c28a0 100644 --- a/servers/ext2/mount.c +++ b/servers/ext2/mount.c @@ -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) { diff --git a/servers/ext2/proto.h b/servers/ext2/proto.h index 54a75c43e..4552244ac 100644 --- a/servers/ext2/proto.h +++ b/servers/ext2/proto.h @@ -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); diff --git a/servers/ext2/read.c b/servers/ext2/read.c index de812e680..0aaa13773 100644 --- a/servers/ext2/read.c +++ b/servers/ext2/read.c @@ -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); -- 2.44.0