 289b04677a
			
		
	
	
		289b04677a
		
	
	
	
	
		
			
			This obviates the need for several file system implementations to remember the device on which they are mounted. Change-Id: Ida8325cf4bcf072e61761cfee34e3f7ed2d750b9
		
			
				
	
	
		
			98 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| #include "fsdriver.h"
 | |
| 
 | |
| /* Library-local variables. */
 | |
| dev_t fsdriver_device;
 | |
| ino_t fsdriver_root;
 | |
| int fsdriver_mounted = FALSE;
 | |
| 
 | |
| static int fsdriver_running;
 | |
| 
 | |
| /*
 | |
|  * Process an incoming VFS request, and send a reply.  If the message is not
 | |
|  * a file system request from VFS, pass it on to the generic message handler.
 | |
|  * Multithreaded file systems should indicate that the reply is to be sent to
 | |
|  * VFS asynchronously.
 | |
|  */
 | |
| void
 | |
| fsdriver_process(const struct fsdriver * __restrict fdp,
 | |
| 	const message * __restrict m_ptr, int ipc_status, int asyn_reply)
 | |
| {
 | |
| 	message m_out;
 | |
| 	unsigned int call_nr;
 | |
| 	int r, transid;
 | |
| 
 | |
| 	/* Is this a file system request at all? */
 | |
| 	if (is_ipc_notify(ipc_status) || m_ptr->m_source != VFS_PROC_NR) {
 | |
| 		if (fdp->fdr_other != NULL)
 | |
| 			fdp->fdr_other(m_ptr, ipc_status);
 | |
| 
 | |
| 		return; /* do not send a reply */
 | |
| 	}
 | |
| 
 | |
| 	/* Call the appropriate function. */
 | |
| 	transid = TRNS_GET_ID(m_ptr->m_type);
 | |
| 	call_nr = TRNS_DEL_ID(m_ptr->m_type);
 | |
| 
 | |
| 	memset(&m_out, 0, sizeof(m_out));
 | |
| 
 | |
| 	if (fsdriver_mounted || call_nr == REQ_READSUPER) {
 | |
| 		call_nr -= FS_BASE;	/* unsigned; wrapping is intended */
 | |
| 
 | |
| 		if (call_nr < NREQS && fsdriver_callvec[call_nr] != NULL)
 | |
| 			r = (fsdriver_callvec[call_nr])(fdp, m_ptr, &m_out);
 | |
| 		else
 | |
| 			r = ENOSYS;
 | |
| 	} else
 | |
| 		r = EINVAL;
 | |
| 
 | |
| 	/* Send a reply. */
 | |
| 	m_out.m_type = TRNS_ADD_ID(r, transid);
 | |
| 
 | |
| 	if (asyn_reply)
 | |
| 		r = asynsend(m_ptr->m_source, &m_out);
 | |
| 	else
 | |
| 		r = ipc_send(m_ptr->m_source, &m_out);
 | |
| 
 | |
| 	if (r != OK)
 | |
| 		printf("fsdriver: sending reply failed (%d)\n", r);
 | |
| 
 | |
| 	if (fdp->fdr_postcall != NULL)
 | |
| 		fdp->fdr_postcall();
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Terminate the file server as soon as the file system has been unmounted.
 | |
|  */
 | |
| void
 | |
| fsdriver_terminate(void)
 | |
| {
 | |
| 
 | |
| 	fsdriver_running = FALSE;
 | |
| 
 | |
| 	sef_cancel();
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Main program of any file server task.
 | |
|  */
 | |
| void
 | |
| fsdriver_task(struct fsdriver * fdp)
 | |
| {
 | |
| 	message mess;
 | |
| 	int r, ipc_status;
 | |
| 
 | |
| 	fsdriver_running = TRUE;
 | |
| 
 | |
| 	while (fsdriver_running || fsdriver_mounted) {
 | |
| 		if ((r = sef_receive_status(ANY, &mess, &ipc_status)) != OK) {
 | |
| 			if (r == EINTR)
 | |
| 				continue;	/* sef_cancel() was called */
 | |
| 
 | |
| 			panic("fsdriver: sef_receive_status failed: %d", r);
 | |
| 		}
 | |
| 
 | |
| 		fsdriver_process(fdp, &mess, ipc_status, FALSE /*asyn_reply*/);
 | |
| 	}
 | |
| }
 |