00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 struct super_block;
00012
00013 #include "fs.h"
00014 #include <fcntl.h>
00015 #include <string.h>
00016 #include <stdio.h>
00017 #include <signal.h>
00018 #include <stdlib.h>
00019 #include <sys/ioc_memory.h>
00020 #include <sys/svrctl.h>
00021 #include <sys/select.h>
00022 #include <minix/callnr.h>
00023 #include <minix/com.h>
00024 #include <minix/keymap.h>
00025 #include <minix/const.h>
00026 #include <minix/endpoint.h>
00027 #include "buf.h"
00028 #include "file.h"
00029 #include "fproc.h"
00030 #include "inode.h"
00031 #include "param.h"
00032 #include "super.h"
00033
00034 FORWARD _PROTOTYPE( void fs_init, (void) );
00035 FORWARD _PROTOTYPE( void get_work, (void) );
00036 FORWARD _PROTOTYPE( void init_root, (void) );
00037
00038
00039
00040
00041 PUBLIC int main()
00042 {
00043
00044
00045
00046
00047 int error;
00048
00049 fs_init();
00050
00051
00052
00053 while (TRUE) {
00054 get_work();
00055 fp = &fproc[who_p];
00056 super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE);
00057
00058
00059 if (call_nr == PROC_EVENT) {
00060
00061 do_sync();
00062 } else if (call_nr == SYN_ALARM) {
00063
00064 fs_expire_timers(m_in.NOTIFY_TIMESTAMP);
00065 } else if ((call_nr & NOTIFY_MESSAGE)) {
00066
00067 dev_status(&m_in);
00068 } else {
00069
00070 if (call_nr < 0 || call_nr >= NCALLS) {
00071 error = ENOSYS;
00072
00073 printf("FS, warning illegal %d system call by %d\n", call_nr, who_e);
00074 } else if (fp->fp_pid == PID_FREE) {
00075 error = ENOSYS;
00076 printf("FS, bad process, who = %d, call_nr = %d, endpt1 = %d\n",
00077 who_e, call_nr, m_in.endpt1);
00078 } else {
00079 error = (*call_vec[call_nr])();
00080 }
00081
00082
00083 if (error != SUSPEND) { reply(who_e, error); }
00084 if (rdahed_inode != NIL_INODE) {
00085 read_ahead();
00086 }
00087 }
00088 }
00089 return(OK);
00090 }
00091
00092
00093
00094
00095 PRIVATE void get_work()
00096 {
00097
00098
00099
00100 register struct fproc *rp;
00101
00102 if (reviving != 0) {
00103
00104 for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++)
00105 if (rp->fp_pid != PID_FREE && rp->fp_revived == REVIVING) {
00106 who_p = (int)(rp - fproc);
00107 who_e = rp->fp_endpoint;
00108 call_nr = rp->fp_fd & BYTE;
00109 m_in.fd = (rp->fp_fd >>8) & BYTE;
00110 m_in.buffer = rp->fp_buffer;
00111 m_in.nbytes = rp->fp_nbytes;
00112 rp->fp_suspended = NOT_SUSPENDED;
00113 rp->fp_revived = NOT_REVIVING;
00114 reviving--;
00115 return;
00116 }
00117 panic(__FILE__,"get_work couldn't revive anyone", NO_NUM);
00118 }
00119
00120 for(;;) {
00121
00122 if (receive(ANY, &m_in) != OK)
00123 panic(__FILE__,"fs receive error", NO_NUM);
00124 who_e = m_in.m_source;
00125 who_p = _ENDPOINT_P(who_e);
00126 if(who_p < -NR_TASKS || who_p >= NR_PROCS)
00127 panic(__FILE__,"receive process out of range", who_p);
00128 if(who_p >= 0 && fproc[who_p].fp_endpoint == NONE) {
00129 printf("FS: ignoring request from %d, endpointless slot %d (%d)\n",
00130 m_in.m_source, who_p, m_in.m_type);
00131 continue;
00132 }
00133 if(who_p >= 0 && fproc[who_p].fp_endpoint != who_e) {
00134 printf("FS: receive endpoint inconsistent (%d, %d, %d).\n",
00135 who_e, fproc[who_p].fp_endpoint, who_e);
00136 panic(__FILE__, "FS: inconsistent endpoint ", NO_NUM);
00137 continue;
00138 }
00139 call_nr = m_in.m_type;
00140 return;
00141 }
00142 }
00143
00144
00145
00146
00147 PRIVATE void buf_pool(void)
00148 {
00149
00150
00151 register struct buf *bp;
00152
00153 bufs_in_use = 0;
00154 front = &buf[0];
00155 rear = &buf[NR_BUFS - 1];
00156
00157 for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++) {
00158 bp->b_blocknr = NO_BLOCK;
00159 bp->b_dev = NO_DEV;
00160 bp->b_next = bp + 1;
00161 bp->b_prev = bp - 1;
00162 }
00163 buf[0].b_prev = NIL_BUF;
00164 buf[NR_BUFS - 1].b_next = NIL_BUF;
00165
00166 for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++) bp->b_hash = bp->b_next;
00167 buf_hash[0] = front;
00168
00169 }
00170
00171
00172
00173
00174 PUBLIC void reply(whom, result)
00175 int whom;
00176 int result;
00177 {
00178
00179 int s;
00180 m_out.reply_type = result;
00181 s = send(whom, &m_out);
00182 if (s != OK) printf("FS: couldn't send reply %d to %d: %d\n",
00183 result, whom, s);
00184 }
00185
00186
00187
00188
00189 PRIVATE void fs_init()
00190 {
00191
00192 register struct inode *rip;
00193 register struct fproc *rfp;
00194 message mess;
00195 int s;
00196
00197
00198
00199
00200
00201
00202 do {
00203 if (OK != (s=receive(PM_PROC_NR, &mess)))
00204 panic(__FILE__,"FS couldn't receive from PM", s);
00205 if (NONE == mess.PR_ENDPT) break;
00206
00207 rfp = &fproc[mess.PR_SLOT];
00208 rfp->fp_pid = mess.PR_PID;
00209 rfp->fp_endpoint = mess.PR_ENDPT;
00210 rfp->fp_realuid = (uid_t) SYS_UID;
00211 rfp->fp_effuid = (uid_t) SYS_UID;
00212 rfp->fp_realgid = (gid_t) SYS_GID;
00213 rfp->fp_effgid = (gid_t) SYS_GID;
00214 rfp->fp_umask = ~0;
00215
00216 } while (TRUE);
00217 mess.m_type = OK;
00218 s=send(PM_PROC_NR, &mess);
00219
00220
00221
00222
00223
00224 if (OPEN_MAX > 127) panic(__FILE__,"OPEN_MAX > 127", NO_NUM);
00225 if (NR_BUFS < 6) panic(__FILE__,"NR_BUFS < 6", NO_NUM);
00226 if (V1_INODE_SIZE != 32) panic(__FILE__,"V1 inode size != 32", NO_NUM);
00227 if (V2_INODE_SIZE != 64) panic(__FILE__,"V2 inode size != 64", NO_NUM);
00228 if (OPEN_MAX > 8 * sizeof(long))
00229 panic(__FILE__,"Too few bits in fp_cloexec", NO_NUM);
00230
00231
00232 fp = (struct fproc *) NULL;
00233 who_e = who_p = FS_PROC_NR;
00234
00235 buf_pool();
00236 build_dmap();
00237 init_root();
00238 init_select();
00239
00240
00241 for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
00242 FD_ZERO(&(rfp->fp_filp_inuse));
00243 if (rfp->fp_pid != PID_FREE) {
00244 rip = get_inode(root_dev, ROOT_INODE);
00245 dup_inode(rip);
00246 rfp->fp_rootdir = rip;
00247 rfp->fp_workdir = rip;
00248 } else rfp->fp_endpoint = NONE;
00249 }
00250 }
00251
00252
00253
00254
00255 PRIVATE void init_root()
00256 {
00257 int bad;
00258 register struct super_block *sp;
00259 register struct inode *rip = NIL_INODE;
00260 int s;
00261
00262
00263 root_dev = DEV_IMGRD;
00264 if ((s=dev_open(root_dev, FS_PROC_NR, R_BIT|W_BIT)) != OK)
00265 panic(__FILE__,"Cannot open root device", s);
00266
00267 #if ENABLE_CACHE2
00268
00269 init_cache2(ram_size);
00270 #endif
00271
00272
00273 for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++)
00274 sp->s_dev = NO_DEV;
00275
00276
00277 sp = &super_block[0];
00278 sp->s_dev = root_dev;
00279
00280
00281 bad = (read_super(sp) != OK);
00282 if (!bad) {
00283 rip = get_inode(root_dev, ROOT_INODE);
00284 if ( (rip->i_mode & I_TYPE) != I_DIRECTORY || rip->i_nlinks < 3) bad++;
00285 }
00286 if (bad) panic(__FILE__,"Invalid root file system", NO_NUM);
00287
00288 sp->s_imount = rip;
00289 dup_inode(rip);
00290 sp->s_isup = rip;
00291 sp->s_rd_only = 0;
00292 return;
00293 }