/*The allocate works in this way:
At the beginning, no block is allocated, we need to find the free address,
we use GetAddrOfOffset().
As time goes by, more and more blocks are allocated using the above method,
until when some blocks are freed by user, then GetFreeBlock() can get a
second hand block, we just need to clear the memory to put it into use again.
 */
void* FixedMemPool::Alloc(bool zero) {
    AllocBlock* p = GetFreeBlock();
    if (p == NULL) {
        //can not find free block, we need to allocate from the pool
        if (m_header->used_size + m_header->block_size <= m_header->max_size) {
            p = (AllocBlock*)GetAddrOfOffset(m_header->used_size);
            //a new block is used
            m_header->used_size += m_header->block_size;
            m_header->used_node_num++;
        } else {
            snprintf(m_error_msg, sizeof(m_error_msg), "Alloc() error, No space left in the pool");
        }
    } else if (!IsValidBlock(p)){
        snprintf(m_error_msg, sizeof(m_error_msg), "Alloc() error, wrong free block format");
        p = NULL;
    }

    if (p == NULL) {
        return NULL;
    }

    //if use former freed block, reset the memory
    if (zero) {
        memset(p, 0, m_header->block_size);
    }

    //0 mean p is not in the free list
    p->next = 0;
    return p->node;
}
Example #2
0
int bd_read(const char *pFilename, char *buffer, int offset, int numbytes) {

  iNodeEntry *pInode = alloca(sizeof(*pInode));
  const int inode = GetINodeFromPath(pFilename, &pInode);
  if (inode == -1) {
    printf("Le fichier %s est inexistant!\n", pFilename);
    return -1;
  }
 
  if (pInode->iNodeStat.st_mode & G_IFDIR) {
    printf("Le fichier %s est un repertoire!\n", pFilename);
    return -2;
  }

  if (pInode->iNodeStat.st_size < offset) {
    return 0;
  }

  const size_t firstBlock = offset / BLOCK_SIZE;
  const size_t offsetFirstBlock = offset % BLOCK_SIZE;
  const size_t sizeToRead = min(pInode->iNodeStat.st_size - offset, numbytes);
  const size_t lastBlock = (sizeToRead + offset) / BLOCK_SIZE;
  const size_t offsetLastBlock = (sizeToRead + offset) % BLOCK_SIZE;  

  size_t length[N_BLOCK_PER_INODE] = {[0 ... N_BLOCK_PER_INODE - 1] = BLOCK_SIZE};
  length[lastBlock] = offsetLastBlock;
  length[firstBlock] = min(BLOCK_SIZE - offsetFirstBlock, sizeToRead);

  size_t readOffset[N_BLOCK_PER_INODE] = {[0 ... N_BLOCK_PER_INODE - 1] = 0};
  readOffset[firstBlock] = offsetFirstBlock;

  size_t i, writeOffset = 0;
  for (i = firstBlock; (i <= lastBlock) && (i < N_BLOCK_PER_INODE); ++i) {
    char *dataBlock = alloca(BLOCK_SIZE);
    if (ReadBlock(pInode->Block[i], dataBlock) == -1)
      return -1;
    memcpy(&buffer[writeOffset], &dataBlock[readOffset[i]], length[i]);
    writeOffset += length[i];
  }
  return sizeToRead;
}

