Subversion Repositories HelenOS

Rev

Rev 2248 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2248 Rev 2388
Line 37... Line 37...
37
 
37
 
38
#include <ipc/ipc.h>
38
#include <ipc/ipc.h>
39
#include <ipc/services.h>
39
#include <ipc/services.h>
40
#include <ipc/ns.h>
40
#include <ipc/ns.h>
41
#include <sysinfo.h>
41
#include <sysinfo.h>
42
#include <stdio.h>
42
#include <io/io.h>
43
#include <stdlib.h>
-
 
44
#include <as.h>
43
#include <as.h>
45
#include <ddi.h>
44
#include <ddi.h>
46
#include <align.h>
45
#include <align.h>
47
#include <bool.h>
46
#include <bool.h>
48
#include <errno.h>
47
#include <errno.h>
49
#include <async.h>
48
#include <async.h>
-
 
49
#include <cap.h>
-
 
50
#include <sys/mman.h>
50
#include "fs.h"
51
#include "fs.h"
-
 
52
#include "dir.h"
-
 
53
#include "../console/console.h"
51
 
54
 
52
 
55
 
-
 
56
static int fs_call;
-
 
57
static ipc_call_t m_input;          /* the input message used for request */
-
 
58
static ipc_callid_t callid;         /* caller's number */
-
 
59
static int new_consument;       /* if new consumer wants to connect to FS */
-
 
60
static int check_con;           /* check of connection of consument */
-
 
61
           
-
 
62
static void prepare_message(void);
-
 
63
static int load_super(void);
-
 
64
static int new_consument_map(void);
-
 
65
 
53
static void fs_connection(ipc_callid_t iid, ipc_call_t *icall)
66
static void fs_connection(ipc_callid_t iid, ipc_call_t *icall)
54
{
67
{
55
    ipc_callid_t callid;
-
 
56
    ipc_call_t call;
-
 
-
 
68
 
57
    int retval;
69
    int result;
58
 
70
 
59
    ipc_answer_fast(iid, 0, 0, 0);
71
    ipc_answer_fast(iid, 0, 0, 0);
60
 
72
 
61
    while (1) {
73
    while (1)
-
 
74
    {
62
        callid = async_get_call(&call);
75
        prepare_message();
63
        switch (IPC_GET_METHOD(call)) {
76
       
64
        case IPC_M_PHONE_HUNGUP:
77
        if (fs_call == IPC_M_PHONE_HUNGUP) {
65
            ipc_answer_fast(callid, 0,0,0);
78
            ipc_answer_fast(callid, 0,0,0);
66
            return;
79
            return;
67
        case FS_OPEN:
-
 
68
            //Why doesn't printf do anything in this task?
-
 
69
            printf("FS_OPEN called");  
-
 
70
            char * f_name = (char *) IPC_GET_ARG1(call);
-
 
71
            printf("I should open file: %s \n",f_name);
-
 
72
            retval = 73;
-
 
73
            break;
-
 
74
        case FS_READ:
-
 
75
            printf("FS_READ called");
-
 
76
            unsigned int file_handle = IPC_GET_ARG1(call);
-
 
77
            void * buffer = (void *) IPC_GET_ARG2(call);
-
 
78
            unsigned int count = IPC_GET_ARG3(call);
-
 
79
            //I still don't know how to copy memory to another task :(
-
 
80
            //Or can i only map memory?
-
 
81
            retval = 0;
-
 
82
            break;
-
 
83
        default:
-
 
84
            retval = EINVAL;
-
 
85
        }
80
        }
-
 
81
 
-
 
82
        if (fs_call == FS_NEW_CONSUMER) {
-
 
83
            if (!new_consument) {
-
 
84
                ipc_answer_fast(callid, FS_ECONNECT, 0, 0);
-
 
85
            }
-
 
86
            else {
-
 
87
                result = new_consument_map();  
86
        ipc_answer_fast(callid, retval, 0, 0);
88
                ipc_answer_fast(callid, result, 0, 0);
-
 
89
 
-
 
90
                if (!result) {
-
 
91
                    new_consument = FALSE;     
-
 
92
                }
-
 
93
            }
-
 
94
            continue;  
-
 
95
        }
-
 
96
 
-
 
97
        if (fs_call == IPC_M_AS_AREA_SEND) {
-
 
98
            if (!new_consument)
-
 
99
                ipc_answer_fast(callid, FS_ECONNECT, 0, 0);    
-
 
100
            else {
-
 
101
                ipc_answer_fast(callid, 0, (uintptr_t)fp->buffer, 0);
-
 
102
                fp =  &fproc[new_consument];
-
 
103
                fp->connected = TRUE;
-
 
104
                new_consument = FALSE;
-
 
105
            }
-
 
106
            continue;
-
 
107
        }
-
 
108
   
-
 
109
        if (check_con < 0) {
-
 
110
            ipc_answer_fast(callid, err_code, 0, 0);
-
 
111
            check_con = TRUE;
-
 
112
            continue;  
-
 
113
        }
-
 
114
 
-
 
115
        if (FS_IN_RANGE(fs_call)) {  
-
 
116
           result = call_vector[fs_call-FS_BASE]();
-
 
117
        }
-
 
118
        else {
-
 
119
           result = FS_EBADCALL;
-
 
120
        }
-
 
121
 
-
 
122
        ipc_answer_fast(callid, result, 0, 0);             
87
    }  
123
    }  
88
}
124
}
89
 
