예제 #1
0
int tiny_open(const char *path, struct fuse_file_info *fi)
{
	tiny_inode		i_tmp;
	tiny_dentry		*pDentry;
	char *token;
	char *path_copy;
	char *dir_name;
	char *base_name;
	int ino;
	int ret = 0;

	if (strcmp(path, "/") == 0) {
		return 0;
	}

	/* Get inode of the parent directory */
	path_copy = (char*)malloc(strlen(path) + 1);
	strcpy(path_copy, path);
	dir_name = dirname(path_copy);
	token = strtok(dir_name, "/");
	ReadInode(&i_tmp, tiny_superblk.s_rdirino);
	while (token) {
		pDentry = __find_dentry(&i_tmp, token);
		if (!pDentry || pDentry->type == FILE_TYPE_FILE) {
			ret = -ENOTDIR;
			goto err;
		}
		
		ReadInode(&i_tmp, pDentry->inodeNum);
		token = strtok(NULL, "/");
	}

	/* Get dentry of the target */
	free(path_copy);
	path_copy = (char*)malloc(strlen(path) + 1);
	strcpy(path_copy, path);
	base_name = basename(path_copy);
	pDentry = __find_dentry(&i_tmp, base_name);

	/* There is no such file */
	if (pDentry == NULL) {
		ret = -ENOENT;
		goto err;
	}

	/* Path indicates a directory */
	if (pDentry->type == FILE_TYPE_DIR) {
		ret = 0;
		goto err;
	}

	/* Get inode number of the target */
	fi->fh = (uint64_t)pDentry->inodeNum;

err:
	free(path_copy);

	return ret;
}
예제 #2
0
int tiny_create(const char *path, mode_t mode, struct fuse_file_info *fi)
{
	tiny_inode		i_tmp;
	int				target_inodeno;
	tiny_dentry		*pDentry;
	char *token;
	char *path_copy;
	char *dir_name;
	char *base_name;
	int ino;
	int ret = 0;

	/* Get inode of the parent directory */
	path_copy = (char*)malloc(strlen(path) + 1);
	strcpy(path_copy, path);
	dir_name = dirname(path_copy);
	token = strtok(dir_name, "/");
	ReadInode(&i_tmp, tiny_superblk.s_rdirino);
	while (token) {
		pDentry = __find_dentry(&i_tmp, token);
		if (!pDentry || pDentry->type == FILE_TYPE_FILE) {
			ret = -ENOTDIR;
			goto err;
		}

		ReadInode(&i_tmp, pDentry->inodeNum);
		token = strtok(NULL, "/");
	}

	/* Get dentry of the target */
	free(path_copy);
	path_copy = (char*)malloc(strlen(path) + 1);
	strcpy(path_copy, path);
	base_name = basename(path_copy);
	if (strlen(base_name) > NAME_LEN_MAX - 1) {
		ret = -ENAMETOOLONG;
		goto err;
	}
	pDentry = __find_dentry(&i_tmp, base_name);

	/* There is no such file */
	if (pDentry == NULL) {
		target_inodeno = __create_file(&i_tmp, base_name);
		if (target_inodeno < 0) {
			ret = -EDQUOT;
			goto err;
		}
		fi->fh = (uint64_t)target_inodeno;
	} else {
		ret = -EEXIST;
		goto err;
	}

err:
	free(path_copy);
	return ret;
}
예제 #3
0
int tiny_unlink(const char *path)
{
	tiny_inode		i_tmp;
	tiny_inode		target;
	tiny_dentry		*pDentry;
	char *token;
	char *path_copy;
	char *dir_name;
	char *base_name;
	int target_inodeno;
	int ret = 0;
	int i, j;

	/* Get inode of the parent directory */
	path_copy = (char*)malloc(strlen(path) + 1);
	strcpy(path_copy, path);
	dir_name = dirname(path_copy);
	token = strtok(dir_name, "/");
	ReadInode(&i_tmp, tiny_superblk.s_rdirino);
	while (token) {
		pDentry = __find_dentry(&i_tmp, token);
		if (!pDentry || pDentry->type == FILE_TYPE_FILE) {
			ret = -ENOTDIR;
			goto err;
		}
		
		ReadInode(&i_tmp, pDentry->inodeNum);
		token = strtok(NULL, "/");
	}

	/* Get dentry of the target */
	free(path_copy);
	path_copy = (char*)malloc(strlen(path) + 1);
	strcpy(path_copy, path);
	base_name = basename(path_copy);
	target_inodeno = __find_dentry_and_remove(&target, &i_tmp, base_name);
	if (target_inodeno < 0) {
		ret = -ENOENT;
		goto err;
	}

	for ( i = 0 ; i < target.i_nblk ; i++ ) {
		SetBlockAllocToFree(target.i_block[i]);
	}
	SetInodeAllocToFree(target_inodeno);

err:
	free(path_copy);

	return ret;
}
예제 #4
0
initrd_inode_t* GetInode(int fd, initrd_superblock_t* sb, uint32_t ino)
{
	initrd_inode_t* inode = (initrd_inode_t*) malloc(sizeof(initrd_inode_t));
	if ( !inode ) { return NULL; }
	if ( !ReadInode(fd, sb, ino, inode) ) { free(inode); return NULL; }
	return inode;
}
예제 #5
0
Partition::Partition(uint64_t size, uint64_t offset, int ssize, HANDLE phandle)
{
    int ret;
    total_sectors = size;
    relative_sect = offset;
    handle = phandle;
    sect_size = ssize;
    onview = false;
    inode_buffer = NULL;
    buffercache.setMaxCost(MAX_CACHE_SIZE);
    ret = Mount();
    if(ret < 0)
    {
        is_valid = false;
        return;
    }

    root = ReadInode(EXT2_ROOT_INO);
    if(!root)
    {
        is_valid = false;
        LOG("Cannot read the root of %s \n", linux_name.c_str());
        return;
    }

    root->file_name = linux_name;
    root->file_type = 0x02;
    is_valid = true;
}
예제 #6
0
int WriteDir(int dirhandle, struct DirEntry *dent)
{
    if (dirhandle<0||dirhandle>=10)
        return -1;

    struct INode inode;
    int  dev=0;
    ReadInode(dev,dir_table[dirhandle]->d_entry.d_ino, &inode);

    int dentries_in_one_block = BLKSIZE / (sizeof (struct OnDiskDirEntry));


    int blk_count= dir_table[dirhandle]->d_offset / dentries_in_one_block;

    char buf [BLKSIZE];

    ReadBlock(dev,DATA_BLK_STARTS_AT+inode.i_blks[blk_count],buf);

    struct OnDiskDirEntry* dp= (struct OnDiskDirEntry*) buf;

    dp += dir_table[dirhandle]->d_offset % dentries_in_one_block;

    my_memcpy(  dp, &dent->d_entry, sizeof (struct OnDiskDirEntry) );

    WriteBlock(dev,DATA_BLK_STARTS_AT+inode.i_blks[blk_count],buf);

    dir_table[dirhandle]->d_offset++;

    return 0 ;// success

}
예제 #7
0
long UFSGetDirEntry( CICell ih, char * dirPath, long long * dirIndex,
                     char ** name, long * flags, long * time,
                     FinderInfo * finderInfo, long * infoValid)
{
    long  ret, fileInodeNum, dirFlags;
    Inode tmpInode;

    if (UFSInitPartition(ih) == -1) return -1;

    if (infoValid) *infoValid = 0;

    // Skip a leading '/' if present
    if (*dirPath == '/') dirPath++;
    if (*dirPath == '/') dirPath++;

    ret = ResolvePathToInode(dirPath, &dirFlags, gFileInodePtr, gRootInodePtr);
    if ((ret == -1) || ((dirFlags & kFileTypeMask) != kFileTypeDirectory))
        return -1;

    ret = ReadDirEntry(gFileInodePtr, &fileInodeNum, dirIndex, name);
    if (ret != 0) return ret;

    ReadInode(fileInodeNum, &tmpInode, flags, time);

    return 0;
}
예제 #8
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;
}
예제 #9
0
// Delete directory (if itis empty)
int RmDir(int pardir, char *dname)
{
    struct DirEntry* parent = dir_table[pardir];
    struct INode inode;
    ReadInode(0,parent->d_entry.d_ino,&inode);

    char buf[BLKSIZE];
    struct OnDiskDirEntry* dp;

    int data_blks_allocated_to_dir= inode.i_size/BLKSIZE + (inode.i_size % BLKSIZE)==0?0:1 ;
    int i=0,done=0;
    int blkno;
    while (done==0&&i<data_blks_allocated_to_dir)  // assuming dirctory-file is small(no need to look in indirect,double indirect.)
    {
        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)) {
            if (strcmp (dp->d_name,dname)==0) {
                done = 1;
                continue;
            }
            j++;dp++;
        }
        i++;
    }

    struct INode inode_of_dir_to_be_remove;
    ReadInode (dev,dp->d_ino,&inode_of_dir_to_be_remove);

    if (inode_of_dir_to_be_remove.i_size>0) {
        printf("directory is not empty\n");
        return -1;
    }

    FreeInode(dev,dp->d_ino);
    //remove dir entry from parent directory
    dp->d_ino=0;

    WriteBlock(dev,blkno,buf);

    return 0;

}
예제 #10
0
long Ext2InitPartition(CICell ih)
{
  long cnt, gdPerBlock;
  
  if (ih == gCurrentIH) return 0;
  
  printf("Ext2InitPartition: %x\n", ih);
  
  gCurrentIH = 0;
  
  // Read for the Super Block.
  Seek(ih, SBOFF);
  Read(ih, (long)gFSBuf, SBSIZE);
  
  gFS = (struct m_ext2fs *)gFSBuf;
  e2fs_sb_bswap(&gFS->e2fs, &gFS->e2fs);
  if (gFS->e2fs.e2fs_magic != E2FS_MAGIC) return -1;
  
  // Calculate the block size and set up the block cache.
  gBlockSize = 1024 << gFS->e2fs.e2fs_log_bsize;
  if (gBlockSizeOld <= gBlockSize) {
    gTempBlock = AllocateBootXMemory(gBlockSize);
  }
  CacheInit(ih, gBlockSize);
  
  gBlockSizeOld = gBlockSize;
  
  gCurrentIH = ih;
  
  gdPerBlock = gBlockSize / sizeof(struct ext2_gd);
  
  // Fill in the in memory super block fields.
  gFS->e2fs_bsize = 1024 << gFS->e2fs.e2fs_log_bsize;
  gFS->e2fs_bshift = LOG_MINBSIZE + gFS->e2fs.e2fs_log_bsize;
  gFS->e2fs_qbmask = gFS->e2fs_bsize - 1;
  gFS->e2fs_bmask = ~gFS->e2fs_qbmask;
  gFS->e2fs_fsbtodb = gFS->e2fs.e2fs_log_bsize + 1;
  gFS->e2fs_ncg = HowMany(gFS->e2fs.e2fs_bcount - gFS->e2fs.e2fs_first_dblock,
			 gFS->e2fs.e2fs_bpg);
  gFS->e2fs_ngdb = HowMany(gFS->e2fs_ncg, gdPerBlock);
  gFS->e2fs_ipb = gFS->e2fs_bsize / EXT2_DINODE_SIZE;
  gFS->e2fs_itpg = gFS->e2fs.e2fs_ipg / gFS->e2fs_ipb;
  gFS->e2fs_gd = AllocateBootXMemory(gFS->e2fs_ngdb * gFS->e2fs_bsize);
  
  // Read the summary information from disk.
  for (cnt = 0; cnt < gFS->e2fs_ngdb; cnt++) {
    ReadBlock(((gBlockSize > 1024) ? 0 : 1) + cnt + 1, 0, gBlockSize,
	      (char *)&gFS->e2fs_gd[gdPerBlock * cnt], 0);
    e2fs_cg_bswap(&gFS->e2fs_gd[gdPerBlock * cnt],
		  &gFS->e2fs_gd[gdPerBlock * cnt], gBlockSize);
  }
  
  // Read the Root Inode
  ReadInode(EXT2_ROOTINO, &gRootInode, 0, 0);
  
  return 0;
}
예제 #11
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;
}
예제 #12
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;
}
예제 #13
0
파일: ext2.cpp 프로젝트: wspeirs/Mooose
int ext2::Open(FileDescriptorBase *fileDescriptor, const string &file, const int flags)
{
	// FIX ME
	(void)flags;
	
	FileDescriptor	*fd = reinterpret_cast<FileDescriptor*>(fileDescriptor);
	
	int inode = FindInodeByPath(string(file));
	
	if(inode < 0)
	{
		printf("COULDN'T FIND INODE\n");
		return(-1);
	}

	fd->inodeNumber = inode;		// set the inode number
	ReadInode(inode, &fd->fileInode);	// read in the inode

/*	printf("SIZE: %d\n", fd->fileInode.size);
	printf("OWNER ID: %d\n", fd->fileInode.ownerUID);
	printf("FILE MODE: %d\n", fd->fileInode.fileMode);
	printf("BLOCK COUNT: %d\n", fd->fileInode.blockCount);
	printf("FILE FLAGS: %d\n", fd->fileInode.fileFlags);
*/
	
	if(!(fd->fileInode.fileMode & FILE_FILE_MODE))
	{
//		Panic::PrintMessage("Not a file\n");
		printf("Not a file\n");
		return(-2);
	}
	
	// read in the first data block
	if(fd->fileInode.size > 0)
	{
		fd->blockData = new uchar[blockSize];	// make the memory
		
		// Read in the first data block
		ReadDataBlock(0, fd->fileInode.blockPointers, fd->blockData);
	}

	else
		fd->blockData = NULL;

	// zero the block number and positions
	fd->blockNumber = fd->filePosition = fd->blockPosition = 0;

	return(0);
}
예제 #14
0
// Write into a file already opened, nbytes from buf
int WriteFile(int fhandle, char buf[], int nbytes)
{

    // implementation of writefile is same as above readfile function, just direction of flow of data is reverse

    if (fhandle<0||ofo_table[fhandle]==NULL) {
        return -1;//error
    }

    struct INode inode;
    ReadInode( dev,ofo_table[fhandle]->ofo_inode->ic_ino,&inode);

    int nblks_to_be_read= (nbytes-1)/BLKSIZE +1;
    int nblk_to_be_skipped= (ofo_table[fhandle]->ofo_curpos -1) / BLKSIZE;

    int first_blkno_tobe_read= inode.i_blks[nblk_to_be_skipped];

    int byte_to_be_skipped= (ofo_table[fhandle]->ofo_curpos-1) % BLKSIZE;

    char tempbuf [BLKSIZE];
    ReadBlock(ofo_table[fhandle]->ofo_inode->ic_dev, first_blkno_tobe_read, tempbuf);

    int bytes_tobe_read= BLKSIZE - byte_to_be_skipped;
    my_memcpy(tempbuf+byte_to_be_skipped, buf, bytes_tobe_read );

    char* buf_ptr=buf+bytes_tobe_read;
    //now read remaining blks
    int i=nblk_to_be_skipped +1;
    for (;i<nblks_to_be_read;i++) {

        ReadBlock(dev,DATA_BLK_STARTS_AT+inode.i_blks[i],tempbuf);

        int bytes_to_transfer;

        if (nbytes>(i+1)*BLKSIZE)
            bytes_to_transfer=BLKSIZE;
        else bytes_to_transfer= nbytes-i*BLKSIZE;

        my_memcpy(tempbuf, buf_ptr, bytes_to_transfer);
        buf_ptr += BLKSIZE;
    }
    // advance the cursor
    ofo_table[fhandle]->ofo_curpos +=  nbytes;

    return nbytes; // return bytes read
}
예제 #15
0
파일: ufs.c 프로젝트: scorpius/chameleon
static long FindFileInDir( char * fileName, long * flags,
                           InodePtr fileInode, InodePtr dirInode )
{
    long ret, inodeNum, index = 0;
    char *name;

    while (1) {
        ret = ReadDirEntry(dirInode, &inodeNum, &index, &name);
        if (ret == -1) return -1;

        if (strcmp(fileName, name) == 0) break;
    }

    ReadInode(inodeNum, fileInode, flags, 0);

    return 0;
}
예제 #16
0
int OpenDir(int pardir, char *dname)
{
    struct DirEntry* parent = dir_table[pardir];
    struct INode inode;
    ReadInode(0,parent->d_entry.d_ino,&inode);

    char buf[BLKSIZE];
    struct OnDiskDirEntry* dp;

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

    int i=0,done=0;
    while (done==0&&i<data_blks_allocated_to_dir)  // assuming dirctory-file 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)) {
            if (strcmp (dp->d_name,dname)==0) {
                done = 1;
                continue;
            }
            j++;dp++;
        }
        i++;
    }

    //get a free entry in dir table
    i=0;
    while (dir_table[i]!=NULL&&i<10)
        i++;
    if (i>=10) {
        printf("can't open more than 10 directories\n");
        return -1;
    }

    dir_table[i]= (struct DirEntry*) malloc(sizeof(struct DirEntry));
    dir_table[i]->d_offset=0;
    my_memcpy(&dir_table[i]->d_entry, dp,sizeof (struct OnDiskDirEntry));

    return i;
}
예제 #17
0
// Move the file pointer to required position
int SeekFile(int fhandle, int pos, int whence)
{
    if (ofo_table[fhandle]==NULL)
        return -1;

    if (whence==SEEK_SET) {
        ofo_table[fhandle]->ofo_curpos = pos;
    }
    else if (whence==SEEK_CUR) {
        ofo_table[fhandle]->ofo_curpos += pos;
    }
    else if(whence==SEEK_END) {

        struct INode inode;
        ReadInode(dev,ofo_table[fhandle]->ofo_inode->ic_ino, &inode);

        ofo_table[fhandle]->ofo_curpos = inode.i_size+pos;
    }
    return ofo_table[fhandle]->ofo_curpos;
}
예제 #18
0
long Ext2GetDirEntry(CICell ih, char *dirPath, long *dirIndex,
		     char **name, long *flags, long *time)
{
  long  ret, fileInodeNum, dirFlags;
  Inode tmpInode;
  
  if (Ext2InitPartition(ih) == -1) return -1;
  
  // Skip a leading '\' if present
  if (dirPath[0] == '\\') dirPath++;
  ret = ResolvePathToInode(dirPath, &dirFlags, &gFileInode, &gRootInode);
  if ((ret == -1) || ((dirFlags & kFileTypeMask) != kFileTypeDirectory))
    return -1;
  
  ret = ReadDirEntry(&gFileInode, &fileInodeNum, dirIndex, name);
  if (ret != 0) return ret;
  
  ReadInode(fileInodeNum, &tmpInode, flags, time);
  
  return 0;
}
예제 #19
0
long UFSInitPartition(CICell ih)
{
  if (ih == gCurrentIH) return 0;
  
  printf("UFSInitPartition: %x\n", ih);
  
  gCurrentIH = 0;
  
  // Assume there is no Disk Label
  gPartitionBase = 0;
  
  // Look for the Super Block
  Seek(ih, gPartitionBase + SBOFF);
  Read(ih, (long)gFSBuf, SBSIZE);
  
  gFS = (struct fs *)gFSBuf;
  if (gFS->fs_magic != FS_MAGIC) {
    return -1;
  }
  
  // Calculate the block size and set up the block cache.
  gBlockSize = gFS->fs_bsize;
  gFragSize  = gFS->fs_fsize;
  gFragsPerBlock = gBlockSize / gFragSize;
  
  if (gBlockSizeOld <= gBlockSize) {
    gTempBlock = AllocateBootXMemory(gBlockSize);
  }
  
  CacheInit(ih, gBlockSize);
  
  gBlockSizeOld = gBlockSize;
  
  gCurrentIH = ih;
  
  // Read the Root Inode
  ReadInode(ROOTINO, &gRootInode, 0, 0);
  
  return 0;
}
예제 #20
0
int ReadFile(int fileDesc, char* pBuffer, int length)
{
/*
 * precondition		: usage) ReadFile(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	wrote = length;
	Buf* pBuf = NULL;
	InodeInfo	inodeInfo;
	DirBlock	dirBlock;

	ReadInode(&inodeInfo, fileDescTable.file[fileDesc].inodeNo);

	// 첫번째 블락에서 data 읽고 pBuffer에 적재
	pBuf = BufRead(inodeInfo.i_block[block]);
	memcpy(pBuffer, (char*)pBuf->pMem + offset, BLOCK_SIZE - offset);
	wrote = length < BLOCK_SIZE - offset ? length : BLOCK_SIZE - offset ;
	fileDescTable.file[fileDesc].offset = wrote;
	if ( length <= 512 )		return wrote;
	// 두번째 블락부터 data 읽고 pBuffer에 적재
	for ( j = block + 1 ; j < (length / BLOCK_SIZE) + block ; j++ )
	{
		if (NUM_OF_INDIRECT_BLOCK == j)
			return  wrote;	// indirect block 12개가 모두 사용중이면 write한 만큼만 리턴
		pBuf = BufRead(inodeInfo.i_block[j]);
		memcpy(pBuffer + BLOCK_SIZE * ((j - (block + 1)) + 1), pBuf->pMem, length - wrote > BLOCK_SIZE ? BLOCK_SIZE : length - wrote);
		wrote = wrote + (length - wrote > BLOCK_SIZE ? BLOCK_SIZE : length - wrote);
		fileDescTable.file[fileDesc].offset = wrote;
		if ( wrote == length )	return wrote;
	}
}
예제 #21
0
int SeekDir(int dirhandle, int pos, int whence)
{
    if (dir_table[dirhandle]==NULL)
        return -1;

    if (whence==SEEK_SET) {
        dir_table[dirhandle]->d_offset = pos;
    }
    else if (whence==SEEK_CUR) {
        dir_table[dirhandle]->d_offset += pos;
    }
    else if(whence==SEEK_END) {

        struct INode inode;
        int dev=0;
        ReadInode(dev,dir_table[dirhandle]->d_entry.d_ino, &inode);

        dir_table[dirhandle]->d_offset = inode.i_size+pos;

    }
    return dir_table[dirhandle]->d_offset;
}
예제 #22
0
long UFSInitPartition( CICell ih )
{
#if !BOOT1
    long ret;
#endif

    if (ih == gCurrentIH) {
#ifdef __i386__
        CacheInit(ih, gBlockSize);
#endif
        return 0;
    }

#if !BOOT1
    verbose("UFSInitPartition: %x\n", ih);
#endif

    gCurrentIH = 0;

#ifdef __i386__
    if (!gULBuf) gULBuf = (char *) malloc(UFS_LABEL_SIZE);
    if (!gFSBuf) gFSBuf = (char *) malloc(SBSIZE);
    if (!gTempName) gTempName = (char *) malloc(MAXNAMLEN + 1);
    if (!gTempName2) gTempName2 = (char *) malloc(MAXNAMLEN + 1);
    if (!gRootInodePtr) gRootInodePtr = (InodePtr) malloc(sizeof(Inode));
    if (!gFileInodePtr) gFileInodePtr = (InodePtr) malloc(sizeof(Inode));
    if (!gULBuf || !gFSBuf || !gTempName || !gTempName2 ||
        !gRootInodePtr || !gFileInodePtr) return -1;
#endif

    // Assume there is no Disk Label
    gPartitionBase = 0;

#if !BOOT1
    // read the disk label to get the UUID
    // (rumor has it that UFS headers can be either-endian on disk; hopefully
    // that isn't true for this UUID field).
    Seek(ih, gPartitionBase + UFS_LABEL_OFFSET);
    ret = Read(ih, (long)&gUFSLabel, UFS_LABEL_SIZE);
    if(ret != 0)
        bzero(&gUFSLabel, UFS_LABEL_SIZE);
#endif /* !BOOT1 */

    // Look for the Super Block
    Seek(ih, gPartitionBase + SBOFF);
    Read(ih, (long)gFSBuf, SBSIZE);

    gFS = (struct fs *)gFSBuf;
    byte_swap_superblock(gFS);

    if (gFS->fs_magic != FS_MAGIC) {
        return -1;
    }

	ih->modTime = gFS->fs_time;
	
    // Calculate the block size and set up the block cache.
    gBlockSize = gFS->fs_bsize;
    gFragSize  = gFS->fs_fsize;
    gFragsPerBlock = gBlockSize / gFragSize;
    if (gTempBlock != 0) free(gTempBlock);
    gTempBlock = malloc(gBlockSize);
    CacheInit(ih, gBlockSize);

    gCurrentIH = ih;

    // Read the Root Inode
    ReadInode(ROOTINO, gRootInodePtr, 0, 0);

    return 0;
}
예제 #23
0
int EnumerateDirStatus(const char* pDirName, DirEntry* pDirEntry, int dirEntries)
{
/*
 * precondition		: usage ) EnumerateDirStatus(pDirName, pDirEntry, dirEntries);
 * postcondition	: 디렉토리에 포함된 파일 또는 디렉토리 정보를 얻어낸다.
 * 					  이 함수는 해당 디렉토리를 구성하고 있는 디렉토리 엔트리들의
 * 					  묶음을 리턴한다.
 * 					  성공하면 읽어진 디렉토리 엔트리 개수를 리턴한다. 예로, 임의의 디렉토리의 전체
 * 					  디렉토리 엔트리 개수가 40이지만, dirEntries가 60으로 입력됬을때, 리턴되는 값은
 * 					  유효한 디렉토리 엔트리 개수인 40을 리턴해야 한다. 또한, 40개의 디렉토리 엔트리
 * 					  내용을 pDirEntry 배열로 전달해야 한다. 또한, 전체 디렉토리 엔트리 개수가 40이지만
 * 					  dirEntry가 20으로 입력되었을 때, 리턴되는 값은 20이며, 20개의 디렉토리 엔트리의
 * 					  내용이 pDirEntry로 리턴되어야 한다. 에러 발생시 -1을 리턴한다.
 */
	char dirname[NAME_LEN_MAX] = {NULL,};
	char* abspath = malloc(strlen(pDirName) + 1);
	char* ptr = abspath;
	DirEntry* dirEntry = pDirEntry;
	InodeInfo inodeInfo;
	DirBlock dirBlock;
	int i = 0, j = 0;
	int found = 0;
	int	cnt = 0;

	memcpy(abspath, pDirName, strlen(pDirName) + 1);

	GetEntryName(dirname, abspath);	// dirname 최종 디렉토리명
	ReadInode(&inodeInfo, fileSysInfo.rootInodeNum);

	ptr = strtok(abspath, "/");
	if (ptr == NULL && strcmp(dirname,"") == 0)		// root directory 일때
	{
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++)
			{
				if ( strcmp(dirBlock.dirEntries[j].name, "") != 0)
				{
					memcpy(dirEntry, &dirBlock.dirEntries[j], sizeof(DirEntry));
					dirEntry++;
					cnt++;
				}
				if ( cnt == dirEntries )
				{
					free(abspath);
					return cnt;
				}
			}
		}
		free(abspath);
		return cnt;
	}
	while(ptr)
	{ // root 내부로 들어감
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if( strcmp(ptr, dirBlock.dirEntries[j].name) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_DIR)
				{
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					found++;
					break;
				}
			}
			if( found == 1 )
			{
				found = 0;
				break;
			}
		}
		ptr = strtok(NULL, "/");
	}
	// 찾는 디렉토리가 없음
	if ( j == MAX_INDEX_OF_DIRBLK )		return WRONG_VALUE;

	for ( i = 0 ; i < inodeInfo.blocks ; i++ )
	{
		ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
		for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++)
		{
//			if ( strcmp(dirBlock.dirEntries[j].name, "") != 0)
			if ( strcmp(dirBlock.dirEntries[j].name, "") != 0
					&& strcmp(dirBlock.dirEntries[j].name, ".") != 0
					&& strcmp(dirBlock.dirEntries[j].name, "..") != 0)
			{
				memcpy(dirEntry, &dirBlock.dirEntries[j], sizeof(DirEntry));
				dirEntry++;
				cnt++;
			}
			if ( cnt == dirEntries )
			{
				free(abspath);
				return cnt;
			}
		}
	}
	free(abspath);
	return cnt;
}
예제 #24
0
int RemoveDir(const char* pDirName)
{
/*
 * precondition		: usage ) RemoveDir(pDirName);
 * postcondition	: 디렉토리를 제거한다. 단, 리눅스 파일 시스템처럼 빈 디렉토리만 제거가 가능하다.
 * 					  성공하면 0을 리턴한다. 실패 했을 때는 -1을 리턴한다.
 * 					  실패 원인은 다음과 같다.
 * 					  1) 디렉토리에 파일 또는 하위 디렉토리가 존재 할 경우
 * 					  2) 제거하고자 하는 디렉토리가 없을 경우
 */
	char dirname[NAME_LEN_MAX] = {NULL,};
	char* abspath = malloc(strlen(pDirName) + 1);
	char* ptr = abspath;
	InodeInfo inodeInfo;
	DirBlock dirBlock;
	int i = 0, j = 0;
	int found = 0;

	memcpy(abspath, pDirName, strlen(pDirName) + 1);

	GetEntryName(dirname, abspath);	// dirname 최종 디렉토리명
	GetEntryPath(abspath, dirname);	// abspath는 dirname을 제외한 path
	ReadInode(&inodeInfo, fileSysInfo.rootInodeNum);

	ptr = strtok(abspath, "/");
	if (ptr == NULL && strcmp(dirname, "") == 0)			// root directory block에서 지울때
	{
		if ( RemoveDirentry(&inodeInfo, dirname) == WRONG_VALUE )
		{
			fprintf(stderr, "* RemoveDirentry() error!\n");
			return WRONG_VALUE;
		}
		free(abspath);
		return 0;
	}
	while(ptr)
	{ // root 내부로 들어감
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if( strcmp(ptr, dirBlock.dirEntries[j].name) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_DIR)
				{
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					found++;
					break;
				}
			}
			if( found == 1 )
			{
				found = 0;
				break;
			}
		}
		ptr = strtok(NULL, "/");
	}
	// 찾는 디렉토리가 없음
	if ( j == MAX_INDEX_OF_DIRBLK )		return WRONG_VALUE;

	if ( RemoveDirentry(&inodeInfo, dirname) == WRONG_VALUE)
	{
		free(abspath);
		return WRONG_VALUE;
	}
	free(abspath);
	return 0;
}
예제 #25
0
int MakeDir(const char* pDirName)
{
/*
 * precondition		: usage ) MakeFir(pDirName);
 * postcondition	: 디렉토리를 생성한다.
 * 					  성공하면 0을 리턴한다. 실패 했을 때는 -1을 리턴한다.
 * 					  실패 원인은 생성하고자 하는 디렉토리의 이름과
 * 					  동일한 디렉토리 또는 파일이 존재할 경우이다.
 */
	char dirname[NAME_LEN_MAX] = {NULL,};
	char* abspath = malloc(strlen(pDirName) + 1);
	char* ptr = abspath;
	InodeInfo inodeInfo;
	DirBlock dirBlock;
	int i = 0, j = 0;
	int found = 0;

	memcpy(abspath, pDirName, strlen(pDirName) + 1);

	GetEntryName(dirname, abspath);		// dirname 최종 디렉토리명
	GetEntryPath(abspath, dirname);	// abspath는 dirname을 제외한 path
	ReadInode(&inodeInfo, fileSysInfo.rootInodeNum);

	ptr = strtok(abspath, "/");
	if (!ptr)			// root directory block에 생성할때
	{
		if ( MakeDirentry(&inodeInfo, dirname) == WRONG_VALUE )
		{
			fprintf(stderr, "* MakeDirentry() error!\n");
			return WRONG_VALUE;
		}
		free(abspath);
		return 0;
	}
	while(ptr)
	{ // root directory block에 생성하지 않고 더 내부로 들어감
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if( strcmp(ptr, dirBlock.dirEntries[j].name) == 0
					&& dirBlock.dirEntries[j].type == FILE_TYPE_DIR)
				{
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					found++;
					break;
				}
			}
			if( found == 1 )
			{
				found = 0;
				break;
			}
		}
		ptr = strtok(NULL, "/");
	}
	if ( j == MAX_INDEX_OF_DIRBLK )		return WRONG_VALUE;

	if ( MakeDirentry(&inodeInfo, dirname) == WRONG_VALUE)
	{
		free(abspath);
		return WRONG_VALUE;
	}
	free(abspath);
	return 0;
}
예제 #26
0
int RemoveFile(const char* pFileName)
{
/*
 * precondition		: usage ) RemoveFile(pFileName);
 * postcondition	: 파일을 제거한다. 단, open된 파일을 제거 할 수 없다.
 * 					  성공하면 0을 리턴한다. 실패 했을 때는 -1을 리턴한다.
 * 					  실패 원인은 다음과 같다.
 * 					  1) 제거할 파일 이름이 없을 경우
 * 					  2) 제거될 파일이 open 되어 있을 경우
 */
	char filename[NAME_LEN_MAX] = {NULL,};
	char* abspath = malloc(strlen(pFileName) + 1);
	char* ptr = abspath;
	InodeInfo inodeInfo;
	DirBlock dirBlock;
	int i = 0, j = 0;
	int found = 0;
	int parent_blockno = 0;
	memcpy(abspath, pFileName, strlen(pFileName) + 1);

	GetEntryName(filename, abspath);	// dirname 최종 디렉토리명
//	GetEntryPath(abspath, filename);	// abspath는 dirname을 제외한 path
	ReadInode(&inodeInfo, fileSysInfo.rootInodeNum);

	ptr = strtok(abspath, "/");
	while(ptr)
	{ // root 내부로 들어감
		for ( i = 0 ; i < inodeInfo.blocks ; i++ )
		{
			ReadDirBlock(&dirBlock, inodeInfo.i_block[i]);
			for ( j = 0 ; j < MAX_INDEX_OF_DIRBLK ; j++ )
			{
				if( strcmp(ptr, dirBlock.dirEntries[j].name) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_DIR )
				{
					parent_blockno = inodeInfo.i_block[i];
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					found++;
					break;
				}
				else if ( strcmp(filename, dirBlock.dirEntries[j].name) == 0
						&& dirBlock.dirEntries[j].type == FILE_TYPE_FILE)
				{
					parent_blockno = inodeInfo.i_block[i];
					ReadInode(&inodeInfo, dirBlock.dirEntries[j].inodeNum);
					found++;
					break;
				}
			}
			if( found == 1 )
			{
				found = 0;
				break;
			}
		}
		ptr = strtok(NULL, "/");
	}
	// 찾는 중간 디렉토리가 없음
	if ( j == MAX_INDEX_OF_DIRBLK )		return WRONG_VALUE;

///////////////////////////////////////////////////
// 여기부터 해당 파일 삭제
	// 사용중인 block 해제
	for ( i = 0 ; i < inodeInfo.blocks ; i++ )
	{
		if(SetBlockAllocToFree(inodeInfo.i_block[i]) == WRONG_VALUE)
		{
			fprintf(stderr, "* RemoveFile() Error!\n");
			return WRONG_VALUE;
		}
	}
	// 사용중인 inode 삭제
	for ( i = 0 ; i < MAX_INDEX_OF_DIRBLK ; i++ )
	{
		if ( strcmp(dirBlock.dirEntries[i].name, filename) == 0 )
		{
			if( SetInodeAllocToFree(dirBlock.dirEntries[i].inodeNum) == WRONG_VALUE)
			{
				fprintf(stderr, "* RemoveFile() Error!\n");
				return WRONG_VALUE;
			}
			strcpy(dirBlock.dirEntries[i].name, "");
			WriteDirBlock(&dirBlock, parent_blockno);
			break;
		}
	}
//
///////////////////////////////////////////////////
}
예제 #27
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;
}
예제 #28
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;
}
예제 #29
0
ExtFile *Partition::ReadDirectory(EXT2DIRENT *dirent)
{
    string filename;
    ExtFile *newEntry;
    char *pos;
    int ret;

    if(!dirent)
        return NULL;
    if(!dirent->dirbuf)
    {
        dirent->dirbuf = (EXT2_DIR_ENTRY *) new char[blocksize];
        if(!dirent->dirbuf)
            return NULL;
        ret = ReadDataBlock(&dirent->parent->inode, dirent->next_block, dirent->dirbuf);
        if(ret < 0)
            return NULL;

        dirent->next_block++;
    }

again:
    if(!dirent->next)
        dirent->next = dirent->dirbuf;
    else
    {
        pos = (char *) dirent->next;
        dirent->next = (EXT2_DIR_ENTRY *)(pos + dirent->next->rec_len);
        if(IS_BUFFER_END(dirent->next, dirent->dirbuf, blocksize))
        {
            dirent->next = NULL;
            if(dirent->read_bytes < dirent->parent->file_size)
            {
                ret = ReadDataBlock(&dirent->parent->inode, dirent->next_block, dirent->dirbuf);
                if(ret < 0)
                    return NULL;

                dirent->next_block++;
                goto again;
            }
            return NULL;
        }
    }

    dirent->read_bytes += dirent->next->rec_len;
    filename.assign(dirent->next->name, dirent->next->name_len);
    if((filename.compare(".") == 0) ||
            (filename.compare("..") == 0))
        goto again;


    newEntry = ReadInode(dirent->next->inode);
    if(!newEntry)
    {
        LOG("Помилка читання Inode %d батьківський inode %d.\n", dirent->next->inode, dirent->parent->inode_num);
        return NULL;
    }

    newEntry->file_type = dirent->next->filetype;
    newEntry->file_name = filename;

    return newEntry;
}
예제 #30
0
int tiny_unlink(const char *path)
{
	tiny_inode		i_tmp;
	tiny_inode		target;
	tiny_dentry		*pDentry;
	char *token;
	char *path_copy;
	char *dir_name;
	char *base_name;
	int target_inodeno;
	int ret = 0;
	int i, j;

	/* Get inode of the parent directory */
	path_copy = (char*)malloc(strlen(path) + 1);
	strcpy(path_copy, path);
	dir_name = dirname(path_copy);
	token = strtok(dir_name, "/");
	ReadInode(&i_tmp, tiny_superblk.s_rdirino);
	while (token) {
		pDentry = __find_dentry(&i_tmp, token);
		if (!pDentry || pDentry->type == FILE_TYPE_FILE) {
			ret = -ENOTDIR;
			goto err;
		}

		ReadInode(&i_tmp, pDentry->inodeNum);
		token = strtok(NULL, "/");
	}

	/* Get dentry of the target */
	free(path_copy);
	path_copy = (char*)malloc(strlen(path) + 1);
	strcpy(path_copy, path);
	base_name = basename(path_copy);
	target_inodeno = __find_dentry_and_remove(&target, &i_tmp, base_name);
	if (target_inodeno < 0) {
		ret = -ENOENT;
		goto err;
	}

	for ( i = 0 ; i < target.i_nblk ; i++ ) {
		SetBlockAllocToFree(target.i_block[i]);
	}
	SetInodeAllocToFree(target_inodeno);

err:
	free(path_copy);


	int qid = OpenMQ(5000);



	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 = 'd';
	if(SendMQ(qid, MSG_FILEIO, &fio) < 0)
	{
		printf("fio send fail\n");
		return ;
	}


	return ret;
}