mfs fix by tveerman from trunk.
[minix.git] / servers / mfs / main.c
blobd935c31678e60241421e366338ec2446ead29f7b
1 #include "fs.h"
2 #include <assert.h>
3 #include <minix/callnr.h>
4 #include <signal.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <minix/dmap.h>
8 #include <minix/endpoint.h>
9 #include <minix/vfsif.h>
10 #include "buf.h"
11 #include "inode.h"
12 #include "drivers.h"
15 /* Declare some local functions. */
16 FORWARD _PROTOTYPE(void get_work, (message *m_in) );
17 FORWARD _PROTOTYPE(void cch_check, (void) );
18 FORWARD _PROTOTYPE( void reply, (endpoint_t who, message *m_out) );
20 /* SEF functions and variables. */
21 FORWARD _PROTOTYPE( void sef_local_startup, (void) );
22 FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
23 FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
25 /*===========================================================================*
26 * main *
27 *===========================================================================*/
28 PUBLIC int main(int argc, char *argv[])
30 /* This is the main routine of this service. The main loop consists of
31 * three major activities: getting new work, processing the work, and
32 * sending the reply. The loop never terminates, unless a panic occurs.
34 int error, ind;
36 /* SEF local startup. */
37 env_setargs(argc, argv);
38 sef_local_startup();
40 while(!unmountdone || !exitsignaled) {
41 endpoint_t src;
43 /* Wait for request message. */
44 get_work(&fs_m_in);
46 src = fs_m_in.m_source;
47 error = OK;
48 caller_uid = INVAL_UID; /* To trap errors */
49 caller_gid = INVAL_GID;
50 req_nr = fs_m_in.m_type;
52 if (req_nr < VFS_BASE) {
53 fs_m_in.m_type += VFS_BASE;
54 req_nr = fs_m_in.m_type;
56 ind = req_nr - VFS_BASE;
58 if (ind < 0 || ind >= NREQS) {
59 printf("mfs: bad request %d\n", req_nr);
60 printf("ind = %d\n", ind);
61 error = EINVAL;
62 } else {
63 error = (*fs_call_vec[ind])();
64 /*cch_check();*/
67 fs_m_out.m_type = error;
68 reply(src, &fs_m_out);
70 if (error == OK && rdahed_inode != NULL)
71 read_ahead(); /* do block read ahead */
76 /*===========================================================================*
77 * sef_local_startup *
78 *===========================================================================*/
79 PRIVATE void sef_local_startup()
81 /* Register init callbacks. */
82 sef_setcb_init_fresh(sef_cb_init_fresh);
83 sef_setcb_init_restart(sef_cb_init_fail);
85 /* No live update support for now. */
87 /* Register signal callbacks. */
88 sef_setcb_signal_handler(sef_cb_signal_handler);
90 /* Let SEF perform startup. */
91 sef_startup();
94 /*===========================================================================*
95 * sef_cb_init_fresh *
96 *===========================================================================*/
97 PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
99 /* Initialize the Minix file server. */
100 int i, r;
102 may_use_vmcache = 1;
104 /* Init inode table */
105 for (i = 0; i < NR_INODES; ++i) {
106 inode[i].i_count = 0;
107 cch[i] = 0;
110 init_inode_cache();
112 /* Init driver mapping */
113 for (i = 0; i < NR_DEVICES; ++i)
114 driver_endpoints[i].driver_e = NONE;
116 SELF_E = getprocnr();
117 buf_pool(DEFAULT_NR_BUFS);
118 fs_block_size = _MIN_BLOCK_SIZE;
120 fs_m_in.m_type = FS_READY;
122 if ((r = send(FS_PROC_NR, &fs_m_in)) != OK) {
123 panic("Error sending login to VFS: %d", r);
126 return(OK);
129 /*===========================================================================*
130 * sef_cb_signal_handler *
131 *===========================================================================*/
132 PRIVATE void sef_cb_signal_handler(int signo)
134 /* Only check for termination signal, ignore anything else. */
135 if (signo != SIGTERM) return;
137 exitsignaled = 1;
138 (void) fs_sync();
140 /* If unmounting has already been performed, exit immediately.
141 * We might not get another message.
143 if (unmountdone) exit(0);
146 /*===========================================================================*
147 * get_work *
148 *===========================================================================*/
149 PRIVATE void get_work(m_in)
150 message *m_in; /* pointer to message */
152 int r, srcok = 0;
153 endpoint_t src;
155 do {
156 if ((r = sef_receive(ANY, m_in)) != OK) /* wait for message */
157 panic("sef_receive failed: %d", r);
158 src = m_in->m_source;
160 if(src == VFS_PROC_NR) {
161 if(unmountdone)
162 printf("MFS: unmounted: unexpected message from FS\n");
163 else
164 srcok = 1; /* Normal FS request. */
166 } else
167 printf("MFS: unexpected source %d\n", src);
168 } while(!srcok);
170 assert((src == VFS_PROC_NR && !unmountdone));
174 /*===========================================================================*
175 * reply *
176 *===========================================================================*/
177 PRIVATE void reply(
178 endpoint_t who,
179 message *m_out /* report result */
182 if (OK != send(who, m_out)) /* send the message */
183 printf("MFS(%d) was unable to send reply\n", SELF_E);
187 /*===========================================================================*
188 * cch_check *
189 *===========================================================================*/
190 PRIVATE void cch_check(void)
192 int i;
194 for (i = 0; i < NR_INODES; ++i) {
195 if (inode[i].i_count != cch[i] && req_nr != REQ_GETNODE &&
196 req_nr != REQ_PUTNODE && req_nr != REQ_READSUPER &&
197 req_nr != REQ_MOUNTPOINT && req_nr != REQ_UNMOUNT &&
198 req_nr != REQ_SYNC && req_nr != REQ_LOOKUP) {
199 printf("MFS(%d) inode(%ul) cc: %d req_nr: %d\n", SELF_E,
200 inode[i].i_num, inode[i].i_count - cch[i], req_nr);
203 cch[i] = inode[i].i_count;