Exemplo n.º 1
0
Arquivo: fs.c Projeto: lhsieh814/OS
/*
 * Remove/delete an existing file
 *
 * This function returns zero on success.
 */
int sfs_remove(int fd)
{
	blkid frame_bid, next_frame_bid;
	sfs_dirblock_t dir;
	sfs_inode_frame_t frame;
	int i, j;
	char *tmp;

	/* TODO: update dir */
	sfs_read_block((char*)&dir, fdtable[fd].dir_bid);
	for (i = 0; i < SFS_DB_NINODES; i++)
	{
		if (dir.inodes[i] == fdtable[fd].inode_bid)
		{
			dir.inodes[i] = 0;
		}
	}
	// Write dir block to update inode values
	sfs_write_block((char*)&dir, fdtable[fd].dir_bid);

	/* TODO: free inode and all its frames */
	frame_bid = fdtable[fd].inode.first_frame;
	
	while (frame_bid != 0)
	{
		sfs_read_block((char*)&frame, frame_bid);

		// Free all the content blocks for each frame
		for (j = 0; j < SFS_FRAME_COUNT; j++)
		{
			tmp = (char*)malloc(BLOCK_SIZE);
			memset(tmp, 0, BLOCK_SIZE);
			sfs_write_block(tmp, frame.content[j]);
			sfs_free_block(frame.content[j]);
			free(tmp);
		}

		next_frame_bid = frame.next;
		memset(&frame, 0, BLOCK_SIZE);
		sfs_write_block((char*)&frame, frame_bid);
		sfs_free_block(frame_bid);
		frame_bid = next_frame_bid;
	}
	
	// Free the inode
	memset((char*)&fdtable[fd].inode, 0, BLOCK_SIZE);

	sfs_write_block((char*)&fdtable[fd].inode, fdtable[fd].inode_bid);
	sfs_free_block(fdtable[fd].inode_bid);

	/* TODO: close the file */
	sfs_close(fd);

	return 0;
}
Exemplo n.º 2
0
Arquivo: fs.c Projeto: lhsieh814/OS
/*
 * Remove an existing empty directory and return 0 on success.
 * If the dir does not exist or still contains files, return -1.
 */