int bd_write(const char *pFilename, const char *buffer, int offset, int numbytes) {

  iNodeEntry *pInode = alloca(sizeof(*pInode));
  const int inode = GetINodeFromPath(pFilename, &pInode);
  if (inode == -1) {
    printf("Le fichier %s est inexistant!\n", pFilename);
    return -1;
  }
 
  if (pInode->iNodeStat.st_mode & G_IFDIR) {
    printf("Le fichier %s est un repertoire!\n", pFilename);
    return -2;
  }

  if (offset > pInode->iNodeStat.st_size) {
    printf("L'offset demande est trop grand!\n");
    return -3;
  }

  const size_t maxFileSize = N_BLOCK_PER_INODE * BLOCK_SIZE;
  if (offset >= maxFileSize) {
    printf("Taille trop grande (offset=%ld) pour le fichier %s!\n", maxFileSize, pFilename);
    return -4;
  }
  if ((numbytes + offset) > maxFileSize) {
    printf("Le fichier %s deviendra trop gros!\n", pFilename);
  }

  const size_t firstBlock = offset / BLOCK_SIZE;
  const size_t offsetFirstBlock = offset % BLOCK_SIZE;
  const size_t sizeToWrite = min(numbytes, maxFileSize - offset);
  const size_t lastBlock = (sizeToWrite + offset) / BLOCK_SIZE;
  const size_t offsetLastBlock = (sizeToWrite + offset) % BLOCK_SIZE;
  
  size_t length[N_BLOCK_PER_INODE] = {[0 ... N_BLOCK_PER_INODE - 1] = BLOCK_SIZE};
  length[lastBlock] = offsetLastBlock;
  length[firstBlock] = min(BLOCK_SIZE - offsetFirstBlock, sizeToWrite);

  size_t writeOffset[N_BLOCK_PER_INODE] = {[0 ... N_BLOCK_PER_INODE - 1] = 0};
  writeOffset[firstBlock] = offsetFirstBlock;

  size_t i, readOffset = 0;
  for (i = firstBlock; (i <= lastBlock) && (i < N_BLOCK_PER_INODE); ++i) {
    if (i >= pInode->iNodeStat.st_blocks) {
      int block = 0;
      if ((block = GetFreeBlock()) == -1)
        return -1;
      pInode->Block[i] = block;
      pInode->iNodeStat.st_blocks++;
    }

    char *dataBlock = alloca(BLOCK_SIZE);
    if (ReadBlock(pInode->Block[i], dataBlock) == -1)
      return -1;

    memcpy(&dataBlock[writeOffset[i]], &buffer[readOffset], length[i]);

    if (WriteBlock(pInode->Block[i], dataBlock) == -1)
      return -1;
    readOffset += length[i];
  }

  pInode->iNodeStat.st_size = max(pInode->iNodeStat.st_size, offset + sizeToWrite);
  if (WriteINodeToDisk(pInode) == -1)
    return -1;

  return sizeToWrite;
}

int bd_mkdir(const char *pDirName) {

  char pathOfDir[PATH_SIZE];
  if (GetDirFromPath(pDirName, pathOfDir) == 0)
    return -1;

  char dirName[PATH_SIZE];
  if (GetFilenameFromPath(pDirName, dirName) == 0 || strlen(dirName) > FILENAME_SIZE)
    return -1;

  iNodeEntry *pDirInode = alloca(sizeof(*pDirInode));
  if (GetINodeFromPath(pathOfDir, &pDirInode) == -1 || pDirInode->iNodeStat.st_mode & G_IFREG)
    return -1;
  const size_t nDir = NumberofDirEntry(pDirInode->iNodeStat.st_size);
  if (((nDir + 1) * sizeof(DirEntry)) > BLOCK_SIZE)
    return -1;
  iNodeEntry *pChildInode = alloca(sizeof(*pChildInode));
  if (GetINodeFromPath(pDirName, &pChildInode) != -1)
    return -2;

  if (GetFreeINode(&pChildInode) == -1)
    return -1;

  char dataBlock[BLOCK_SIZE];
  DirEntry *pDirEntry = (DirEntry*)dataBlock;
  strcpy(pDirEntry[0].Filename, ".");
  strcpy(pDirEntry[1].Filename, "..");
  pDirEntry[0].iNode = pChildInode->iNodeStat.st_ino;
  pDirEntry[1].iNode = pDirInode->iNodeStat.st_ino;
  const int idBlocDir = GetFreeBlock();
  if (idBlocDir == -1) {
    ReleaseINodeFromDisk(pChildInode->iNodeStat.st_ino);
    return -1;
  }
  if (WriteBlock(idBlocDir, dataBlock) == -1) {
    ReleaseINodeFromDisk(pChildInode->iNodeStat.st_ino);
    ReleaseBlockFromDisk(idBlocDir);
    return -1;
  }

  pChildInode->iNodeStat.st_mode |= G_IFDIR | G_IRWXU | G_IRWXG;
  pChildInode->iNodeStat.st_nlink = 2;
  pChildInode->iNodeStat.st_size = 2 * sizeof(DirEntry);
  pChildInode->iNodeStat.st_blocks = 1;
  pChildInode->Block[0] = idBlocDir;
  if (WriteINodeToDisk(pChildInode) == -1) {
    ReleaseINodeFromDisk(pChildInode->iNodeStat.st_ino);
    ReleaseBlockFromDisk(idBlocDir);
    return -1;
  }

  pDirInode->iNodeStat.st_nlink++;

  if (AddINodeToINode(dirName, pChildInode, pDirInode) == -1) {
    ReleaseINodeFromDisk(pChildInode->iNodeStat.st_ino);
    ReleaseBlockFromDisk(idBlocDir);
    return -1;
  }
  return 0;
}
Example #3
0
static int __create_file(tiny_inode *parent_inode, const char *name)
{
	int qid = OpenMQ(5000);
	tiny_inode target;
	tiny_dirblk tmp_dirblk;
	int target_inodeno;
	int parent_inodeno;
	int i, j;

	// 1. get inode number
	target_inodeno = GetFreeInode();
	if ( SetInodeFreeToAlloc() == -1 ) {
		goto __create_file_success;
	}

	target.i_nblk = 0;
	target.i_size = 0;
	target.i_type = FILE_TYPE_FILE;

	// 2. write a inode entry into inode block
	WriteInode(&target, target_inodeno);

	// 3. find a empty place for dentry
	for ( i = 0 ; i < parent_inode->i_nblk ; i++ ) {
		ReadDirBlock(&tmp_dirblk, parent_inode->i_block[i]);
		for ( j = 0 ; j < NUM_OF_DIRENT_IN_1BLK ; j++ ) {
			if ( i == 0 && j == 0 ) {
				parent_inodeno = tmp_dirblk.dirEntries[0].inodeNum;
			}
			if ( strcmp(tmp_dirblk.dirEntries[j].name, "") == 0 ) {
				tmp_dirblk.dirEntries[j].inodeNum = target_inodeno;
				tmp_dirblk.dirEntries[j].type = FILE_TYPE_FILE;
				strncpy(tmp_dirblk.dirEntries[j].name, name, NAME_LEN_MAX - 1);
				tmp_dirblk.dirEntries[j].name[NAME_LEN_MAX - 1] = '\0';
				WriteDirBlock(&tmp_dirblk, parent_inode->i_block[i]);
				goto __create_file_success;
			}
		}
	}

	//TODO: allocate new i_block
	if ( parent_inode->i_nblk != TINY_N_DIRECT_BLOCKS ) {
		parent_inode->i_block[parent_inode->i_nblk++] = GetFreeBlock();
		SetBlockFreeToAlloc();

		ReadDirBlock(&tmp_dirblk, 
				parent_inode->i_block[parent_inode->i_nblk-1]);
		tmp_dirblk.dirEntries[0].inodeNum = target_inodeno;
		tmp_dirblk.dirEntries[0].type = FILE_TYPE_FILE;
		strncpy(tmp_dirblk.dirEntries[0].name, name, NAME_LEN_MAX - 1);
		tmp_dirblk.dirEntries[0].name[NAME_LEN_MAX - 1] = '\0';
		WriteDirBlock(&tmp_dirblk, 
				parent_inode->i_block[parent_inode->i_nblk-1]);
		WriteInode(parent_inode, parent_inodeno);

		goto __create_file_success;
	}

	// err: already using all i_block -> return NULL;
	// error occured!
__create_file_failed:
	SetInodeAllocToFree(target_inodeno);

__create_file_success:

	if(qid < 0)
	{
		printf("q open fail\n");
		return ;
	}

	SuperBlk_t sb;
	sb.fsi = tiny_superblk;
	if(SendMQ(qid, MSG_SUPER_BLOCK, &sb) < 0)
	{
		printf("superblk send fail\n");
		return ;
	}

	InodeBitmap_t ibm;
	ibm.size = tiny_superblk.s_ninode / 8; /*byte*/
	memcpy(ibm.s_ibitmap_ptr, tiny_superblk.s_ibitmap_ptr, ibm.size);
	if(SendMQ(qid, MSG_INODE_BITMAP, &ibm) < 0)
	{
		printf("ibm send fail\n");
		return ;
	}

	BlockBitmap_t bbm;
	bbm.size = tiny_superblk.s_datablk_size / 8;  /*byte*/
	memcpy(bbm.s_dbitmap_ptr, tiny_superblk.s_dbitmap_ptr, bbm.size);
	if(SendMQ(qid, MSG_BLOCK_BITMAP, &bbm) < 0)
	{
		printf("bbm send fail\n");
		return ;
	}

	FileIO_t fio;
	memcpy(&fio.inode, &target, sizeof(tiny_inode));
	fio.dentry.inodeNum = target_inodeno;
	fio.flag = 'w';
	if(SendMQ(qid, MSG_FILEIO, &fio) < 0)
	{
		printf("fio send fail\n");
		return ;
	}
	return target_inodeno;
}
Example #4
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 #5
0
int MakeDirentry(InodeInfo* inodeInfo, char* dirname)
{
/*
 * precondition		: inodeInfo != NULL, dirname != NULL
 * postcondition	: 해당 inodeInfo의 indirect block에 directory entry가 생성됨
 * 					  제일 앞쪽부터 찾아 비어있는 directory entry index에 name과 inodeno를 할당
 * 					  free directory entry가 없으면 -1 리턴
*/
	int block = 0;
	int index = 0;
	int	parent_inodeno = 0;
	int	current_inodeno = 0;
	InodeInfo newInodeInfo;
	DirBlock dirBlock;
	ReadDirBlock(&dirBlock, inodeInfo->i_block[0]);
	parent_inodeno = dirBlock.dirEntries[0].inodeNum;
	for ( block = 0 ; block < inodeInfo->blocks ; block++ )
	{
		ReadDirBlock(&dirBlock, inodeInfo->i_block[block]);
		if (( index = GetFreeDir(&dirBlock)) != WRONG_VALUE)
		{// 비어있는곳을 찾으면
			strcpy(dirBlock.dirEntries[index].name, dirname);
			dirBlock.dirEntries[index].inodeNum = GetFreeInode();
			if ( SetInodeFreeToAlloc() == WRONG_VALUE )		return WRONG_VALUE;
			dirBlock.dirEntries[index].type = FILE_TYPE_DIR;
			current_inodeno = dirBlock.dirEntries[index].inodeNum;
			WriteDirBlock(&dirBlock, inodeInfo->i_block[block]);
			newInodeInfo.blocks = 1;
			newInodeInfo.size = BLOCK_SIZE;
			newInodeInfo.type = FILE_TYPE_DIR;
			newInodeInfo.mode = FILE_MODE_READONLY;
			newInodeInfo.i_block[0] = GetFreeBlock();
			SetBlockFreeToAlloc();
		////////////////////////////////////////////
		//	생성한 directory block 초기화
			ReadDirBlock(&dirBlock, newInodeInfo.i_block[0]);
			strcpy(dirBlock.dirEntries[0].name, ".");
			dirBlock.dirEntries[0].inodeNum = current_inodeno;
			dirBlock.dirEntries[0].type = FILE_TYPE_DIR;
			strcpy(dirBlock.dirEntries[1].name, "..");
			dirBlock.dirEntries[1].inodeNum = parent_inodeno;
			dirBlock.dirEntries[1].type = FILE_TYPE_DIR;
			WriteDirBlock(&dirBlock, newInodeInfo.i_block[0]);
		//
		////////////////////////////////////////////
			WriteInode(&newInodeInfo, current_inodeno);
			return 0;
		}
	}
	if( inodeInfo->blocks < NUM_OF_INDIRECT_BLOCK )
	{// indirect block을 더 생성할 수 있을때
		inodeInfo->blocks++;
		inodeInfo->i_block[inodeInfo->blocks - 1] = GetFreeBlock();
		SetBlockFreeToAlloc();
		WriteInode(inodeInfo, parent_inodeno);
		ReadDirBlock(&dirBlock, inodeInfo->i_block[inodeInfo->blocks - 1]);
		strcpy(dirBlock.dirEntries[0].name, dirname);
		dirBlock.dirEntries[0].inodeNum = GetFreeInode();
		if ( SetInodeFreeToAlloc() == WRONG_VALUE )		return WRONG_VALUE;
		dirBlock.dirEntries[0].type = FILE_TYPE_DIR;
		current_inodeno = dirBlock.dirEntries[0].inodeNum;
		WriteDirBlock(&dirBlock, inodeInfo->i_block[block]);
		newInodeInfo.blocks = 1;
		newInodeInfo.size += BLOCK_SIZE;
		newInodeInfo.type = FILE_TYPE_DIR;
		newInodeInfo.mode = FILE_MODE_READONLY;
		newInodeInfo.i_block[0] = GetFreeBlock();
		SetBlockFreeToAlloc();
	////////////////////////////////////////////
	//	생성한 directory block 초기화
		ReadDirBlock(&dirBlock, newInodeInfo.i_block[0]);
		memset(&dirBlock, 0, sizeof(DirBlock));
		strcpy(dirBlock.dirEntries[0].name, ".");
		dirBlock.dirEntries[0].inodeNum = current_inodeno;
		dirBlock.dirEntries[0].type = FILE_TYPE_DIR;
		strcpy(dirBlock.dirEntries[1].name, "..");
		dirBlock.dirEntries[1].inodeNum = parent_inodeno;
		dirBlock.dirEntries[1].type = FILE_TYPE_DIR;
		WriteDirBlock(&dirBlock, newInodeInfo.i_block[0]);
	//
	////////////////////////////////////////////
		WriteInode(&newInodeInfo, current_inodeno);
		return 0;
	}
	// 모든 indirect block을 사용중이며 또한 모든 directory block에 빈 공간이 없다.
	return WRONG_VALUE;
}
Example #6
0
int	OpenFile(const char* pFileName, OpenFlag flag)
{
/*
 * precondition		: usage) OpenFile(absfilepath, flag);
 * 					  pFileName은 오픈할 파일의 이름. 단, 파일 이름은 절대경로이다.
 * 					  flag는 OPEN_FLAG_READWRITE, OPEN_FLAG_CREATE가 있다.
 * postcondition	: 파일을 open한다.
 *					  성공하면, file descriptor를 리턴한다.
 * 					  이 file descriptor는 file descriptor table의 entry의 index값으로 정의된다.
 * 					  실패했을때는 -1을 리턴한다.
 */
	InodeInfo	inodeInfo, newInode;
	DirBlock	dirBlock;
	char* 	abspath = malloc(strlen(pFileName) + 1);
	char* 	ptr = malloc(strlen(pFileName) + 1);
	char	filename[NAME_LEN_MAX];
	int 	i = 0, j = 0;
	int		found = 0;
	int		fd = 0;
	int		parent_inodeno = 0;
	int		current_inodeno = 0;

	strcpy(abspath, pFileName);
	strcpy(ptr, pFileName);

	memset(&newInode, 0, sizeof(InodeInfo));

	if (*ptr != '/')		// 절대경로의 시작이 '/'가 아닐때
	{
		free(abspath);
		free(ptr);
		return -1;
	}
	// root inode와 block을 읽음
	// filename에 파일 경로를 얻어냄
	if ( GetEntryName(filename, abspath) == WRONG_VALUE)
	{
		fprintf(stderr, "* GetEntryName error!\n");
		fprintf(stderr, "* filename is too long!\n");
	}
	GetEntryPath(abspath, filename);

	ReadInode(&inodeInfo, fileSysInfo.rootInodeNum);
	abspath = strtok(abspath, "/");
	while(abspath)
	{
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			if( inodeInfo.type == FILE_TYPE_DIR ) {
				ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
				for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
				{
					if ( strcmp(dirBlock.dirEntries[j].name, abspath) == 0
							&& dirBlock.dirEntries[j].type == FILE_TYPE_DIR)
					{// 마지막 상위 디렉토리(찾는 파일 또는 디렉토리의 ..)를 찾으면
						ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
						parent_inodeno = dirBlock.dirEntries[j].inodeNum;
						found++;
						break;
					}
				}
				if ( found == 1 )
				{
					found = 0;
					break;
				}
			}
		}
		abspath = strtok(NULL, "/");
	}
	if ( strcmp(filename, "") == 0)	// 파일명이 없으면 실패리턴
	{
		if( i == inodeInfo.blocks )
		{
			free(abspath);
			free(ptr);
			return WRONG_VALUE;	// 블록 전부를 검색했지만 일치하는 결과가 없으므로 실패
		}
		if( found == 0)
		{
			free(abspath);
			free(ptr);
			return WRONG_VALUE; // dir을 못찾았을
		}
	}
	// 여기까지 왔으면 해당 디렉토리 찾은 것
	switch(flag)
	{
	case OPEN_FLAG_READWRITE:
		// 파일명 찾고 permission readwrite로
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			if( inodeInfo.type == FILE_TYPE_DIR )
				ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if ( strcmp(dirBlock.dirEntries[j].name, filename) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_FILE)
				{// 파일명 찾으면
					// permission read로
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					inodeInfo.mode = FILE_MODE_READWRITE;
					for ( fd = 0 ; fd < FS_INODE_COUNT ; fd++ )
					{// 이미 open 했던 경우
						if ( fileDescTable.file[fd].inodeNo == dirBlock.dirEntries[j].inodeNum )
						{
							fileDescTable.file[fd].offset = 0;
							free(abspath);
							free(ptr);
							return fd;
						}
					}
					for ( fd = 0 ; fd < FS_INODE_COUNT ; fd++ )
					{// 처음 open 하는 경우
						if ( fileDescTable.file[fd].valid_bit == 0 )
						{
							fileDescTable.file[fd].inodeNo = dirBlock.dirEntries[j].inodeNum;
							fileDescTable.file[fd].offset = 0;
							fileDescTable.file[fd].valid_bit = 1;
							free(abspath);
							free(ptr);
							return fd;
						}
					}
				}
			}
		}

		break;
	case OPEN_FLAG_CREATE:
		// 파일명 찾고 있으면 덮어쓰고 없으면 생성
		// 파일명 찾고 permission readonly로
		// 파일이 존재할 경우
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			if( inodeInfo.type == FILE_TYPE_DIR )
				ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if ( strcmp(dirBlock.dirEntries[j].name, filename) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_FILE)
				{// 파일명 찾으면
					// permission readwrite로
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					inodeInfo.mode = FILE_MODE_READWRITE;
					for ( fd = 0 ; fd < FS_INODE_COUNT ; fd++ )
					{// 이미 open 했던 경우
						if ( fileDescTable.file[fd].inodeNo == dirBlock.dirEntries[j].inodeNum )
						{
							fileDescTable.file[fd].offset = 0;
							free(abspath);
							free(ptr);
							return fd;
						}
					}
					for ( fd = 0 ; fd < FS_INODE_COUNT ; fd++ )
					{// 처음 open 하는 경우
						if ( fileDescTable.file[fd].valid_bit == 0 )
						{
							fileDescTable.file[fd].inodeNo = dirBlock.dirEntries[j].inodeNum;
							fileDescTable.file[fd].offset = 0;
							fileDescTable.file[fd].valid_bit = 1;
							free(abspath);
							free(ptr);
							return fd;
						}
					}
				}
			}
		}
		// 파일이 없어서 생성해야 하는 경우
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			if( inodeInfo.type == FILE_TYPE_DIR )
				ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if ( strcmp(dirBlock.dirEntries[j].name,"") == 0 )
				{// 엔트리가 비어있으면
					strcpy(dirBlock.dirEntries[j].name, filename);
					dirBlock.dirEntries[j].type = FILE_TYPE_FILE;
					dirBlock.dirEntries[j].inodeNum = GetFreeInode();
					WriteDirBlock(&dirBlock, inodeInfo.i_block[i]); // 변경된 상위디렉토리의 dirBlock 갱신

					newInode.size = 0;
					newInode.type = FILE_TYPE_FILE;
					newInode.mode = FILE_MODE_READWRITE;
					newInode.blocks = 1;
					newInode.i_block[0] = GetFreeBlock();

					WriteInode(&newInode, dirBlock.dirEntries[j].inodeNum);
					SetInodeFreeToAlloc();
					SetBlockFreeToAlloc();
					for ( fd = 0 ; fd < FS_INODE_COUNT ; fd++ )
					{// 파일 디스크립터 생성
						if ( fileDescTable.file[fd].valid_bit == 0 )
						{
							fileDescTable.file[fd].inodeNo = dirBlock.dirEntries[j].inodeNum;
							fileDescTable.file[fd].valid_bit = 1;
							free(abspath);
							free(ptr);
							return fd;
						}
					}
				}
			}
		}
		// 사용 가능한 다이렉트블락이 없다 -> 실패리턴
		if ( inodeInfo.blocks != NUM_OF_INDIRECT_BLOCK )
		{
			// 사용 가능한 다이렉트블락이 있다 -> 진행
			inodeInfo.blocks++;
			inodeInfo.i_block[inodeInfo.blocks-1] = GetFreeBlock();
			SetBlockFreeToAlloc();
			WriteInode(&inodeInfo, parent_inodeno);
		//////////////////////////////////////////////////////////////
		//	생성한 directory block 초기화
			ReadDirBlock(&dirBlock, inodeInfo.i_block[inodeInfo.blocks-1]);
			strcpy(dirBlock.dirEntries[0].name, filename);
			dirBlock.dirEntries[0].inodeNum = GetFreeInode();
			SetInodeFreeToAlloc();
			dirBlock.dirEntries[0].type = FILE_TYPE_FILE;
			WriteDirBlock(&dirBlock, inodeInfo.i_block[inodeInfo.blocks-1]);
			return 0;
		//
		//////////////////////////////////////////////////////////////
		}
		break;
	}
	// 여기까지 왔으면 못찾은것임
	free(abspath);
	free(ptr);
	return WRONG_VALUE;
}