Example #1
0
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();
}
Example #2
0
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();
}
Example #3
0
void WriteDirBlock(DirBlock* dirBlock, int blockNo)
{
/*
 * precondition		:
 * postcondition	: 인자 blockNo는 dirBlock의 block number이다.
 * 					  dirBlock을 디스크에 저장한다.
 */
	Buf* pBuf = NULL;

	pBuf = BufRead(blockNo);
	BufWrite(pBuf, dirBlock, sizeof(DirBlock));
}
Example #4
0
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);
}
Example #5
0
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;
	}
}
Example #6
0
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;
}
Example #7
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();
	}
}