int sfs_rmdir(char *dirname)
{
	sfs_dirblock_t currentDir, prevDir, nextDir;
	blkid bid, prevBlkid, nextBlkid;

	/* TODO: check if the dir exists */
	bid = sfs_find_dir(dirname);
	if (bid != 0) {
		// Directory exists
		sfs_read_block((char*)&currentDir, bid);

		/* TODO: check if no files */
		int i;
		for (i = 0; i < SFS_DB_NINODES; i++) 
		{
			if (currentDir.inodes[i] != 0) {
				// directory is not empty
				printf("ERROR: inodes not empty = %d\n", currentDir.inodes[i]);
				return -1;
			}
		}

		/* TODO: go thru the linked list to delete the dir*/
		// Need to change the next_dir pointer of the previous dir and dir to be deleted
		nextBlkid = sb.first_dir;
		if (nextBlkid == bid) {
			// Deleting the root directory
			sb.first_dir = 0;
			sfs_read_block((char*)&currentDir, nextBlkid);						
			currentDir.next_dir = 0;
			memset(currentDir.dir_name, 0, sizeof(currentDir.dir_name));
			return 0;
		} 
		else 
		{
			while (nextBlkid != bid)
			{
				prevBlkid = nextBlkid;
				sfs_read_block((char*)&prevDir, nextBlkid);			
				nextBlkid = prevDir.next_dir;
			}
			nextBlkid = currentDir.next_dir;
		}

		// Remove the directory: update the linked list next_dir variable
		prevDir.next_dir = nextBlkid;
		currentDir.next_dir = 0;
		// Remove the dir_name of the dir to be deleted
		memset(currentDir.dir_name, 0, sizeof(currentDir.dir_name));

		// Flush the removed directory and prevDir
		sfs_write_block((char*)&currentDir, bid);
		sfs_write_block((char*)&prevDir, prevBlkid);
		// Update the freemap so that deleted dir is empty
		sfs_free_block(bid);

		return 0;
	}
	return -1;
}
Exemplo n.º 3
0
W
sfs_i_truncate (struct inode *ip, W newsize)
{
  int	nblock, blockno, inblock, offset, dinblock;
  int	i;
  W	errno;
  W	fd;
  struct fs *fsp;
  struct sfs_inode *sfs_ip;

  fd = ip->i_device;
  fsp = ip->i_fs;
  sfs_ip = &(ip->i_private.sfs_inode);
  nblock = ROUNDUP (newsize, fsp->fs_blksize)/fsp->fs_blksize;
  if (nblock < ip->i_size_blk) {
    /* 余分なブロックを開放 */
    blockno = nblock;
    if (blockno < SFS_DIRECT_BLOCK_ENTRY) {
      /* 直接ブロックの範囲内 */
      for(i = blockno; i < SFS_DIRECT_BLOCK_ENTRY; ++i) {
	if (sfs_ip->sfs_i_direct[i] > 0)
	  sfs_free_block(fd, fsp, sfs_ip->sfs_i_direct[i]);
	sfs_ip->sfs_i_direct[i] = 0;
      }
      sfs_free_indirect(fd, fsp, sfs_ip, 0, 0);
      sfs_free_all_dindirect(fd, fsp, sfs_ip, 0);
    }
    else if (blockno < (SFS_DIRECT_BLOCK_ENTRY 
			+ (SFS_INDIRECT_BLOCK_ENTRY * SFS_INDIRECT_BLOCK))) {
      /* 一重間接ブロックの範囲内 */
      inblock = (blockno - SFS_DIRECT_BLOCK_ENTRY);
      offset = inblock % SFS_INDIRECT_BLOCK;
      inblock = inblock / SFS_INDIRECT_BLOCK;
      sfs_free_indirect(fd, fsp, sfs_ip, offset, inblock);
      sfs_free_all_dindirect(fd, fsp, sfs_ip, 0);
    }
    else if (blockno < (SFS_DIRECT_BLOCK_ENTRY 
			+ (SFS_INDIRECT_BLOCK_ENTRY * SFS_INDIRECT_BLOCK)
			+ (SFS_DINDIRECT_BLOCK_ENTRY * SFS_INDIRECT_BLOCK * SFS_INDIRECT_BLOCK))) {
      /* 二重間接ブロックの範囲内 */
      blockno = blockno -
	(SFS_DIRECT_BLOCK_ENTRY + SFS_INDIRECT_BLOCK_ENTRY * SFS_INDIRECT_BLOCK);
      
      inblock = blockno / (SFS_DINDIRECT_BLOCK_ENTRY * SFS_INDIRECT_BLOCK);
      dinblock = (blockno % (SFS_DINDIRECT_BLOCK_ENTRY * SFS_INDIRECT_BLOCK))
	/ SFS_INDIRECT_BLOCK;
      offset = blockno % SFS_INDIRECT_BLOCK;
      sfs_free_dindirect(fd, fsp, sfs_ip, offset, dinblock, inblock);
      sfs_free_all_dindirect(fd, fsp, sfs_ip, inblock+1);
    }
  }

  ip->i_size = newsize;
  ip->i_size_blk = nblock;
  ip->i_dirty = 1;
  /* これは deallocate の中で処理するのが普通 */
  errno = sfs_i_sync(ip);
  if (errno) {
    return(errno);
  }
  /* ここで fs を sync する必要があるか? */
  errno = sfs_syncfs(fsp);
  if (errno) {
    return(errno);
  }
  return (EP_OK);
}
Exemplo n.º 4
0
/*
 * Remove/delete an existing file
 * This function returns zero on success.
 */
