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