summaryrefslogtreecommitdiff
path: root/minix/lib/libsys/vm_cache.c
blob: c91e4e396c12665ff553361dfeaf428c5bc7cb18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

#include "syslib.h"

#include <string.h>
#include <assert.h>

#include <sys/mman.h>

#include <minix/vm.h>
#include <minix/sysutil.h>

#include <machine/param.h>
#include <machine/vmparam.h>

static int vm_cachecall(message *m, int call, void *addr, dev_t dev,
	off_t dev_offset, ino_t ino, off_t ino_offset, u32_t *flags,
	int blocksize, int setflags)
{
    if(blocksize % PAGE_SIZE)
    	panic("blocksize %d should be a multiple of pagesize %d\n",
		blocksize, PAGE_SIZE);

    if(ino_offset % PAGE_SIZE)
    	panic("inode offset %lld should be a multiple of pagesize %d\n",
		ino_offset, PAGE_SIZE);

    if(dev_offset % PAGE_SIZE)
    	panic("dev offset offset %lld should be a multiple of pagesize %d\n",
		dev_offset, PAGE_SIZE);

    memset(m, 0, sizeof(*m));

    assert(dev != NO_DEV);

    m->m_vmmcp.dev_offset = dev_offset;
    m->m_vmmcp.ino_offset = ino_offset;
    m->m_vmmcp.ino = ino;
    m->m_vmmcp.block = addr;
    m->m_vmmcp.flags_ptr = flags;
    m->m_vmmcp.dev = dev;
    m->m_vmmcp.pages = blocksize / PAGE_SIZE;
    m->m_vmmcp.flags = setflags;

    return _taskcall(VM_PROC_NR, call, m);
}

void *vm_map_cacheblock(dev_t dev, off_t dev_offset,
	ino_t ino, off_t ino_offset, u32_t *flags, int blocksize)
{
	message m;

	if(vm_cachecall(&m, VM_MAPCACHEPAGE, NULL, dev, dev_offset,
		ino, ino_offset, flags, blocksize, 0) != OK)
		return MAP_FAILED;

	return m.m_vmmcp_reply.addr;
}

int 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)
{
	message m;

	return vm_cachecall(&m, VM_SETCACHEPAGE, block, dev, dev_offset,
		ino, ino_offset, flags, blocksize, setflags);
}

int vm_forget_cacheblock(dev_t dev, off_t dev_offset, int blocksize)
{
	message m;

	return vm_cachecall(&m, VM_FORGETCACHEPAGE, NULL, dev, dev_offset,
		VMC_NO_INODE, 0, 0, blocksize, 0);
}

int
vm_clear_cache(dev_t dev)
{
	message m;

	assert(dev != NO_DEV);

	memset(&m, 0, sizeof(m));

	m.m_vmmcp.dev = dev;

	return _taskcall(VM_PROC_NR, VM_CLEARCACHE, &m);
}