sprofalyze fixes
[minix.git] / lib / libsffs / main.c
blobb45b7847e8c656a6f792ce3ee6b072c59c5b86ef
1 /* This file contains the SFFS initialization code and message loop.
3 * The entry points into this file are:
4 * sffs_init initialization
5 * sffs_signal signal handler
6 * sffs_loop main message loop
8 * Created:
9 * April 2009 (D.C. van Moolenbroek)
12 #include "inc.h"
14 /*===========================================================================*
15 * sffs_init *
16 *===========================================================================*/
17 int sffs_init(char *name, const struct sffs_table *table,
18 struct sffs_params *params)
20 /* Initialize this file server. Called at startup time.
22 int i;
24 /* Make sure that the given path prefix doesn't end with a slash. */
25 i = strlen(params->p_prefix);
26 while (i > 0 && params->p_prefix[i - 1] == '/') i--;
27 params->p_prefix[i] = 0;
29 state.s_mounted = FALSE;
30 state.s_signaled = FALSE;
32 sffs_name = name;
33 sffs_table = table;
34 sffs_params = params;
36 return OK;
39 /*===========================================================================*
40 * sffs_signal *
41 *===========================================================================*/
42 void sffs_signal(int signo)
45 /* Only check for termination signal, ignore anything else. */
46 if (signo != SIGTERM) return;
48 /* We can now terminate if we have also been unmounted. */
49 state.s_signaled = TRUE;
51 if (state.s_mounted) {
52 dprintf(("%s: got SIGTERM, still mounted\n", sffs_name));
53 } else {
54 dprintf(("%s: got SIGTERM, shutting down\n", sffs_name));
56 /* Break out of the main loop, giving the main program the chance to
57 * perform further cleanup. This causes sef_receive() to return with
58 * an EINTR error code.
60 sef_cancel();
64 /*===========================================================================*
65 * get_work *
66 *===========================================================================*/
67 static int get_work(who_e)
68 endpoint_t *who_e;
70 /* Receive a request message from VFS. Return TRUE if a new message is ready
71 * to be processed, or FALSE if sef_stop() was called from the signal handler.
73 int r;
75 if ((r = sef_receive(ANY, &m_in)) != OK) {
76 if (r != EINTR)
77 panic("receive failed: %d", r);
79 return FALSE;
82 *who_e = m_in.m_source;
83 return TRUE;
86 /*===========================================================================*
87 * send_reply *
88 *===========================================================================*/
89 static void send_reply(err, transid)
90 int err; /* resulting error code */
91 int transid;
93 /* Send a reply message to the requesting party, with the given error code.
95 int r;
97 m_out.m_type = err;
98 if (IS_VFS_FS_TRANSID(transid)) {
99 /* If a transaction ID was set, reset it */
100 m_out.m_type = TRNS_ADD_ID(m_out.m_type, transid);
102 if ((r = send(m_in.m_source, &m_out)) != OK)
103 printf("%s: send failed (%d)\n", sffs_name, r);
106 /*===========================================================================*
107 * sffs_loop *
108 *===========================================================================*/
109 void sffs_loop(void)
111 /* The main function of this file server. After initializing, loop, receiving
112 * one request from VFS at a time, processing it, and sending a reply back to
113 * VFS. Termination occurs when we both have been unmounted and have received
114 * a termination signal.
116 endpoint_t who_e;
117 int call_nr, err, transid;
119 while (state.s_mounted || !state.s_signaled) {
120 if (!get_work(&who_e))
121 continue; /* Recheck running conditions */
123 transid = TRNS_GET_ID(m_in.m_type);
124 m_in.m_type = TRNS_DEL_ID(m_in.m_type);
125 if (m_in.m_type == 0) {
126 assert(!IS_VFS_FS_TRANSID(transid));
127 m_in.m_type = transid; /* Backwards compat. */
128 transid = 0;
129 } else
130 assert(IS_VFS_FS_TRANSID(transid));
132 call_nr = m_in.m_type;
133 if (who_e != VFS_PROC_NR) {
134 continue;
137 if (state.s_mounted || call_nr == REQ_READSUPER) {
138 call_nr -= VFS_BASE;
140 dprintf(("%s: call %d\n", sffs_name, call_nr));
142 if (call_nr >= 0 && call_nr < NREQS) {
143 err = (*call_vec[call_nr])();
144 } else {
145 err = ENOSYS;
148 dprintf(("%s: call %d result %d\n", sffs_name, call_nr, err));
150 else err = EINVAL;
152 send_reply(err, transid);