3 #include <minix/callnr.h>
8 #include <minix/dmap.h>
9 #include <minix/endpoint.h>
10 #include <minix/vfsif.h>
11 #include <minix/optset.h>
15 /* Declare some local functions. */
16 static void get_work(message
*m_in
);
17 static void reply(endpoint_t who
, message
*m_out
);
19 /* SEF functions and variables. */
20 static void sef_local_startup(void);
21 static int sef_cb_init_fresh(int type
, sef_init_info_t
*info
);
22 static void sef_cb_signal_handler(int signo
);
25 EXTERN
char **env_argv
;
27 static struct optset optset_table
[] = {
28 { "sb", OPT_INT
, &opt
.block_with_super
, 0 },
29 { "orlov", OPT_BOOL
, &opt
.use_orlov
, TRUE
},
30 { "oldalloc", OPT_BOOL
, &opt
.use_orlov
, FALSE
},
31 { "mfsalloc", OPT_BOOL
, &opt
.mfsalloc
, TRUE
},
32 { "reserved", OPT_BOOL
, &opt
.use_reserved_blocks
, TRUE
},
33 { "prealloc", OPT_BOOL
, &opt
.use_prealloc
, TRUE
},
34 { "noprealloc", OPT_BOOL
, &opt
.use_prealloc
, FALSE
},
38 /*===========================================================================*
40 *===========================================================================*/
41 int main(int argc
, char *argv
[])
43 /* This is the main routine of this service. The main loop consists of
44 * three major activities: getting new work, processing the work, and
45 * sending the reply. The loop never terminates, unless a panic occurs.
47 int error
= OK
, ind
, transid
;
48 unsigned short test_endian
= 1;
50 /* SEF local startup. */
51 env_setargs(argc
, argv
);
54 le_CPU
= (*(unsigned char *) &test_endian
== 0 ? 0 : 1);
56 /* Server isn't tested on big endian CPU */
59 while(!unmountdone
|| !exitsignaled
) {
62 /* Wait for request message. */
65 transid
= TRNS_GET_ID(fs_m_in
.m_type
);
66 fs_m_in
.m_type
= TRNS_DEL_ID(fs_m_in
.m_type
);
67 if (fs_m_in
.m_type
== 0) {
68 assert(!IS_VFS_FS_TRANSID(transid
));
69 fs_m_in
.m_type
= transid
; /* Backwards compat. */
72 assert(IS_VFS_FS_TRANSID(transid
));
74 src
= fs_m_in
.m_source
;
75 caller_uid
= INVAL_UID
; /* To trap errors */
76 caller_gid
= INVAL_GID
;
77 req_nr
= fs_m_in
.m_type
;
79 if (req_nr
< VFS_BASE
) {
80 fs_m_in
.m_type
+= VFS_BASE
;
81 req_nr
= fs_m_in
.m_type
;
83 ind
= req_nr
- VFS_BASE
;
85 if (ind
< 0 || ind
>= NREQS
) {
86 printf("mfs: bad request %d\n", req_nr
);
87 printf("ind = %d\n", ind
);
90 error
= (*fs_call_vec
[ind
])();
93 fs_m_out
.m_type
= error
;
94 if (IS_VFS_FS_TRANSID(transid
)) {
95 /* If a transaction ID was set, reset it */
96 fs_m_out
.m_type
= TRNS_ADD_ID(fs_m_out
.m_type
, transid
);
98 reply(src
, &fs_m_out
);
101 read_ahead(); /* do block read ahead */
107 /*===========================================================================*
108 * sef_local_startup *
109 *===========================================================================*/
110 static void sef_local_startup()
112 /* Register init callbacks. */
113 sef_setcb_init_fresh(sef_cb_init_fresh
);
114 sef_setcb_init_restart(sef_cb_init_fail
);
116 /* No live update support for now. */
118 /* Register signal callbacks. */
119 sef_setcb_signal_handler(sef_cb_signal_handler
);
121 /* Let SEF perform startup. */
125 /*===========================================================================*
126 * sef_cb_init_fresh *
127 *===========================================================================*/
128 static int sef_cb_init_fresh(int UNUSED(type
), sef_init_info_t
*UNUSED(info
))
130 /* Initialize the Minix file server. */
134 opt
.use_orlov
= TRUE
;
135 opt
.mfsalloc
= FALSE
;
136 opt
.use_reserved_blocks
= FALSE
;
137 opt
.block_with_super
= 0;
138 opt
.use_prealloc
= FALSE
;
140 /* If we have been given an options string, parse options from there. */
141 for (i
= 1; i
< env_argc
- 1; i
++)
142 if (!strcmp(env_argv
[i
], "-o"))
143 optset_parse(optset_table
, env_argv
[++i
]);
145 lmfs_may_use_vmcache(1);
147 /* Init inode table */
148 for (i
= 0; i
< NR_INODES
; ++i
) {
149 inode
[i
].i_count
= 0;
155 SELF_E
= getprocnr();
157 /* just a small number before we find out the block size at mount time */
163 /*===========================================================================*
164 * sef_cb_signal_handler *
165 *===========================================================================*/
166 static void sef_cb_signal_handler(int signo
)
168 /* Only check for termination signal, ignore anything else. */
169 if (signo
!= SIGTERM
) return;
174 /* If unmounting has already been performed, exit immediately.
175 * We might not get another message.
177 if (unmountdone
) exit(0);
180 /*===========================================================================*
182 *===========================================================================*/
183 static void get_work(m_in
)
184 message
*m_in
; /* pointer to message */
190 if ((r
= sef_receive(ANY
, m_in
)) != OK
) /* wait for message */
191 panic("sef_receive failed: %d", r
);
192 src
= m_in
->m_source
;
194 if(src
== VFS_PROC_NR
) {
196 printf("ext2: unmounted: unexpected message from FS\n");
198 srcok
= 1; /* Normal FS request. */
201 printf("ext2: unexpected source %d\n", src
);
204 assert((src
== VFS_PROC_NR
&& !unmountdone
));
208 /*===========================================================================*
210 *===========================================================================*/
213 message
*m_out
/* report result */
216 if (OK
!= send(who
, m_out
)) /* send the message */
217 printf("ext2(%d) was unable to send reply\n", SELF_E
);