int sfs_remove(int fd_num)
{
	blkid frame_bid;
	sfs_dirblock_t dir;
	char block_ptr[BLOCK_SIZE];
	int i;

	fd_struct_t fd = fdtable[fd_num];

	//Set the index of the inode to zero
	blkid dir_bid = fd.dir_bid;
	blkid inode_bid = fd.inode_bid;

	//Remove the inode from the directory
	sfs_read_block(block_ptr, dir_bid);
	dir = *(sfs_dirblock_t*)block_ptr;

	//Find the index at which the inode is stored
	int count = 0;
	while(count < SFS_DB_NINODES){
		if(dir.inodes[count] == inode_bid){
			dir.inodes[count] = 0;
			break;
		}
		count++;
	}

	dir.inodes[inode_bid] = 0;
	sfs_write_block(&dir, dir_bid);

	/* TODO: free inode and all its frames */
	sfs_inode_t inode;
	sfs_read_block(block_ptr, inode_bid);
	inode = *(sfs_inode_t*)block_ptr;

	char frame_ptr[BLOCK_SIZE];
	sfs_inode_frame_t frame;
	blkid next_frame = inode.first_frame;

	//Iterate through each of the nonzero content blocks
	//sfs_free_block() on all of them
	while(next_frame != 0){

		sfs_read_block(frame_ptr, next_frame);
		frame = *(sfs_inode_frame_t*)frame_ptr;

		//Check each of the entries of the frame and free nonzero blocks
		int i;
		for(i = 0; i < SFS_FRAME_COUNT; i++){
			blkid content_blk = frame.content[i];
			if(content_blk != 0){
				sfs_free_block(content_blk);
			}
		}
		sfs_free_block(next_frame);
		next_frame = frame.next;
	}

	/* TODO: close the file */
	sfs_free_block(inode_bid);
	//Reset the file description to default
	
	fd.valid = 0;
	memset(&fd.inode, 0, sizeof(sfs_inode_t));
	fd.dir_bid = 0;
	fd.inode_bid = 0;

	return 0;
}
Exemplo n.º 5
0
/*
 * Remove an existing empty directory and return 0 on success.
 * If the dir does not exist or still contains files, return -1.
 */
int sfs_rmdir(char *dirname)
{
	/* TODO: check if the dir exists */
	blkid dir_bid = sfs_find_dir(dirname);

	if(dir_bid == 0){
		printf("ERROR sfs_rmdir: Specified directory does not exist\n");
		return -1;
	}

	if(sb.first_dir == 0 || dir_bid == 0){
		//The directory does not exist
		return -1;
	} else{
		//Unset the corresponding bit in the freemap
		sfs_free_block(dir_bid);
	}

	//Find the directories that come before and after the 
	//directory we want to delete
	blkid next_dir = sb.first_dir;		//First block 
	blkid current_dir;					//Current block is sb
	blkid previous_dir = 0;				//No previous blocks
	char block_ptr[BLOCK_SIZE];
	sfs_dirblock_t dir;

	if(next_dir == dir_bid){
		sfs_read_block(block_ptr, next_dir);
		dir = *(sfs_dirblock_t*)block_ptr;

		blkid block_to_copy = dir.next_dir;

		sfs_read_block(&sb, 0);
		sb.first_dir = block_to_copy;
		sfs_write_block(&sb, 0);		
	}

	//General case
	while(next_dir != dir_bid){
		
		previous_dir = current_dir;	
		
		current_dir = next_dir;
		
		sfs_read_block(block_ptr, next_dir);
		dir = *(sfs_dirblock_t*)block_ptr;

		next_dir = dir.next_dir;

		//The next block is what we want to remove
		if(next_dir == dir_bid){
			//Set the next dir of the current block to the next+1 block
			sfs_read_block(block_ptr, next_dir);
			dir = *(sfs_dirblock_t*)block_ptr;
			blkid block_to_copy = dir.next_dir;

			sfs_read_block(block_ptr, current_dir);
			dir = *(sfs_dirblock_t*)block_ptr;
			dir.next_dir = block_to_copy;

			sfs_write_block(&dir, current_dir);				
		}
	}

	return 0;
}