1 2 #include "fsdriver.h" 3 4 /* Library-local variables. */ 5 dev_t fsdriver_device; 6 ino_t fsdriver_root; 7 int fsdriver_mounted = FALSE; 8 9 static int fsdriver_running; 10 11 /* 12 * Process an incoming VFS request, and send a reply. If the message is not 13 * a file system request from VFS, pass it on to the generic message handler. 14 * Multithreaded file systems should indicate that the reply is to be sent to 15 * VFS asynchronously. 16 */ 17 void 18 fsdriver_process(const struct fsdriver * __restrict fdp, 19 const message * __restrict m_ptr, int ipc_status, int asyn_reply) 20 { 21 message m_out; 22 unsigned int call_nr; 23 int r, transid; 24 25 /* Is this a file system request at all? */ 26 if (is_ipc_notify(ipc_status) || m_ptr->m_source != VFS_PROC_NR) { 27 if (fdp->fdr_other != NULL) 28 fdp->fdr_other(m_ptr, ipc_status); 29 30 return; /* do not send a reply */ 31 } 32 33 /* Call the appropriate function. */ 34 transid = TRNS_GET_ID(m_ptr->m_type); 35 call_nr = TRNS_DEL_ID(m_ptr->m_type); 36 37 memset(&m_out, 0, sizeof(m_out)); 38 39 if (fsdriver_mounted || call_nr == REQ_READSUPER) { 40 call_nr -= FS_BASE; /* unsigned; wrapping is intended */ 41 42 if (call_nr < NREQS && fsdriver_callvec[call_nr] != NULL) 43 r = (fsdriver_callvec[call_nr])(fdp, m_ptr, &m_out); 44 else 45 r = ENOSYS; 46 } else 47 r = EINVAL; 48 49 /* Send a reply. */ 50 m_out.m_type = TRNS_ADD_ID(r, transid); 51 52 if (asyn_reply) 53 r = asynsend(m_ptr->m_source, &m_out); 54 else 55 r = ipc_send(m_ptr->m_source, &m_out); 56 57 if (r != OK) 58 printf("fsdriver: sending reply failed (%d)\n", r); 59 60 if (fdp->fdr_postcall != NULL) 61 fdp->fdr_postcall(); 62 } 63 64 /* 65 * Terminate the file server as soon as the file system has been unmounted. 66 */ 67 void 68 fsdriver_terminate(void) 69 { 70 71 fsdriver_running = FALSE; 72 73 sef_cancel(); 74 } 75 76 /* 77 * Main program of any file server task. 78 */ 79 void 80 fsdriver_task(struct fsdriver * fdp) 81 { 82 message mess; 83 int r, ipc_status; 84 85 fsdriver_running = TRUE; 86 87 while (fsdriver_running || fsdriver_mounted) { 88 if ((r = sef_receive_status(ANY, &mess, &ipc_status)) != OK) { 89 if (r == EINTR) 90 continue; /* sef_cancel() was called */ 91 92 panic("fsdriver: sef_receive_status failed: %d", r); 93 } 94 95 fsdriver_process(fdp, &mess, ipc_status, FALSE /*asyn_reply*/); 96 } 97 } 98