125
 
-
 
126
/* Extracts parameters from message and prepare them for later usage. */
-
 
127
void prepare_message(void)
-
 
128
{
-
 
129
   
-
 
130
    int shift, id_task;
-
 
131
   
-
 
132
    callid = async_get_call(&m_input);
-
 
133
    fs_call = IPC_GET_METHOD(m_input);
-
 
134
   
-
 
135
    if (fs_call == IPC_M_AS_AREA_SEND) {   
-
 
136
        if (!new_consument) {
-
 
137
            new_consument = FALSE;
-
 
138
        }
-
 
139
 
-
 
140
        return;
-
 
141
    }
-
 
142
   
-
 
143
    id_task = IPC_GET_ARG1(m_input);    
-
 
144
   
-
 
145
    /* Setup new consument. */
-
 
146
    if (fs_call == FS_NEW_CONSUMER) {
-
 
147
        if (!new_consument) {
-
 
148
            new_consument = id_task;
-
 
149
        }
-
 
150
        else {
-
 
151
            new_consument = FALSE;
-
 
152
        }
-
 
153
 
-
 
154
        return;
-
 
155
    }
-
 
156
   
-
 
157
    /* Other messages discard process of new consument connecting. */
-
 
158
    if (new_consument) {
-
 
159
        new_consument = FALSE;
-
 
160
    }
-
 
161
   
-
 
162
    if (id_task < 0 || id_task >= NR_PROCS) {
-
 
163
        check_con = FS_EINVAL;
-
 
164
        return;    
-
 
165
    }
-
 
166
   
-
 
167
    /* Switch to active consument. */
-
 
168
    fp = &fproc[id_task];
-
 
169
   
-
 
170
    /* Check if consument was connected. */
-
 
171
    if (!(fp->connected)) {
-
 
172
        check_con = FS_ENOTCONNECT;
-
 
173
        return;
-
 
174
    }
-
 
175
 
-
 
176
   
-
 
177
    /* Unpacking extended input message into message_params structure. */
-
 
178
    unpack_message(&message_params, m_input, fp->buffer);
-
 
179
}
-
 
180
 
-
 
181
/* Map some memory to the task */
-
 
182
int new_consument_map()
-
 
183
{
-
 
184
   
-
 
185
    size_t size;
-
 
186
    task_id_t task_id;
-
 
187
 
-
 
188
    task_id = new_consument;   
-
 
189
    if (task_id < 0 || task_id >= NR_PROCS) {
-
 
190
        return FS_EINVAL;
-
 
191
    }
-
 
192
 
-
 
193
    fp = &fproc[task_id];
-
 
194
    size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
-
 
195
    fp->buffer = as_get_mappable_page(size, PAGE_COLOR((uintptr_t)fp->buffer));
-
 
196
 
-
 
197
    return TRUE;
-
 
198
}
-
 
199
/* Reads in the superblock from image. */
-
 
200
int load_super(void)
-
 
201
{
-
 
202
   
-
 
203
    super_block_t *sp;
-
 
204
   
-
 
205
    if (!init_super_block())
-
 
206
        return FALSE;
-
 
207
 
-
 
208
        sp = get_super();
-
 
209
    if (read_super(sp) != OK)
-
 
210
    {
-
 
211
        print_console("Super block read error\n");
-
 
212
        return FALSE;
-
 
213
    }
-
 
214
 
-
 
215
    return TRUE;
-
 
216
}
90
 
217
 
-
 
