xref: /minix/minix/lib/libfsdriver/fsdriver.c (revision e3b78ef1)
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