void Unmount(void) { /* * precondition : usage ) Unmount(void); * postcondition : 가상 디스크의 파일 시스템을 종료한다. * 메모리상에 있는 버퍼에 변경된 데이터와 메타데이터를 디스크와 * 동기화 하고 언마운트 한다. */ int i = 0; Buf* pBuf = NULL; // fileSysInfo 갱신 pBuf = BufRead(0); BufWrite(pBuf, &fileSysInfo, sizeof(fileSysInfo) - sizeof(char*) * 2); // fileSysInfo.pInodeBitmap 갱신 for ( i = fileSysInfo.inodeBitmapStart ; i < fileSysInfo.inodeBitmapStart + inodeBitmapSize ; i++ ) { pBuf = BufRead(i); BufWrite(pBuf, fileSysInfo.pInodeBitmap + (i - fileSysInfo.inodeBitmapStart) * BLOCK_SIZE, 512); } // fileSysInfo.pBlockBitmap 갱신 for ( i = fileSysInfo.blockBitmapStart ; i < fileSysInfo.blockBitmapStart + blockBitmapSize ; i++ ) { pBuf = BufRead(i); BufWrite(pBuf, fileSysInfo.pBlockBitmap + (i - fileSysInfo.blockBitmapStart) * BLOCK_SIZE, 512); } BufSync(); }
void MapInit( void ) /*************************/ { char tim[8 + 1]; char dat[8 + 1]; char *ptr; struct tm *localt; char *msg; Absolute_Seg = FALSE; Buffering = FALSE; // buffering on/off. if( (MapFlags & MAP_FLAG) == 0 ) return; MapFile = QOpenRW( MapFName ); StartMapBuffering(); localt = localtime( &StartT ); MapCol = 0; msg = MsgStrings[PRODUCT]; BufWrite( msg, strlen( msg ) ); WriteMapNL( 1 ); msg = MsgStrings[COPYRIGHT]; BufWrite( msg, strlen( msg ) ); WriteMapNL( 1 ); msg = MsgStrings[COPYRIGHT2]; BufWrite( msg, strlen( msg ) ); WriteMapNL( 1 ); ptr = tim; ptr = PutDec( ptr, localt->tm_hour ); *ptr++ = ':'; ptr = PutDec( ptr, localt->tm_min ); *ptr++ = ':'; ptr = PutDec( ptr, localt->tm_sec ); *ptr = '\0'; ptr = dat; ptr = PutDec( ptr, localt->tm_year ); *ptr++ = '/'; ptr = PutDec( ptr, localt->tm_mon + 1 ); *ptr++ = '/'; ptr = PutDec( ptr, localt->tm_mday ); *ptr = '\0'; LnkMsg( MAP+MSG_CREATED_ON, "12", dat, tim ); StopMapBuffering(); }
void WriteDirBlock(DirBlock* dirBlock, int blockNo) { /* * precondition : * postcondition : 인자 blockNo는 dirBlock의 block number이다. * dirBlock을 디스크에 저장한다. */ Buf* pBuf = NULL; pBuf = BufRead(blockNo); BufWrite(pBuf, dirBlock, sizeof(DirBlock)); }
void WriteInode(InodeInfo* inodeInfo, int inodeNo) { /* * precondition : * postcondition : 인자 inodeNo는 inodeInfo의 inode number이다. * inodeInfo를 디스크에 저장한다. */ Buf* pBuf = NULL; void* pMem = malloc(BLOCK_SIZE); InodeInfo* pCur = pMem; int block = fileSysInfo.inodeListStart + inodeNo / NUM_OF_INODE_IN_1BLK; int inode = inodeNo % NUM_OF_INODE_IN_1BLK; pBuf = BufRead(block); memcpy(pMem, pBuf->pMem, BLOCK_SIZE); pCur = pCur + inode; memcpy(pCur, inodeInfo, sizeof(InodeInfo)); BufWrite(pBuf, pMem, BLOCK_SIZE); free(pMem); }
void Mount(MountType type) { /* * precondition : usage ) Mount(MT_TYPE_FORMAT); * postcondition : 가상 디스크의 파일 시스템을 초기화 한다. * (1) MT_TYPE_FORMAT : 가상 디스크, 즉, 디스크를 에뮬레이션할 파일을 생성하고, * 그 파일을 파일 시스템이 인식할 수 있도록 organize 함. * 즉, 디스크 포맷처럼 가상 디스크 역할을 담당하는 파일 내에 * superblock, inode bitmap, block bitmap, inode list * 등을 초기화한다. 이때, 생성될 가상디스크의 크기는 10MB로 한다. * (2) MT_TYPE_READWRITE : MT_TYPE_FORMAT과 달리 가상 디스크를 포맷하지 않으며, * 파일 시스템 unmount 되기 이전의 디스크 사용 상태를 유지시키면서 * 파일 시스템을 초기화한다. 이때, 내부적으로 가상 디스크용 파일을 * 리눅스의 “open” system call을 사용하여 파일 열기를 수행하며, * file system info, inode bitmap, block bitmap을 * 정의된 in-memory data structure에 load한다. */ int i = 0; Buf* pBuf = NULL; InodeInfo inodeInfo; DirBlock dirBlock; ////////////////////////////////////////////////////////////////////// // 모두 block 단위임 inodeBitmapSize = (FS_INODE_COUNT / 8/*1byte*/ / BLOCK_SIZE == 0) ? 1 : (int)(ceil((double)FS_INODE_COUNT / (double)8 / (double)BLOCK_SIZE));// FS_INODE_COUNT / 8/*1byte*/ / BLOCK_SIZE + 1; // block 단위 inodeListSize = (int)(ceil((double)FS_INODE_COUNT / (double)NUM_OF_INODE_IN_1BLK)); // block 단위 dataRegionSize = (FS_DISK_CAPACITY / BLOCK_SIZE - 1/*FileSysInfo block*/ /* - 1*//*BlockBitmap block*/ - (double)inodeBitmapSize - (double)inodeListSize); blockBitmapSize = ceil(dataRegionSize / 8/*1byte*/ / BLOCK_SIZE); // block 단위 dataRegionSize = dataRegionSize - blockBitmapSize; // ////////////////////////////////////////////////////////////////////// memset(&fileDescTable, NULL, sizeof(FileDescTable)); Init(); // 버퍼캐시 생성 및 초기화 switch(type) { case MT_TYPE_FORMAT: DevInit(); // 디스크 초기화 fileSysInfo.blocks = BLOCK_SIZE; fileSysInfo.rootInodeNum = 0; // 수정해야함 fileSysInfo.diskCapacity = dataRegionSize; // 수퍼블락을 제외한 순수 data rigion의 블록사이즈 fileSysInfo.numAllocBlocks = 0; fileSysInfo.numFreeBlocks = fileSysInfo.diskCapacity; fileSysInfo.numInodes = FS_INODE_COUNT; fileSysInfo.numAllocInodes = 0; fileSysInfo.numFreeInodes = FS_INODE_COUNT; fileSysInfo.inodeBitmapStart = 1; // inode bitmap이 저장된 블록번호 fileSysInfo.blockBitmapStart = fileSysInfo.inodeBitmapStart + inodeBitmapSize; // block bitmap이 저장된 블록 번호 fileSysInfo.inodeListStart = fileSysInfo.blockBitmapStart + blockBitmapSize; // inode list를 저장하는 영역의 시작 블록 번호 fileSysInfo.dataStart = fileSysInfo.inodeListStart + inodeListSize; // data region의 시작 블록 번호 fileSysInfo.pInodeBitmap = malloc(inodeBitmapSize * BLOCK_SIZE); fileSysInfo.pBlockBitmap = malloc((int)blockBitmapSize * BLOCK_SIZE); memset(fileSysInfo.pInodeBitmap, 0xFF, inodeBitmapSize * BLOCK_SIZE); memset(fileSysInfo.pBlockBitmap, 0xFF, (int)blockBitmapSize * BLOCK_SIZE); memset(&inodeInfo, 0x0, sizeof(InodeInfo)); memset(&dirBlock, 0x0, sizeof(DirBlock)); //////////////////////////////////////////////////// // root 생성 // // inode 데이터 대입 inodeInfo.size = 0; inodeInfo.type = FILE_TYPE_DIR; inodeInfo.mode = FILE_MODE_READONLY; inodeInfo.blocks = 1; inodeInfo.i_block[0] = fileSysInfo.dataStart; // inode 저장 pBuf = BufRead(fileSysInfo.inodeListStart); BufWrite(pBuf, &inodeInfo, sizeof(InodeInfo)); // inode 사용현황 변경 if ( SetInodeFreeToAlloc() == WRONG_VALUE ) fprintf(stderr, "* SetInodeFreeToAlloc() error!\n"); // Directory Block 생성 strncpy(dirBlock.dirEntries[0].name, ".", NAME_LEN_MAX); dirBlock.dirEntries[0].inodeNum = 0; dirBlock.dirEntries[0].type = FILE_TYPE_DIR; // dir block 저장 pBuf = BufRead(fileSysInfo.dataStart); BufWrite(pBuf, &dirBlock, sizeof(DirBlock)); // block 사용현황 변경 if ( SetBlockFreeToAlloc() == WRONG_VALUE ) fprintf(stderr, "* SetBlockFreeToAlloc() error!\n"); // //////////////////////////////////////////////////// break; case MT_TYPE_READWRITE: // 버퍼캐시 생성 및 초기 DevLoad(); // 디스크 로 pBuf = BufRead(0); /* FileSysInfo */ memcpy(&fileSysInfo, pBuf->pMem, sizeof(fileSysInfo) - sizeof(char*) * 2 /*포인터변수 2개*/); fileSysInfo.pInodeBitmap = malloc(inodeBitmapSize * BLOCK_SIZE); fileSysInfo.pBlockBitmap = malloc((int)blockBitmapSize * BLOCK_SIZE); memset(fileSysInfo.pInodeBitmap, NULL, inodeBitmapSize * BLOCK_SIZE); memset(fileSysInfo.pBlockBitmap, NULL, (int)blockBitmapSize * BLOCK_SIZE); // inodeBitmap 로드 for ( i = fileSysInfo.inodeBitmapStart ; i < fileSysInfo.inodeBitmapStart + inodeBitmapSize ; i++ ) { pBuf = BufRead(i); memcpy(fileSysInfo.pInodeBitmap + (i - fileSysInfo.inodeBitmapStart) * BLOCK_SIZE, pBuf->pMem, BLOCK_SIZE); } // blockBitmap 로드 for ( i = fileSysInfo.blockBitmapStart ; i < fileSysInfo.blockBitmapStart + blockBitmapSize ; i++ ) { pBuf = BufRead(i); memcpy(fileSysInfo.pBlockBitmap + (i - fileSysInfo.blockBitmapStart) * BLOCK_SIZE, pBuf->pMem, BLOCK_SIZE); } break; } }
int WriteFile(int fileDesc, char* pBuffer, int length) { /* * precondition : usage) WriteFile(fileDesc, pBuffer, length); * fileDesc : file descriptor * pBuffer : 저장할 데이터를 포함하는 메모리의 주소 * length : 저장될 데이터의 길이 * postcondition : open된 파일에 데이터를 저장한다. * 성공하면 저장된 데이터의 길이 값을 리턴한다. 실패 했을때는 -1을 리턴한다. */ int i = 0, j = 0; int block = fileDescTable.file[fileDesc].offset / BLOCK_SIZE; int offset = fileDescTable.file[fileDesc].offset % BLOCK_SIZE; int exsist = 0; int remain = length; char buf[BLOCK_SIZE] = {NULL,}; Buf* pBuf = NULL; InodeInfo inodeInfo; DirBlock dirBlock; if ( fileDescTable.file[fileDesc].valid_bit != 1 ) return WRONG_VALUE; ReadInode(&inodeInfo, fileDescTable.file[fileDesc].inodeNo); // lseek 함수가 없기 때문에 inode에 저장된 indirect block 갯수보다 // 위에서 계산된 block(fd[].offset / BLOCK_SIZE)이 클수가 없음 // 따라서 예외처리 안해도 됨 // 첫번째 블락에 pBuffer 쓰기 pBuf = BufRead(inodeInfo.i_block[block]); memcpy(&buf, pBuf->pMem, BLOCK_SIZE); memcpy(&buf + offset, pBuffer, (remain + offset >= BLOCK_SIZE) ? BLOCK_SIZE - offset : remain); BufWrite(pBuf, &buf, BLOCK_SIZE); if ( inodeInfo.size < (remain - offset) ) inodeInfo.size = remain - offset; fileDescTable.file[fileDesc].offset += (remain + offset >= BLOCK_SIZE) ? BLOCK_SIZE - offset : remain; remain -= (BLOCK_SIZE - offset); if ( remain <= 0 ) return length; // 두번째 블락부터 pBuffer 쓰기 for ( j = block + 1 ; j < (length / BLOCK_SIZE + 1) + block ; j++ ) { // inodeInfo.blocks가 모자르면 새로 할당해줘야함 if ( j == inodeInfo.blocks && inodeInfo.blocks < NUM_OF_INDIRECT_BLOCK ) { inodeInfo.i_block[inodeInfo.blocks++] = GetFreeBlock(); SetBlockFreeToAlloc(); } if ( j == NUM_OF_INDIRECT_BLOCK ) { // indirect block 부족으로 쓰기 실패 WriteInode(&inodeInfo, fileDescTable.file[fileDesc].inodeNo); return length - remain; } pBuf = BufRead(inodeInfo.i_block[j]); BufWrite(pBuf, pBuffer + BLOCK_SIZE * ((j - (block + 1) + 1)), remain > BLOCK_SIZE ? BLOCK_SIZE : remain); fileDescTable.file[fileDesc].offset += (remain > BLOCK_SIZE ? BLOCK_SIZE : remain); remain = remain - BLOCK_SIZE; if ( remain <= 0 ) { inodeInfo.size += BLOCK_SIZE + remain; WriteInode(&inodeInfo, fileDescTable.file[fileDesc].inodeNo); return length; } else inodeInfo.size += BLOCK_SIZE; } return 0; }
void HttpcHandleContent(USHORT sLen, PCHAR pBuf) { UCHAR iVal; USHORT sLeftLen, sLen2; if (_sHttpcRespCode != 200) { goto SkipContent; } if (_iHttpcTask == HTTPC_TASK_GET_PROV || _iHttpcTask == HTTPC_TASK_GET_CFG || _iHttpcTask == HTTPC_TASK_CFG_AUTH) { sLen2 = sLen; if (_bHttpcEncrypt) { TaskRC4Calc(pBuf, pBuf, sLen2); } while (sLen2 --) { iVal = *pBuf ++; if (iVal == 0x0d || iVal == 0x0a) { if (_iHttpcTask == HTTPC_TASK_GET_PROV) { HandleProvParam(); } else { HttpcHandleSettings(); } } else if (iVal != (UCHAR)'"') { HttpcSaveRecv(iVal); } } goto SkipContent; } if (_iHttpcTask == HTTPC_TASK_GET_SW) { if (_iHttpcUpdatePage == SYSTEM_INVALID_PAGE) goto SkipContent; sLeftLen = FILE_FULL_PAGE_SIZE - _sHttpcPostLen; if (sLen < sLeftLen || !sLeftLen) { BufWrite(pBuf, sLen); BufForward(sLen); _sHttpcPostLen += sLen; } else { BufWrite(pBuf, sLeftLen); BufForward(sLeftLen); _sHttpcPostLen = 0; TaskUIHandler(UI_UPDATE_PROGRESS, (USHORT)_iHttpcCurPage); if (FlashWritePage(_iHttpcCurPage)) { _iHttpcUpdatePage = SYSTEM_INVALID_PAGE; goto SkipContent; } _iHttpcCurPage ++; if ((_iHttpcCurPage - _iHttpcUpdatePage) >= SYSTEM_PROGRAM_PAGE_NUM) { TaskSystemHandler(SYS_UPDATE_FLAG, _iHttpcCurPage); _iHttpcTask = HTTPC_TASK_REBOOT; } else { sLen2 = (USHORT)(sLen - sLeftLen); BufSeek(0); BufWrite((PCHAR)(pBuf + sLeftLen), sLen2); BufForward(sLen2); _sHttpcPostLen = sLen2; } } } SkipContent: if (_lHttpcContentLen > (ULONG)sLen) { _lHttpcContentLen -= (ULONG)sLen; } else { _lHttpcContentLen = 0; HttpcNextTask(); } }