Make VM fix up memory for kernel that crosses region boundaries
[minix.git] / servers / vm / vfs.c
blob9f8d34899838fc7a44c73810f56d0d9684b4ddbc
2 #define _SYSTEM 1
4 #define VERBOSE 0
6 #include <minix/callnr.h>
7 #include <minix/com.h>
8 #include <minix/config.h>
9 #include <minix/const.h>
10 #include <minix/ds.h>
11 #include <minix/endpoint.h>
12 #include <minix/keymap.h>
13 #include <minix/minlib.h>
14 #include <minix/type.h>
15 #include <minix/ipc.h>
16 #include <minix/sysutil.h>
17 #include <minix/syslib.h>
18 #include <minix/safecopies.h>
19 #include <minix/bitmap.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <env.h>
24 #include <stdio.h>
26 #include "glo.h"
27 #include "proto.h"
28 #include "util.h"
30 /*===========================================================================*
31 * register_callback *
32 *===========================================================================*/
33 PRIVATE void register_callback(struct vmproc *for_who, callback_t callback,
34 int callback_type)
36 if(for_who->vm_callback) {
37 vm_panic("register_callback: callback already registered",
38 for_who->vm_callback_type);
40 for_who->vm_callback = callback;
41 for_who->vm_callback_type = callback_type;
43 return;
46 /*===========================================================================*
47 * vfs_open *
48 *===========================================================================*/
49 PUBLIC int vfs_open(struct vmproc *for_who, callback_t callback,
50 cp_grant_id_t filename_gid, int filename_len, int flags, int mode)
52 static message m;
53 int r;
55 register_callback(for_who, callback, VM_VFS_REPLY_OPEN);
57 m.m_type = VM_VFS_OPEN;
58 m.VMVO_NAME_GRANT = filename_gid;
59 m.VMVO_NAME_LENGTH = filename_len;
60 m.VMVO_FLAGS = flags;
61 m.VMVO_MODE = mode;
62 m.VMVO_ENDPOINT = for_who->vm_endpoint;
64 if((r=asynsend(VFS_PROC_NR, &m)) != OK) {
65 vm_panic("vfs_open: asynsend failed", r);
68 return r;
71 /*===========================================================================*
72 * vfs_close *
73 *===========================================================================*/
74 PUBLIC int vfs_close(struct vmproc *for_who, callback_t callback, int fd)
76 static message m;
77 int r;
79 register_callback(for_who, callback, VM_VFS_REPLY_CLOSE);
81 m.m_type = VM_VFS_CLOSE;
82 m.VMVC_ENDPOINT = for_who->vm_endpoint;
83 m.VMVC_FD = fd;
85 if((r=asynsend(VFS_PROC_NR, &m)) != OK) {
86 vm_panic("vfs_close: asynsend failed", r);
89 return r;
92 /*===========================================================================*
93 * do_vfs_reply *
94 *===========================================================================*/
95 PUBLIC int do_vfs_reply(message *m)
97 /* Reply to a request has been received from vfs. Handle it. First verify
98 * and look up which process, identified by endpoint, this is about.
99 * Then call the callback function that was registered when the request
100 * was done. Return result to vfs.
102 endpoint_t ep;
103 struct vmproc *vmp;
104 int procno;
105 callback_t cb;
106 ep = m->VMV_ENDPOINT;
107 if(vm_isokendpt(ep, &procno) != OK) {
108 printf("VM:do_vfs_reply: reply %d about invalid endpoint %d\n",
109 m->m_type, ep);
110 vm_panic("do_vfs_reply: invalid endpoint from vfs", NO_NUM);
112 vmp = &vmproc[procno];
113 if(!vmp->vm_callback) {
114 printf("VM:do_vfs_reply: reply %d: endpoint %d not waiting\n",
115 m->m_type, ep);
116 vm_panic("do_vfs_reply: invalid endpoint from vfs", NO_NUM);
118 if(vmp->vm_callback_type != m->m_type) {
119 printf("VM:do_vfs_reply: reply %d unexpected for endpoint %d\n"
120 " (expecting %d)\n", m->m_type, ep, vmp->vm_callback_type);
121 vm_panic("do_vfs_reply: invalid reply from vfs", NO_NUM);
123 if(vmp->vm_flags & VMF_EXITING) {
124 /* This is not fatal or impossible, but the callback
125 * function has to realize it shouldn't do any PM or
126 * VFS calls for this process.
128 printf("VM:do_vfs_reply: reply %d for EXITING endpoint %d\n",
129 m->m_type, ep);
132 /* All desired callback state has been used, so save and reset
133 * the callback. This allows the callback to register another
134 * one.
136 cb = vmp->vm_callback;
137 vmp->vm_callback = NULL;
138 cb(vmp, m);
139 return SUSPEND;