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 13 14 /* Declare some local functions. */ 15 static void get_work(message *m_in); 16 static void reply(endpoint_t who, message *m_out); 17 18 /* SEF functions and variables. */ 19 static void sef_local_startup(void); 20 static int sef_cb_init_fresh(int type, sef_init_info_t *info); 21 static void sef_cb_signal_handler(int signo); 22 23 /*===========================================================================* 24 * main * 25 *===========================================================================*/ 26 int main(int argc, char *argv[]) 27 { 28 /* This is the main routine of this service. The main loop consists of 29 * three major activities: getting new work, processing the work, and 30 * sending the reply. The loop never terminates, unless a panic occurs. 31 */ 32 int error = OK, ind, transid; 33 34 /* SEF local startup. */ 35 env_setargs(argc, argv); 36 sef_local_startup(); 37 38 while(!unmountdone || !exitsignaled) { 39 endpoint_t src; 40 41 /* Wait for request message. */ 42 get_work(&fs_m_in); 43 44 transid = TRNS_GET_ID(fs_m_in.m_type); 45 fs_m_in.m_type = TRNS_DEL_ID(fs_m_in.m_type); 46 if (fs_m_in.m_type == 0) { 47 assert(!IS_VFS_FS_TRANSID(transid)); 48 fs_m_in.m_type = transid; /* Backwards compat. */ 49 transid = 0; 50 } else 51 assert(IS_VFS_FS_TRANSID(transid)); 52 53 src = fs_m_in.m_source; 54 caller_uid = INVAL_UID; /* To trap errors */ 55 caller_gid = INVAL_GID; 56 req_nr = fs_m_in.m_type; 57 58 if (req_nr < FS_BASE) { 59 fs_m_in.m_type += FS_BASE; 60 req_nr = fs_m_in.m_type; 61 } 62 ind = req_nr - FS_BASE; 63 64 if (ind < 0 || ind >= NREQS) { 65 printf("MFS: bad request %d from %d\n", req_nr, src); 66 printf("ind = %d\n", ind); 67 error = EINVAL; 68 } else { 69 error = (*fs_call_vec[ind])(); 70 /*cch_check();*/ 71 } 72 73 fs_m_out.m_type = error; 74 if (IS_VFS_FS_TRANSID(transid)) { 75 /* If a transaction ID was set, reset it */ 76 fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, transid); 77 } 78 reply(src, &fs_m_out); 79 } 80 81 return(OK); 82 } 83 84 /*===========================================================================* 85 * sef_local_startup * 86 *===========================================================================*/ 87 static void sef_local_startup() 88 { 89 /* Register init callbacks. */ 90 sef_setcb_init_fresh(sef_cb_init_fresh); 91 sef_setcb_init_restart(sef_cb_init_fail); 92 93 /* No live update support for now. */ 94 95 /* Register signal callbacks. */ 96 sef_setcb_signal_handler(sef_cb_signal_handler); 97 98 /* Let SEF perform startup. */ 99 sef_startup(); 100 } 101 102 /*===========================================================================* 103 * sef_cb_init_fresh * 104 *===========================================================================*/ 105 static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) 106 { 107 /* Initialize the Minix file server. */ 108 int i; 109 110 lmfs_may_use_vmcache(1); 111 112 /* Init inode table */ 113 for (i = 0; i < NR_INODES; ++i) { 114 inode[i].i_count = 0; 115 cch[i] = 0; 116 } 117 118 init_inode_cache(); 119 120 lmfs_buf_pool(DEFAULT_NR_BUFS); 121 122 return(OK); 123 } 124 125 /*===========================================================================* 126 * sef_cb_signal_handler * 127 *===========================================================================*/ 128 static void sef_cb_signal_handler(int signo) 129 { 130 /* Only check for termination signal, ignore anything else. */ 131 if (signo != SIGTERM) return; 132 133 exitsignaled = 1; 134 (void) fs_sync(); 135 136 /* If unmounting has already been performed, exit immediately. 137 * We might not get another message. 138 */ 139 if (unmountdone) exit(0); 140 } 141 142 /*===========================================================================* 143 * get_work * 144 *===========================================================================*/ 145 static void get_work(m_in) 146 message *m_in; /* pointer to message */ 147 { 148 int r, srcok = 0; 149 endpoint_t src; 150 151 do { 152 if ((r = sef_receive(ANY, m_in)) != OK) /* wait for message */ 153 panic("sef_receive failed: %d", r); 154 src = m_in->m_source; 155 156 if(src == VFS_PROC_NR) { 157 if(unmountdone) 158 printf("MFS: unmounted: unexpected message from FS\n"); 159 else 160 srcok = 1; /* Normal FS request. */ 161 162 } else 163 printf("MFS: unexpected source %d\n", src); 164 } while(!srcok); 165 166 assert((src == VFS_PROC_NR && !unmountdone)); 167 } 168 169 170 /*===========================================================================* 171 * reply * 172 *===========================================================================*/ 173 static void reply( 174 endpoint_t who, 175 message *m_out /* report result */ 176 ) 177 { 178 if (OK != ipc_send(who, m_out)) /* send the message */ 179 printf("MFS(%d) was unable to send reply\n", sef_self()); 180 } 181 182 183 #if 0 184 /*===========================================================================* 185 * cch_check * 186 *===========================================================================*/ 187 static void cch_check(void) 188 { 189 int i; 190 191 for (i = 0; i < NR_INODES; ++i) { 192 if (inode[i].i_count != cch[i] && req_nr != REQ_GETNODE && 193 req_nr != REQ_PUTNODE && req_nr != REQ_READSUPER && 194 req_nr != REQ_MOUNTPOINT && req_nr != REQ_UNMOUNT && 195 req_nr != REQ_SYNC && req_nr != REQ_LOOKUP) { 196 printf("MFS(%d) inode(%lu) cc: %d req_nr: %d\n", sef_self(), 197 inode[i].i_num, inode[i].i_count - cch[i], req_nr); 198 } 199 200 cch[i] = inode[i].i_count; 201 } 202 } 203 #endif 204 205