xref: /minix3/minix/tests/test72.c (revision 6c46a77d9509a6aefda1522eee2103e194ced4b3)
1433d6423SLionel Sambuc /* Test 72 - libminixfs unit test.
2433d6423SLionel Sambuc  *
3433d6423SLionel Sambuc  * Exercise the caching functionality of libminixfs in isolation.
4433d6423SLionel Sambuc  */
5433d6423SLionel Sambuc 
6433d6423SLionel Sambuc #define _MINIX_SYSTEM
7433d6423SLionel Sambuc 
8433d6423SLionel Sambuc #include <minix/sysutil.h>
9433d6423SLionel Sambuc #include <minix/syslib.h>
10433d6423SLionel Sambuc #include <minix/vm.h>
11433d6423SLionel Sambuc #include <minix/bdev.h>
12433d6423SLionel Sambuc #include <sys/types.h>
13433d6423SLionel Sambuc #include <sys/mman.h>
14433d6423SLionel Sambuc #include <sys/ioc_memory.h>
15433d6423SLionel Sambuc #include <stdio.h>
16433d6423SLionel Sambuc #include <stdarg.h>
17433d6423SLionel Sambuc #include <assert.h>
18433d6423SLionel Sambuc #include <string.h>
19433d6423SLionel Sambuc #include <stdlib.h>
20433d6423SLionel Sambuc #include <unistd.h>
21433d6423SLionel Sambuc #include <fcntl.h>
22433d6423SLionel Sambuc #include <math.h>
23ebd3c067SDavid van Moolenbroek #include <minix/libminixfs.h>
24433d6423SLionel Sambuc 
25433d6423SLionel Sambuc int max_error = 0;
26433d6423SLionel Sambuc 
27433d6423SLionel Sambuc #include "common.h"
28433d6423SLionel Sambuc #include "testcache.h"
29433d6423SLionel Sambuc 
30433d6423SLionel Sambuc #define MYMAJOR	40	/* doesn't really matter, shouldn't be NO_DEV though */
31433d6423SLionel Sambuc 
32433d6423SLionel Sambuc #define MYDEV	makedev(MYMAJOR, 1)
33433d6423SLionel Sambuc 
34433d6423SLionel Sambuc static int curblocksize = -1;
35433d6423SLionel Sambuc 
36433d6423SLionel Sambuc static char *writtenblocks[MAXBLOCKS];
37433d6423SLionel Sambuc 
38433d6423SLionel Sambuc /* Some functions used by testcache.c */
39433d6423SLionel Sambuc 
40433d6423SLionel Sambuc int
dowriteblock(int b,int blocksize,u32_t seed,char * data)41433d6423SLionel Sambuc dowriteblock(int b, int blocksize, u32_t seed, char *data)
42433d6423SLionel Sambuc {
43433d6423SLionel Sambuc 	struct buf *bp;
44*6c46a77dSDavid van Moolenbroek 	int r;
45433d6423SLionel Sambuc 
46433d6423SLionel Sambuc 	assert(blocksize == curblocksize);
47433d6423SLionel Sambuc 
48*6c46a77dSDavid van Moolenbroek 	if ((r = lmfs_get_block(&bp, MYDEV, b, NORMAL)) != 0) {
49433d6423SLionel Sambuc 		e(30);
50433d6423SLionel Sambuc 		return 0;
51433d6423SLionel Sambuc 	}
52433d6423SLionel Sambuc 
53433d6423SLionel Sambuc 	memcpy(bp->data, data, blocksize);
54433d6423SLionel Sambuc 
55433d6423SLionel Sambuc 	lmfs_markdirty(bp);
56433d6423SLionel Sambuc 
570314acfbSDavid van Moolenbroek 	lmfs_put_block(bp);
58433d6423SLionel Sambuc 
59433d6423SLionel Sambuc 	return blocksize;
60433d6423SLionel Sambuc }
61433d6423SLionel Sambuc 
62433d6423SLionel Sambuc int
readblock(int b,int blocksize,u32_t seed,char * data)63433d6423SLionel Sambuc readblock(int b, int blocksize, u32_t seed, char *data)
64433d6423SLionel Sambuc {
65433d6423SLionel Sambuc 	struct buf *bp;
66*6c46a77dSDavid van Moolenbroek 	int r;
67433d6423SLionel Sambuc 
68433d6423SLionel Sambuc 	assert(blocksize == curblocksize);
69433d6423SLionel Sambuc 
70*6c46a77dSDavid van Moolenbroek 	if ((r = lmfs_get_block(&bp, MYDEV, b, NORMAL)) != 0) {
71433d6423SLionel Sambuc 		e(30);
72433d6423SLionel Sambuc 		return 0;
73433d6423SLionel Sambuc 	}
74433d6423SLionel Sambuc 
75433d6423SLionel Sambuc 	memcpy(data, bp->data, blocksize);
76433d6423SLionel Sambuc 
770314acfbSDavid van Moolenbroek 	lmfs_put_block(bp);
78433d6423SLionel Sambuc 
79433d6423SLionel Sambuc 	return blocksize;
80433d6423SLionel Sambuc }
81433d6423SLionel Sambuc 
testend(void)82433d6423SLionel Sambuc void testend(void)
83433d6423SLionel Sambuc {
84433d6423SLionel Sambuc 	int i;
85433d6423SLionel Sambuc 	for(i = 0; i < MAXBLOCKS; i++) {
86433d6423SLionel Sambuc 		if(writtenblocks[i]) {
87433d6423SLionel Sambuc 			free(writtenblocks[i]);
88433d6423SLionel Sambuc 			writtenblocks[i] = NULL;
89433d6423SLionel Sambuc 		}
90433d6423SLionel Sambuc 	}
91433d6423SLionel Sambuc }
92433d6423SLionel Sambuc 
93433d6423SLionel Sambuc /* Fake some libminixfs client functions */
94433d6423SLionel Sambuc 
allocate(int b)95433d6423SLionel Sambuc static void allocate(int b)
96433d6423SLionel Sambuc {
97433d6423SLionel Sambuc 	assert(curblocksize > 0);
98433d6423SLionel Sambuc 	assert(!writtenblocks[b]);
99433d6423SLionel Sambuc 	if(!(writtenblocks[b] = calloc(1, curblocksize))) {
100433d6423SLionel Sambuc 		fprintf(stderr, "out of memory allocating block %d\n", b);
101433d6423SLionel Sambuc 		exit(1);
102433d6423SLionel Sambuc 	}
103433d6423SLionel Sambuc }
104433d6423SLionel Sambuc 
105433d6423SLionel Sambuc /* Fake some libblockdriver functions */
106433d6423SLionel Sambuc ssize_t
bdev_gather(dev_t dev,u64_t pos,iovec_t * vec,int count,int flags)107433d6423SLionel Sambuc bdev_gather(dev_t dev, u64_t pos, iovec_t *vec, int count, int flags)
108433d6423SLionel Sambuc {
10935118b0aSDavid van Moolenbroek 	int i, block;
11035118b0aSDavid van Moolenbroek 	size_t size, block_off;
111433d6423SLionel Sambuc 	ssize_t tot = 0;
112433d6423SLionel Sambuc 	assert(dev == MYDEV);
113433d6423SLionel Sambuc 	assert(curblocksize > 0);
114433d6423SLionel Sambuc 	assert(!(pos % curblocksize));
115433d6423SLionel Sambuc 	for(i = 0; i < count; i++) {
116433d6423SLionel Sambuc 		char *data = (char *) vec[i].iov_addr;
117433d6423SLionel Sambuc 		block = pos / curblocksize;
11835118b0aSDavid van Moolenbroek 		block_off = (size_t)(pos % curblocksize);
11935118b0aSDavid van Moolenbroek 		size = vec[i].iov_size;
12035118b0aSDavid van Moolenbroek 		assert(size == PAGE_SIZE);
121433d6423SLionel Sambuc 		assert(block >= 0);
122433d6423SLionel Sambuc 		assert(block < MAXBLOCKS);
12335118b0aSDavid van Moolenbroek 		assert(block_off + size <= curblocksize);
124433d6423SLionel Sambuc 		if(!writtenblocks[block]) {
125433d6423SLionel Sambuc 			allocate(block);
126433d6423SLionel Sambuc 		}
12735118b0aSDavid van Moolenbroek 		memcpy(data, writtenblocks[block] + block_off, size);
12835118b0aSDavid van Moolenbroek 		pos += size;
12935118b0aSDavid van Moolenbroek 		tot += size;
130433d6423SLionel Sambuc 	}
131433d6423SLionel Sambuc 
132433d6423SLionel Sambuc 	return tot;
133433d6423SLionel Sambuc }
134433d6423SLionel Sambuc 
135433d6423SLionel Sambuc ssize_t
bdev_scatter(dev_t dev,u64_t pos,iovec_t * vec,int count,int flags)136433d6423SLionel Sambuc bdev_scatter(dev_t dev, u64_t pos, iovec_t *vec, int count, int flags)
137433d6423SLionel Sambuc {
138433d6423SLionel Sambuc 	int i, block;
13935118b0aSDavid van Moolenbroek 	size_t size, block_off;
140433d6423SLionel Sambuc 	ssize_t tot = 0;
141433d6423SLionel Sambuc 	assert(dev == MYDEV);
142433d6423SLionel Sambuc 	assert(curblocksize > 0);
143433d6423SLionel Sambuc 	assert(!(pos % curblocksize));
144433d6423SLionel Sambuc 	for(i = 0; i < count; i++) {
145433d6423SLionel Sambuc 		char *data = (char *) vec[i].iov_addr;
14635118b0aSDavid van Moolenbroek 		block = pos / curblocksize;
14735118b0aSDavid van Moolenbroek 		block_off = (size_t)(pos % curblocksize);
14835118b0aSDavid van Moolenbroek 		size = vec[i].iov_size;
14935118b0aSDavid van Moolenbroek 		assert(size == PAGE_SIZE);
150433d6423SLionel Sambuc 		assert(block >= 0);
151433d6423SLionel Sambuc 		assert(block < MAXBLOCKS);
15235118b0aSDavid van Moolenbroek 		assert(block_off + size <= curblocksize);
153433d6423SLionel Sambuc 		if(!writtenblocks[block]) {
154433d6423SLionel Sambuc 			allocate(block);
155433d6423SLionel Sambuc 		}
15635118b0aSDavid van Moolenbroek 		memcpy(writtenblocks[block] + block_off, data, size);
15735118b0aSDavid van Moolenbroek 		pos += size;
15835118b0aSDavid van Moolenbroek 		tot += size;
159433d6423SLionel Sambuc 	}
160433d6423SLionel Sambuc 
161433d6423SLionel Sambuc 	return tot;
162433d6423SLionel Sambuc }
163433d6423SLionel Sambuc 
164433d6423SLionel Sambuc ssize_t
bdev_read(dev_t dev,u64_t pos,char * data,size_t count,int flags)165433d6423SLionel Sambuc bdev_read(dev_t dev, u64_t pos, char *data, size_t count, int flags)
166433d6423SLionel Sambuc {
167433d6423SLionel Sambuc 	int block;
168433d6423SLionel Sambuc 
169433d6423SLionel Sambuc 	assert(dev == MYDEV);
170433d6423SLionel Sambuc 	assert(curblocksize > 0);
171433d6423SLionel Sambuc 	assert(!(pos % curblocksize));
172433d6423SLionel Sambuc 	assert(count > 0);
173433d6423SLionel Sambuc 	assert(!(count % curblocksize));
17435118b0aSDavid van Moolenbroek 	assert(count == PAGE_SIZE);
17535118b0aSDavid van Moolenbroek 	assert(curblocksize == PAGE_SIZE);
176433d6423SLionel Sambuc 
177433d6423SLionel Sambuc 	block = pos / curblocksize;
178433d6423SLionel Sambuc 	assert(block >= 0);
179433d6423SLionel Sambuc 	assert(block < MAXBLOCKS);
180433d6423SLionel Sambuc 	if(!writtenblocks[block]) {
181433d6423SLionel Sambuc 		allocate(block);
182433d6423SLionel Sambuc 	}
183433d6423SLionel Sambuc 	memcpy(data, writtenblocks[block], curblocksize);
18435118b0aSDavid van Moolenbroek 	return count;
185433d6423SLionel Sambuc }
186433d6423SLionel Sambuc 
187433d6423SLionel Sambuc /* Fake some libsys functions */
188433d6423SLionel Sambuc 
189433d6423SLionel Sambuc __dead void
panic(const char * fmt,...)190433d6423SLionel Sambuc panic(const char *fmt, ...)
191433d6423SLionel Sambuc {
192433d6423SLionel Sambuc 	va_list va;
193433d6423SLionel Sambuc 	va_start(va, fmt);
194433d6423SLionel Sambuc 	vfprintf(stderr, fmt, va);
195433d6423SLionel Sambuc 	va_end(va);
196433d6423SLionel Sambuc 
197433d6423SLionel Sambuc 	exit(1);
198433d6423SLionel Sambuc }
199433d6423SLionel Sambuc 
200433d6423SLionel Sambuc int
vm_info_stats(struct vm_stats_info * vsi)201433d6423SLionel Sambuc vm_info_stats(struct vm_stats_info *vsi)
202433d6423SLionel Sambuc {
203433d6423SLionel Sambuc 	return ENOSYS;
204433d6423SLionel Sambuc }
205433d6423SLionel Sambuc 
206433d6423SLionel Sambuc void
util_stacktrace(void)207433d6423SLionel Sambuc util_stacktrace(void)
208433d6423SLionel Sambuc {
209433d6423SLionel Sambuc 	fprintf(stderr, "fake stacktrace\n");
210433d6423SLionel Sambuc }
211433d6423SLionel Sambuc 
alloc_contig(size_t len,int flags,phys_bytes * phys)212433d6423SLionel Sambuc void *alloc_contig(size_t len, int flags, phys_bytes *phys)
213433d6423SLionel Sambuc {
214433d6423SLionel Sambuc 	return malloc(len);
215433d6423SLionel Sambuc }
216433d6423SLionel Sambuc 
free_contig(void * addr,size_t len)217433d6423SLionel Sambuc int free_contig(void *addr, size_t len)
218433d6423SLionel Sambuc {
219433d6423SLionel Sambuc 	free(addr);
220433d6423SLionel Sambuc 	return 0;
221433d6423SLionel Sambuc }
222433d6423SLionel Sambuc 
sqrt_approx(u32_t v)223433d6423SLionel Sambuc u32_t sqrt_approx(u32_t v)
224433d6423SLionel Sambuc {
225433d6423SLionel Sambuc 	return (u32_t) sqrt(v);
226433d6423SLionel Sambuc }
227433d6423SLionel Sambuc 
vm_set_cacheblock(void * block,dev_t dev,off_t dev_offset,ino_t ino,off_t ino_offset,u32_t * flags,int blocksize,int setflags)228433d6423SLionel Sambuc int vm_set_cacheblock(void *block, dev_t dev, off_t dev_offset,
229e321f655SDavid van Moolenbroek         ino_t ino, off_t ino_offset, u32_t *flags, int blocksize, int setflags)
230433d6423SLionel Sambuc {
231433d6423SLionel Sambuc 	return ENOSYS;
232433d6423SLionel Sambuc }
233433d6423SLionel Sambuc 
vm_map_cacheblock(dev_t dev,off_t dev_offset,ino_t ino,off_t ino_offset,u32_t * flags,int blocksize)234433d6423SLionel Sambuc void *vm_map_cacheblock(dev_t dev, off_t dev_offset,
235433d6423SLionel Sambuc         ino_t ino, off_t ino_offset, u32_t *flags, int blocksize)
236433d6423SLionel Sambuc {
237433d6423SLionel Sambuc 	return MAP_FAILED;
238433d6423SLionel Sambuc }
239433d6423SLionel Sambuc 
vm_forget_cacheblock(dev_t dev,off_t dev_offset,int blocksize)240e94f856bSDavid van Moolenbroek int vm_forget_cacheblock(dev_t dev, off_t dev_offset, int blocksize)
241e94f856bSDavid van Moolenbroek {
242e94f856bSDavid van Moolenbroek 	return 0;
243e94f856bSDavid van Moolenbroek }
244e94f856bSDavid van Moolenbroek 
vm_clear_cache(dev_t dev)245433d6423SLionel Sambuc int vm_clear_cache(dev_t dev)
246433d6423SLionel Sambuc {
247433d6423SLionel Sambuc 	return 0;
248433d6423SLionel Sambuc }
249433d6423SLionel Sambuc 
250433d6423SLionel Sambuc int
main(int argc,char * argv[])251433d6423SLionel Sambuc main(int argc, char *argv[])
252433d6423SLionel Sambuc {
253f0188976SDavid van Moolenbroek 	size_t newblocksize;
254433d6423SLionel Sambuc 	int wss, cs, n = 0, p;
255433d6423SLionel Sambuc 
256433d6423SLionel Sambuc #define ITER 3
257433d6423SLionel Sambuc #define BLOCKS 200
258433d6423SLionel Sambuc 
259433d6423SLionel Sambuc 	start(72);
260433d6423SLionel Sambuc 
261433d6423SLionel Sambuc 	lmfs_setquiet(1);
262433d6423SLionel Sambuc 
263433d6423SLionel Sambuc 	/* Can the cache handle differently sized blocks? */
264433d6423SLionel Sambuc 
265433d6423SLionel Sambuc 	for(p = 1; p <= 3; p++) {
266f0188976SDavid van Moolenbroek 		/* Do not update curblocksize until the cache is flushed. */
267f0188976SDavid van Moolenbroek 		newblocksize = PAGE_SIZE*p;
2680314acfbSDavid van Moolenbroek 		lmfs_set_blocksize(newblocksize);
269f0188976SDavid van Moolenbroek 		curblocksize = newblocksize;	/* now it's safe to update */
270433d6423SLionel Sambuc 		lmfs_buf_pool(BLOCKS);
271433d6423SLionel Sambuc 		if(dotest(curblocksize, BLOCKS, ITER)) e(n);
272433d6423SLionel Sambuc 		n++;
273433d6423SLionel Sambuc 	}
274433d6423SLionel Sambuc 
275433d6423SLionel Sambuc 	/* Can the cache handle various combinations of the working set
276433d6423SLionel Sambuc 	 * being larger and smaller than the cache?
277433d6423SLionel Sambuc 	 */
278433d6423SLionel Sambuc 	for(wss = 2; wss <= 3; wss++) {
279433d6423SLionel Sambuc 		int wsblocks = 10*wss*wss*wss*wss*wss;
280433d6423SLionel Sambuc 		for(cs = wsblocks/4; cs <= wsblocks*3; cs *= 1.5) {
2810314acfbSDavid van Moolenbroek 			lmfs_set_blocksize(PAGE_SIZE);
282f0188976SDavid van Moolenbroek 			curblocksize = PAGE_SIZE;	/* same as above */
283433d6423SLionel Sambuc 			lmfs_buf_pool(cs);
284433d6423SLionel Sambuc 		        if(dotest(curblocksize, wsblocks, ITER)) e(n);
285433d6423SLionel Sambuc 			n++;
286433d6423SLionel Sambuc 		}
287433d6423SLionel Sambuc 	}
288433d6423SLionel Sambuc 
289433d6423SLionel Sambuc 	quit();
290433d6423SLionel Sambuc 
291433d6423SLionel Sambuc 	return 0;
292433d6423SLionel Sambuc }
293433d6423SLionel Sambuc 
294