218
/* Basic initialization. */
91
static bool fs_init(void)
219
static bool fs_init(void)
92
{
220
{
93
   
221
   
-
 
222
    register inode_t *rip;
-
 
223
    int bad, i;
-
 
224
   
-
 
225
 
-
 
226
    bad = 0;
-
 
227
    callid = SERVICE_FS;
-
 
228
    fp = (fproc_t *)NULL;
-
 
229
   
-
 
230
    print_console("FS initialization...");
-
 
231
 
-
 
232
    /* Block cache initialization. */
-
 
233
    if (!init_block())
-
 
234
        return FALSE;
-
 
235
   
-
 
236
    /* Loading superblock. */
-
 
237
    if (!load_super())
-
 
238
        return FALSE;
-
 
239
       
-
 
240
    for (i = 0; i < NR_PROCS; i++) {
-
 
241
        if (i == SERVICE_FS)
-
 
242
            continue;
-
 
243
 
-
 
244
        fp = &fproc[i];
-
 
245
        rip = get_inode(ROOT_INODE);
-
 
246
        fp->fp_rootdir = rip;
-
 
247
        dup_inode(rip);
-
 
248
        fp->fp_workdir = rip;
-
 
249
    }
-
 
250
   
-
 
251
    fp = &fproc[SERVICE_FS];
-
 
252
 
-
 
253
    /* Certain relations must hold for the file system to work at all. */
-
 
254
    if (SUPER_SIZE > BLOCK_SIZE) {
-
 
255
        print_console("SUPER_SIZE > BLOCK_SIZE\n");
-
 
256
        bad++;
-
 
257
    }
-
 
258
    if (BLOCK_SIZE % V1_INODE_SIZE != 0) { 
-
 
259
        print_console("BLOCK_SIZE mod V1_INODE_SIZE != 0\n");
-
 
260
        bad++;
-
 
261
    }
-
 
262
    if (OPEN_MAX > 127) {  
-
 
263
        print_console("OPEN_MAX > 127\n");
-
 
264
        bad++;
-
 
265
    }
-
 
266
    if (V1_INODE_SIZE != 32) { 
-
 
267
        print_console("V1 inode size != 32\n");
-
 
268
        bad++;
-
 
269
    }
-
 
270
   
-
 
271
    if (V2_INODE_SIZE != 64) { 
-
 
272
        print_console("V2 inode size != 64\n");
-
 
273
        bad++;
-
 
274
    }
-
 
275
   
-
 
276
    if (bad)
-
 
277
        return FALSE;
-
 
278
 
-
 
279
    /* New consument flag settings. */
-
 
280
    new_consument = FALSE;
-
 
281
    check_con = FALSE;
-
 
282
 
-
 
283
    print_console("OK\n");
-
 
284
   
94
    return true;
285
    return TRUE;
95
}
286
}
96
 
287
 
97
int main(int argc, char **argv)
288
int main(int argc, char **argv)
98
{
289
{
-
 
290
   
-
 
291
    int retval, flags;
-
 
292
    unsigned int size;
-
 
293
 
-
 
294
 
-
 
295
    /* Initializing printing functions. */
-
 
296
    if (!init_printing())
-
 
297
        return -1;
-
 
298
 
-
 
299
    print_console("FS task\n");
-
 
300
 
-
 
301
    /* Connection to SERVICE_RD service. */
-
 
302
    print_console("Connnection to SERVICE_RD...");
-
 
303
    if (connect_to_rd(&rd_phone, RD_CONN_ATTEMPTS))
-
 
304
        print_console("OK\n");
-
 
305
    else {
-
 
306
        print_console("FALSE\n");
-
 
307
        return -1;
-
 
308
    }
-
 
309
   
-
 
310
    /* Creating shared memory for usage with SERVICE_RD.  */
-
 
311
    print_console("Creating address space area for share with SERVICE_RD task...");
-
 
312
    size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
-
 
313
    buffer = mmap(buffer, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
-
 
314
    if ((int)buffer < 0) {
-
 
315
        print_console_int("As_area_create error %d", (int)buffer);
-
 
316
        return -1;
-
 
317
    }
-
 
318
    print_console("OK\n");
-
 
319
 
-
 
320
 
-
 
321
    /* Mapping memory to SERVICE_RD. */
-
 
322
    print_console("Sending memory to RD_SERVICE...");
-
 
323
    flags = 0;
-
 
324
    flags = AS_AREA_READ | AS_AREA_WRITE;
-
 
325
    retval = async_req_3(rd_phone, IPC_M_AS_AREA_SEND, (uintptr_t)buffer, size, flags, NULL, NULL, NULL);
-
 
326
    if (retval < 0) {
-
 
327
        print_console_int("%d\n", retval);
-
 
328
        return -1;
-
 
329
    }
-
 
330
    print_console("OK\n");
-
 
331
 
99
    if (fs_init()) {
332
    if (fs_init()) {
100
        ipcarg_t phonead;
333
        ipcarg_t phonead;
101
       
334
   
102
        async_set_client_connection(fs_connection);
335
        async_set_client_connection(fs_connection);
103
       
336
 
104
        /* Register service at nameserver */
337
        /* Register service at nameserver */
105
        if (ipc_connect_to_me(PHONE_NS, SERVICE_FS, 0, &phonead) != 0)
338
        if (ipc_connect_to_me(PHONE_NS, SERVICE_FS, 0, &phonead) != 0)
106
            return -1;
339
            return -1;
107
       
340
       
108
        async_manager();
341
        async_manager();
109
       
342
 
110
        /* Never reached */
343
        /* Never reached */
111
        return 0;
344
        return 0;
112
    }
345
    }
113
   
346
   
114
    return -1;
347
    return -1;