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; }
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; }
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; }
// 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); }
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; }
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; }
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; }
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; }
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; }