📄 nfile.c
字号:
uint8_t *tmp = pPage; *ppPage = (uint32_t *) ss->buf; ss->buf = tmp; } else#endif#if 1 bcopy(buf, &pPage[offset], nBytes);#endif DEBUG(write) kdprintf(KR_OSTREAM, "write: ino: 0x%X bwrote %d at 0x%x\n", ino->uuid, nBytes, at); len -= nBytes; at += nBytes; buf += nBytes; } } if (at > ino->u.sz) ino->u.sz = at; return RC_OK;}/* Write /len/ bytes of data from /buf/ into /file/, starting at position /at/. Extends the file as necessary. */uint32_tread_from_file(server_state *ss, ino_s *ino, f_size_t at, uint32_t *rqLen, uint8_t *buf){ uint32_t len = *rqLen; DEBUG(read) kdprintf(KR_OSTREAM, "read: ino: 0x%X reading %d at 0x%x\n", ino->uuid, len, at); if (at > ino->u.sz) return RC_RequestError; if (at + len > ino->u.sz) { len = ino->u.sz - at; *rqLen = len; DEBUG(read) kdprintf(KR_OSTREAM, "read: ino: 0x%X truncated to %d at 0x%x\n", ino->uuid, len, at); } /* The passed /buf/ is contiguous, but there is no guarantee that the file itself is. */ while (len) { uint32_t offset = at & (BLOCK_SIZE - 1); uint32_t nBytes = BLOCK_SIZE - offset; if (nBytes > len) nBytes = len; DEBUG(write) kdprintf(KR_OSTREAM, "read: ino: 0x%X bread %d at 0x%x\n", ino->uuid, nBytes, at); { uint32_t **ppPage = find_file_page(ss, ino, at, NO_GROW); if (ppPage == 0) { DEBUG(write) kdprintf(KR_OSTREAM, "read: ino: 0x%X bread %d at 0x%x -- lazy zero\n", ino->uuid, nBytes, at); bzero(buf, nBytes); } else { uint8_t *pPage = (uint8_t *) *ppPage; bcopy(&pPage[offset], buf, nBytes); } } DEBUG(write) kdprintf(KR_OSTREAM, "read: ino: 0x%X got i\n", ino->uuid); /* blockTable now points to the start of the content page */ len -= nBytes; at += nBytes; buf += nBytes; } return RC_OK;}voidgrow_inode_table(server_state *ss){ int i; DEBUG(inogrow) kdprintf(KR_OSTREAM, "ino: growing inode table\n"); { /* Extends the file with a new zero page: */ uint32_t **ppPage = find_file_page(ss, &ss->root, ss->root.u.sz, GROW); uint32_t *pPage = *ppPage; ino_s *pIno = (ino_s *) pPage; for (i = 0; i < BLOCK_SIZE / sizeof(ino_s); i++) pIno[i].u.nxt_free = &pIno[i+1]; pIno[i-1].u.nxt_free = 0; ss->first_free_inode = &pIno[0]; }}uint32_tcreate_new_file(server_state *ss, ino_s** outFile){ ino_s *newfile; if (ss->first_free_inode == 0) grow_inode_table(ss); /* Now have at least one free inode */ newfile = ss->first_free_inode; ss->first_free_inode = newfile->u.nxt_free; bzero(newfile, sizeof(*newfile)); *outFile = newfile; newfile->nLayer = 0; newfile->uuid = ss->nxt_uuid; ss->nxt_uuid++; DEBUG(ino) kdprintf(KR_OSTREAM, "ino: created new file ino=0x%x with uuid 0x%X\n", newfile, newfile->uuid); return RC_OK;}uint32_tmake_file_seg(ino_s* ino){ uint32_t result; struct nk_value_s myKeyval; result = spcbank_buy_nodes(KR_BANK, 1, KR_CURFILE, KR_VOID, KR_VOID); if (result != RC_OK) return result; #ifdef KT_Wrapper /* Set up the format key for the red segment. Use SEND_NODE so that it is easy to delete the file when we need to. */ myKeyval.value[0] = WRAPPER_SEND_NODE | WRAPPER_SEND_WORD | WRAPPER_KEEPER; /* Any valid BLSS will do, since there are no initial slots. */ WRAPPER_SET_BLSS(myKeyval, 0); myKeyval.value[1] = (uint32_t)ino; /* pointer to /ino/ */ myKeyval.value[2] = 0; /* new node is in /KR_CURFILE/. fill it with the information */ result = node_write_number(KR_CURFILE, WrapperFormat, &myKeyval); result = node_swap(KR_CURFILE, WrapperKeeper, KR_FILESTART, KR_VOID); /* now we have everything set up -- make the segment key */ result = node_make_wrapper_key(KR_CURFILE, 0, KR_CURFILE);#else /* Set up the format key for the red segment. Use SEND_NODE so that it is easy to delete the file when we need to. */ myKeyval.value[0] = 0; REDSEG_SET_INITIAL_SLOTS(myKeyval, 0); REDSEG_SET_KPR_SLOT(myKeyval, RedSegKeeper); REDSEG_SET_BG_SLOT(myKeyval, RedSegFormat); /* none */ REDSEG_SET_SENDNODE(myKeyval, REDSEG_SEND_NODE); /* Any valid BLSS will do, since there are no initial slots. */ REDSEG_SET_BLSS(myKeyval, EROS_PAGE_BLSS+1); myKeyval.value[1] = (uint32_t)ino; /* pointer to /ino/ */ myKeyval.value[2] = 0; /* new node is in /KR_CURFILE/. fill it with the information */ result = node_write_number(KR_CURFILE, RedSegFormat, &myKeyval); result = node_swap(KR_CURFILE, RedSegKeeper, KR_FILESTART, KR_VOID); /* now we have everything set up -- make the segment key */ result = node_make_segment_key(KR_CURFILE, RedSegBLSS, KR_CURFILE);#endif return RC_OK;}voidreclaim_ino_pages(server_state *ss, uint32_t lvl, uint32_t *blockTable){ if (lvl) { int i; for (i = 0; i < BLOCK_SIZE/sizeof(uint32_t); i++) reclaim_ino_pages(ss, lvl - 1, (uint32_t *) blockTable[i]); } if (blockTable) { DEBUG(free) kdprintf(KR_OSTREAM, "Freeing pg 0x%x\n", blockTable); *blockTable = (uint32_t) ss->first_free_block; ss->first_free_block = blockTable; }}uint32_tdestroy_file(server_state *ss, ino_s *ino){ int i; uint32_t result; result = spcbank_return_node(KR_BANK, KR_CURFILE); for (i = 0; i < INO_NINDIR; i++) reclaim_ino_pages(ss, ino->nLayer, ino->indir[i]); ino->u.nxt_free = ss->first_free_inode; ss->first_free_inode = ino; return result;}intProcessRequest(Message *msg, server_state *ss){ uint32_t result = RC_OK; msg->snd_key0 = KR_VOID; msg->snd_len = 0; /* until proven otherwise */ msg->snd_w1 = 0; msg->snd_w2 = 0; msg->snd_w3 = 0; switch(msg->rcv_code) { case OC_NFile_Create: { ino_s *newFile; DEBUG(req) kdprintf(KR_OSTREAM, "NFILE: create\n"); result = create_new_file(ss, &newFile); if (result != RC_OK) break; result = make_file_seg(newFile); if (result != RC_OK) break; msg->snd_key0 = KR_CURFILE; break; } case OC_NFile_Destroy: { ino_s *ino = (ino_s *)msg->rcv_w1; DEBUG(req) kdprintf(KR_OSTREAM, "NFILE: ino 0x%X destroy\n", ino->uuid); result = destroy_file(ss, ino); break; } case OC_NFile_Read: { ino_s *ino = (ino_s *)msg->rcv_w1; f_size_t len = msg->rcv_w2; f_size_t at = msg->rcv_w3; DEBUG(req) kdprintf(KR_OSTREAM, "NFILE: ino 0x%X read %d at %d\n", ino->uuid, len, at); result = read_from_file(ss, ino, at, &len, ss->buf); msg->snd_data = &ss->buf; msg->snd_len = len; break; } case OC_NFile_Write: { ino_s *ino = (ino_s *)msg->rcv_w1; f_size_t len = msg->rcv_len; f_size_t at = msg->rcv_w3; DEBUG(req) kdprintf(KR_OSTREAM, "NFILE: ino 0x%X write %d at %d\n", ino->uuid, len, at);#if 1 result = write_to_file(ss, ino, at, len, ss->buf);#endif msg->snd_w1 = len; break; } default: DEBUG(req) kdprintf(KR_OSTREAM, "NFILE: unknown request %x (%d)\n", msg->rcv_code, msg->rcv_code); result = RC_UnknownRequest; break; } msg->snd_code = result; return 1;}intmain(){ Message msg; server_state ss; init(&ss); process_make_start_key(KR_SELF, 0, KR_SCRATCH); process_make_start_key(KR_SELF, 1, KR_FILESTART); msg.snd_invKey = KR_RETURN; msg.snd_key0 = KR_SCRATCH; msg.snd_key1 = KR_VOID; msg.snd_key2 = KR_VOID; msg.snd_key3 = KR_VOID; msg.snd_data = 0; msg.snd_len = 0; msg.snd_code = 0; msg.snd_w1 = 0; msg.snd_w2 = 0; msg.snd_w3 = 0; msg.rcv_key0 = KR_VOID; msg.rcv_key1 = KR_VOID; msg.rcv_key2 = KR_CURFILE; msg.rcv_key3 = KR_RETURN; msg.rcv_data = ss.buf; msg.rcv_code = 0; msg.rcv_w1 = 0; msg.rcv_w2 = 0; msg.rcv_w3 = 0; do {#ifdef FLIP_BUF msg.rcv_data = ss.buf;#endif msg.rcv_len = BUF_SZ; RETURN(&msg); msg.snd_len = 0; /* unless it's a read, in which case ProcessRequest() will reset this. */ msg.snd_invKey = KR_RETURN; } while ( ProcessRequest(&msg, &ss) ); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -