Exemple #1
0
int FreeInode(int dev, int ino)
{
    char buf[BLKSIZE * 2];
    ReadBlock(dev,SUP_BLK_STARTS_AT,buf);
    ReadBlock( dev,SUP_BLK_STARTS_AT+1,buf+BLKSIZE);
    struct SupBlock* sptr= (struct SupBlock*) buf;

    sptr->sb_nfreeino++;

    if (sptr->sb_freeinoindex !=0 ) // if inode list is not full
    {
        sptr->sb_freeinoindex--;
        sptr->sb_freeinos[sptr->sb_freeinoindex]= ino;
    }


    writeSuper(dev,sptr);

    struct INode inode;
    ReadInode(dev,ino,&inode);
    inode.i_lnk=0;
    WriteInode(dev,ino,&inode);
    //return success
    return 0;
}
Exemple #2
0
int RemoveDirentry(InodeInfo* inodeInfo, char* dirname)
{
/*
 * precondition		: inodeInfo != NULL, dirname != NULL
 * postcondition	: dirname은 삭제를 원하는 디렉토리명이며,
 * 					  inodeInfo는 dirname을 가지고 있을 것으로 추정되는 inode이다.
 * 					  성공시 0, 실패시 -1 리턴
*/
	int block = 0, index = 0;
	int	parent_inodeno = 0;
	int	current_inodeno = 0;
	int ret_value = 0;
	int i = 0;
	InodeInfo delInodeInfo;
	InodeInfo nullinode;
	DirBlock dirBlock;
	DirBlock nullblock;
	memset(&nullinode, 0, sizeof(InodeInfo));
	memset(&nullblock, 0, sizeof(DirBlock));

	ReadDirBlock(&dirBlock, inodeInfo->i_block[0]);
	current_inodeno = dirBlock.dirEntries[0].inodeNum;
	parent_inodeno = dirBlock.dirEntries[1].inodeNum;
	for ( block = 0 ; block < inodeInfo->blocks ; block++ )
	{
		ReadDirBlock(&dirBlock, inodeInfo->i_block[block]);
		for ( index = 0 ; index < MAX_INDEX_OF_DIRBLK ; index++ )
		{
			if(strcmp(dirBlock.dirEntries[index].name, dirname) == 0
					&& dirBlock.dirEntries[index].type == FILE_TYPE_DIR)
			{// 지울 디렉토리명을 찾으면
				ReadInode(&delInodeInfo, dirBlock.dirEntries[index].inodeNum);
				if ( (ret_value = DirIsEmpty(&delInodeInfo)) == WRONG_VALUE )
				{
					fprintf(stderr, "dirname is not a DIRECTORY!\n");
					fprintf(stderr, "DirIsEmpty() Error!\n");
				}
				if ( ret_value == TRUE )
				{// 디렉토리가 비어있다. ==> 삭제
					for ( i = 0 ; i < delInodeInfo.blocks ; i++ )
					{
						WriteDirBlock(&nullblock, delInodeInfo.i_block[i]);
						SetBlockAllocToFree(delInodeInfo.i_block[i]);
					}
					WriteInode(&nullinode, dirBlock.dirEntries[index].inodeNum);
					SetInodeAllocToFree(dirBlock.dirEntries[index].inodeNum);
					dirBlock.dirEntries[index].inodeNum = 0;
					strcpy(dirBlock.dirEntries[index].name, "");
					// DirBlock과 InodeInfo 갱신하기
					WriteDirBlock(&dirBlock, inodeInfo->i_block[block]);
					return 0;
				}
			}
		}
	}
	return -1;
}
Exemple #3
0
static int __find_dentry_and_remove(tiny_inode* out_inode, 
		tiny_inode *parent_inode, const char *entry_name)
{
	int qid = OpenMQ(5000);
	tiny_dirblk *dirblk;
	tiny_dentry *dentry;
	Buf *buf;
	int i, j;
	int isEmpty = 1;
	int find = 0;
	int dirblkno;
	int parent_inodeno;
	int target_inodeno;

	for (i = 0; i < parent_inode->i_nblk; i++) {
		buf = BufRead(parent_inode->i_block[i]);
		dirblk = __get_dirblk_from_buf(buf);
		dirblkno = parent_inode->i_block[i];

		isEmpty = 1;
		for (j = 0; j < NUM_OF_DIRENT_IN_1BLK; j++) {
			dentry = &dirblk->dirEntries[j];

			if ( i == 0 && j == 0 ) {
				parent_inodeno = dentry[0].inodeNum;
			}

			if (strncmp(entry_name, dentry->name, NAME_LEN_MAX) == 0) {
				ReadInode(out_inode, dentry->inodeNum);
				strncpy(dentry->name, "", NAME_LEN_MAX);
				target_inodeno = dentry->inodeNum;

				find = 1;
			} else if (strncmp(dentry->name, "", NAME_LEN_MAX) != 0) {
				isEmpty = 0;
			}
		}

		if (find) {
			if (isEmpty) {
				SetBlockAllocToFree(dirblkno);
				parent_inode->i_block[i] =
					parent_inode->i_block[--parent_inode->i_nblk];
				WriteInode(parent_inode, parent_inodeno);
			} else {
				WriteDirBlock(dirblk, dirblkno);
			}
			return target_inodeno;
		}
	}

	return -1;
}
Exemple #4
0
// Create a directory
int MkDir(int pardir, char *dname, int uid, int gid, int attrib)
{
    struct OnDiskDirEntry new_dir;
    strcpy (new_dir.d_name,dname);
    int dev=0;
    new_dir.d_ino= AllocInode(devfd[dev]);

    struct INode inode;
    inode.i_gid=gid;
    inode.i_uid=uid;
    inode.i_mode= 0x4000 | attrib;
    inode.i_lnk=1;
    inode.i_size=0;
    inode.i_gen++;
    WriteInode (dev,new_dir.d_ino,&inode);

    struct DirEntry new_dentry;
    my_memcpy(&new_dentry,&new_dir,sizeof(struct OnDiskDirEntry));

    SeekDir(pardir,0,SEEK_END);
    WriteDir(pardir, &new_dentry);
}
Exemple #5
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;
}
Exemple #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;
}
Exemple #7
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;
}
Exemple #8
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;
}
Exemple #9
0
int CreateFile(int dirhandle, char *fname, int mode, int uid, int gid, int attrib)
{

//allocating a inode to the file to be created
    int free_inode= AllocInode(dev);
    struct INode inode;
    ReadInode(dev,free_inode,&inode);

    inode.i_mode=0x1755;// regular file
    inode.i_size=0;// initially file is empty
    inode.i_gen++;// each time when inode is use for new file increase its gen (following unix)
    inode.i_lnk=1;
    inode.i_uid=uid;
    inode.i_gid=gid;

    WriteInode(dev,free_inode,&inode);

    // adding a directory entry into the given directory
    int done=0, i=0;
    char buf[BLKSIZE];

    int data_blks_allocated_to_dir= inode.i_size/BLKSIZE + (inode.i_size % BLKSIZE)==0?0:1 ;

    struct OnDiskDirEntry* dp;

    while (done==0 && i<data_blks_allocated_to_dir )   // assuming size is small(no need to look in indirect,double indirect.)
    {
        int blkno=inode.i_blks[i];
        ReadBlock(dev,DATA_BLK_STARTS_AT+blkno,buf);
        dp= (struct OnDiskDirEntry*) buf;
        int j=0;
        while (done==0 && j<BLKSIZE/sizeof (struct OnDiskDirEntry)) //get a free directory entry(having inode no=0)
        {
            if (dp->d_ino==0) {
                done = 1;
                dp->d_ino=free_inode;
                strcpy(dp->d_name,fname);
                WriteBlock(dev,DATA_BLK_STARTS_AT+blkno,buf);
                continue;
            }
            j++;dp++;
        }
        i++;
    }
    //direcotory has already got an entry of new file

    //new open the file and return its file descriptor

    //add a entry in system wide open file table
    struct InCoreINode* new_entry;
    new_entry= (struct InCoreINode* ) malloc(sizeof(struct InCoreINode));

    // copy disk inode to incore-inode
    my_memcpy(&new_entry->ic_inode,&inode,sizeof (struct INode));

    // initialize other fields
    new_entry->ic_ino=dp->d_ino;
    new_entry->ic_dev=dev;
    new_entry->ic_ref=1; //currently 1 instance of file is open

    //adding in the front of linklist (system-wide table)
    new_entry->ic_next=head;
    head->ic_prev=new_entry;
    head=new_entry;

    //search a free entry in open file table
    i=0;
    while (ofo_table[i]!=NULL)
        i++;

    int file_descriptor =i;

    ofo_table[file_descriptor]= (struct OpenFileObject*) malloc(sizeof(struct OpenFileObject));
    //per process entry points to corresponding entry in system wide table

    ofo_table[file_descriptor]->ofo_inode= new_entry;

    //initialize other additional fields
    ofo_table[file_descriptor]->ofo_curpos=0;
    ofo_table[file_descriptor]->ofo_inode=dp->d_ino;
    ofo_table[file_descriptor]->ofo_mode=mode;
    ofo_table[file_descriptor]->ofo_ref=0;

    return file_descriptor;

}