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
9 * April 2009 (D.C. van Moolenbroek)
14 /*===========================================================================*
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.
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
;
39 /*===========================================================================*
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
));
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.
64 /*===========================================================================*
66 *===========================================================================*/
67 static int get_work(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.
75 if ((r
= sef_receive(ANY
, &m_in
)) != OK
) {
77 panic("receive failed: %d", r
);
82 *who_e
= m_in
.m_source
;
86 /*===========================================================================*
88 *===========================================================================*/
89 static void send_reply(err
, transid
)
90 int err
; /* resulting error code */
93 /* Send a reply message to the requesting party, with the given error code.
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 /*===========================================================================*
108 *===========================================================================*/
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.
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. */
130 assert(IS_VFS_FS_TRANSID(transid
));
132 call_nr
= m_in
.m_type
;
133 if (who_e
!= VFS_PROC_NR
) {
137 if (state
.s_mounted
|| call_nr
== REQ_READSUPER
) {
140 dprintf(("%s: call %d\n", sffs_name
, call_nr
));
142 if (call_nr
>= 0 && call_nr
< NREQS
) {
143 err
= (*call_vec
[call_nr
])();
148 dprintf(("%s: call %d result %d\n", sffs_name
, call_nr
, err
));
152 send_reply(err
, transid
);