39,8 → 39,7 |
#include <ipc/services.h> |
#include <ipc/ns.h> |
#include <sysinfo.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <io/io.h> |
#include <as.h> |
#include <ddi.h> |
#include <align.h> |
47,66 → 46,300 |
#include <bool.h> |
#include <errno.h> |
#include <async.h> |
#include <cap.h> |
#include <sys/mman.h> |
#include "fs.h" |
#include "dir.h" |
#include "../console/console.h" |
|
|
static int fs_call; |
static ipc_call_t m_input; /* the input message used for request */ |
static ipc_callid_t callid; /* caller's number */ |
static int new_consument; /* if new consumer wants to connect to FS */ |
static int check_con; /* check of connection of consument */ |
|
static void prepare_message(void); |
static int load_super(void); |
static int new_consument_map(void); |
|
static void fs_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
ipc_callid_t callid; |
ipc_call_t call; |
int retval; |
|
int result; |
|
ipc_answer_fast(iid, 0, 0, 0); |
|
while (1) { |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
while (1) |
{ |
prepare_message(); |
|
if (fs_call == IPC_M_PHONE_HUNGUP) { |
ipc_answer_fast(callid, 0,0,0); |
return; |
case FS_OPEN: |
//Why doesn't printf do anything in this task? |
printf("FS_OPEN called"); |
char * f_name = (char *) IPC_GET_ARG1(call); |
printf("I should open file: %s \n",f_name); |
retval = 73; |
break; |
case FS_READ: |
printf("FS_READ called"); |
unsigned int file_handle = IPC_GET_ARG1(call); |
void * buffer = (void *) IPC_GET_ARG2(call); |
unsigned int count = IPC_GET_ARG3(call); |
//I still don't know how to copy memory to another task :( |
//Or can i only map memory? |
retval = 0; |
break; |
default: |
retval = EINVAL; |
} |
ipc_answer_fast(callid, retval, 0, 0); |
|
if (fs_call == FS_NEW_CONSUMER) { |
if (!new_consument) { |
ipc_answer_fast(callid, FS_ECONNECT, 0, 0); |
} |
else { |
result = new_consument_map(); |
ipc_answer_fast(callid, result, 0, 0); |
|
if (!result) { |
new_consument = FALSE; |
} |
} |
continue; |
} |
|
if (fs_call == IPC_M_AS_AREA_SEND) { |
if (!new_consument) |
ipc_answer_fast(callid, FS_ECONNECT, 0, 0); |
else { |
ipc_answer_fast(callid, 0, (uintptr_t)fp->buffer, 0); |
fp = &fproc[new_consument]; |
fp->connected = TRUE; |
new_consument = FALSE; |
} |
continue; |
} |
|
if (check_con < 0) { |
ipc_answer_fast(callid, err_code, 0, 0); |
check_con = TRUE; |
continue; |
} |
|
if (FS_IN_RANGE(fs_call)) { |
result = call_vector[fs_call-FS_BASE](); |
} |
else { |
result = FS_EBADCALL; |
} |
|
ipc_answer_fast(callid, result, 0, 0); |
} |
} |
|
/* Extracts parameters from message and prepare them for later usage. */ |
void prepare_message(void) |
{ |
|
int shift, id_task; |
|
callid = async_get_call(&m_input); |
fs_call = IPC_GET_METHOD(m_input); |
|
if (fs_call == IPC_M_AS_AREA_SEND) { |
if (!new_consument) { |
new_consument = FALSE; |
} |
|
return; |
} |
|
id_task = IPC_GET_ARG1(m_input); |
|
/* Setup new consument. */ |
if (fs_call == FS_NEW_CONSUMER) { |
if (!new_consument) { |
new_consument = id_task; |
} |
else { |
new_consument = FALSE; |
} |
|
return; |
} |
|
/* Other messages discard process of new consument connecting. */ |
if (new_consument) { |
new_consument = FALSE; |
} |
|
if (id_task < 0 || id_task >= NR_PROCS) { |
check_con = FS_EINVAL; |
return; |
} |
|
/* Switch to active consument. */ |
fp = &fproc[id_task]; |
|
/* Check if consument was connected. */ |
if (!(fp->connected)) { |
check_con = FS_ENOTCONNECT; |
return; |
} |
|
|
/* Unpacking extended input message into message_params structure. */ |
unpack_message(&message_params, m_input, fp->buffer); |
} |
|
/* Map some memory to the task */ |
int new_consument_map() |
{ |
|
size_t size; |
task_id_t task_id; |
|
task_id = new_consument; |
if (task_id < 0 || task_id >= NR_PROCS) { |
return FS_EINVAL; |
} |
|
fp = &fproc[task_id]; |
size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE); |
fp->buffer = as_get_mappable_page(size, PAGE_COLOR((uintptr_t)fp->buffer)); |
|
return TRUE; |
} |
/* Reads in the superblock from image. */ |
int load_super(void) |
{ |
|
super_block_t *sp; |
|
if (!init_super_block()) |
return FALSE; |
|
sp = get_super(); |
if (read_super(sp) != OK) |
{ |
print_console("Super block read error\n"); |
return FALSE; |
} |
|
return TRUE; |
} |
|
/* Basic initialization. */ |
static bool fs_init(void) |
{ |
|
return true; |
register inode_t *rip; |
int bad, i; |
|
|
bad = 0; |
callid = SERVICE_FS; |
fp = (fproc_t *)NULL; |
|
print_console("FS initialization..."); |
|
/* Block cache initialization. */ |
if (!init_block()) |
return FALSE; |
|
/* Loading superblock. */ |
if (!load_super()) |
return FALSE; |
|
for (i = 0; i < NR_PROCS; i++) { |
if (i == SERVICE_FS) |
continue; |
|
fp = &fproc[i]; |
rip = get_inode(ROOT_INODE); |
fp->fp_rootdir = rip; |
dup_inode(rip); |
fp->fp_workdir = rip; |
} |
|
fp = &fproc[SERVICE_FS]; |
|
/* Certain relations must hold for the file system to work at all. */ |
if (SUPER_SIZE > BLOCK_SIZE) { |
print_console("SUPER_SIZE > BLOCK_SIZE\n"); |
bad++; |
} |
if (BLOCK_SIZE % V1_INODE_SIZE != 0) { |
print_console("BLOCK_SIZE mod V1_INODE_SIZE != 0\n"); |
bad++; |
} |
if (OPEN_MAX > 127) { |
print_console("OPEN_MAX > 127\n"); |
bad++; |
} |
if (V1_INODE_SIZE != 32) { |
print_console("V1 inode size != 32\n"); |
bad++; |
} |
|
if (V2_INODE_SIZE != 64) { |
print_console("V2 inode size != 64\n"); |
bad++; |
} |
|
if (bad) |
return FALSE; |
|
/* New consument flag settings. */ |
new_consument = FALSE; |
check_con = FALSE; |
|
print_console("OK\n"); |
|
return TRUE; |
} |
|
int main(int argc, char **argv) |
{ |
|
int retval, flags; |
unsigned int size; |
|
|
/* Initializing printing functions. */ |
if (!init_printing()) |
return -1; |
|
print_console("FS task\n"); |
|
/* Connection to SERVICE_RD service. */ |
print_console("Connnection to SERVICE_RD..."); |
if (connect_to_rd(&rd_phone, RD_CONN_ATTEMPTS)) |
print_console("OK\n"); |
else { |
print_console("FALSE\n"); |
return -1; |
} |
|
/* Creating shared memory for usage with SERVICE_RD. */ |
print_console("Creating address space area for share with SERVICE_RD task..."); |
size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE); |
buffer = mmap(buffer, size, AS_AREA_READ | AS_AREA_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0); |
if ((int)buffer < 0) { |
print_console_int("As_area_create error %d", (int)buffer); |
return -1; |
} |
print_console("OK\n"); |
|
|
/* Mapping memory to SERVICE_RD. */ |
print_console("Sending memory to RD_SERVICE..."); |
flags = 0; |
flags = AS_AREA_READ | AS_AREA_WRITE; |
retval = async_req_3(rd_phone, IPC_M_AS_AREA_SEND, (uintptr_t)buffer, size, flags, NULL, NULL, NULL); |
if (retval < 0) { |
print_console_int("%d\n", retval); |
return -1; |
} |
print_console("OK\n"); |
|
if (fs_init()) { |
ipcarg_t phonead; |
|
|
async_set_client_connection(fs_connection); |
|
|
/* Register service at nameserver */ |
if (ipc_connect_to_me(PHONE_NS, SERVICE_FS, 0, &phonead) != 0) |
return -1; |
|
async_manager(); |
|
|
/* Never reached */ |
return 0; |
} |