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