Exemplo n.º 1
0
/* Closes INODE and writes it to disk.
   If this was the last reference to INODE, frees its memory.
   If INODE was also a removed inode, frees its blocks. */
void
inode_close (struct inode *inode) 
{
  /* Ignore null pointer. */
  if (inode == NULL)
    return;

  //Acquire both the internal and global inode locks. Internal is required so nobody can change the
  //open_cnt variable while the external lock is required so nobody can get a new pointer to the node
  //while it's being deleted and later freed which would result in a dangling pointer.
  lock_acquire(&inode_list_lock);
  lock_acquire(&inode->internal_lock);
  /* Release resources if this was the last opener. */
  if (--inode->open_cnt == 0)
    {
      /* Remove from inode list and release lock. */
      list_remove (&inode->elem);
 
      /* Deallocate blocks if removed. */
      if (inode->removed) 
        {
          free_map_release (inode->sector, 1);
          free_map_release (inode->data.start,
                            bytes_to_sectors (inode->data.length)); 
        }

      free (inode); 
    }
  else
    {
      lock_release(&inode->internal_lock);
    }
  lock_release(&inode_list_lock);
}
Exemplo n.º 2
0
/* Closes INODE and writes it to disk.
   If this was the last reference to INODE, frees its memory.
   If INODE was also a removed inode, frees its blocks. */
void
inode_close (struct inode *inode) 
{
  /* Ignore null pointer. */
  if (inode == NULL)
    return;

  lock_acquire(&inode_list_lock); 
  lock_acquire(&inode->inode_lock); 

  /* Release resources if this was the last opener. */
  if (--inode->open_cnt == 0)
    {
      /* Remove from inode list. */
      list_remove (&inode->elem);
      
 
      /* Deallocate blocks if the file is marked as removed. */
      if (inode->removed) 
        {
          free_map_release (inode->sector, 1);
          free_map_release (inode->data.start,
                            bytes_to_sectors (inode->data.length)); 
        }
      lock_release(&inode->inode_lock);
      free (inode);
      lock_release(&inode_list_lock);
      return;
    }
  lock_release(&inode->inode_lock);
  lock_release(&inode_list_lock);
}
Exemplo n.º 3
0
static void
deallocate_sectors(struct inode_disk *data)
{
  size_t i, j;
  size_t sectors = bytes_to_sectors(data->length);

  struct sector_table *doubly_indirect_table = calloc(1, sizeof(struct sector_table));
  cache_read(data->doubly_indirect, doubly_indirect_table, 512, 0);
  
  for(i = 0; i < 128; i++)
  {
    if(sectors == 0)
      break;
    struct sector_table *indirect_table = calloc(1, sizeof(struct sector_table));
    cache_read(data->indirect, indirect_table, 512, 0);
    
    for(j = 0; j < 128; j++)
    {
      if(sectors == 0)
        break;
      free_map_release(indirect_table->table[j], 1);
      sectors--;
    }
    free_map_release(data->indirect, 1);
    free(indirect_table);

  }
  //free_map_release(data->doubly_indirect, 1);
  free(doubly_indirect_table);
}
Exemplo n.º 4
0
void inode_deallocate_data_blocks(struct inode* inode){
	struct inode_disk disk_inode = inode->data;
	int i, size = disk_inode.length;
	if(size<=DIRECT_ACCESS){
		for(i=0; i<DIV_ROUND_UP(size, BLOCK_SECTOR_SIZE); i++){
			free_map_release(disk_inode.direct[i], 1);
		}
		return;
	}
	if(size<= DIRECT_ACCESS+INDIRECT_ACCESS){
		for(i=0; i<N_DIRECT_BLOCKS; i++){
			free_map_release(disk_inode.direct[i], 1);
		}
		size-=DIRECT_ACCESS;
		uint32_t* indirect_block = (uint32_t*)malloc(BLOCK_SECTOR_SIZE);
		cached_read(inode, disk_inode.indirect,indirect_block);
		for(i=0; i<DIV_ROUND_UP(size, BLOCK_SECTOR_SIZE); i++){
			free_map_release(indirect_block[i], 1);
		}
		free_map_release(disk_inode.indirect, 1);
		free(indirect_block);
		return;
	}
	if(size<=DIRECT_ACCESS+INDIRECT_ACCESS+DOUBLE_INDIRECT_ACCESS){
		uint32_t* buff = (uint32_t*)malloc(BLOCK_SECTOR_SIZE);
		for(i=0; i<N_DIRECT_BLOCKS; i++){
			free_map_release(disk_inode.direct[i], 1);
		}
		size-=DIRECT_ACCESS;
		uint32_t* indirect_block = (uint32_t*)malloc(BLOCK_SECTOR_SIZE);
		cached_read(inode, disk_inode.indirect,indirect_block);
		for(i=0; i<N_INDIRECT_POINTERS; i++){
			free_map_release(indirect_block[i], 1);
		}
		free_map_release(disk_inode.indirect, 1);
		free(indirect_block);
		size-=INDIRECT_ACCESS;
		uint32_t* double_indirect_block = (uint32_t*)malloc(BLOCK_SECTOR_SIZE);
		cached_read(inode, disk_inode.double_indirect,double_indirect_block);
		int c_size = size;
		int i,j;
		for(i=0; i<DIV_ROUND_UP(c_size, N_INDIRECT_POINTERS*BLOCK_SECTOR_SIZE); i++){
			cached_read(inode, double_indirect_block[i], buff);
			for(j=0; j<N_INDIRECT_POINTERS && j<DIV_ROUND_UP(size, BLOCK_SECTOR_SIZE); j++){
				free_map_release(buff[j], 1);
				
			}
			size-=BLOCK_SECTOR_SIZE*N_INDIRECT_POINTERS;
			free_map_release(double_indirect_block[i],1);
		}
		free_map_release(disk_inode.double_indirect, 1);
		free(double_indirect_block);
		free(buff);
		return;
	}
}
Exemplo n.º 5
0
/* Creates directory. True if successful. */
bool 
filesys_mkdir (const char *dir)
{
  bool success = false;

  /*The string *dir cannot be empty.*/
  if (*dir == NULL)
    {
      return success;
    }

  /* Locates the directory where the new directory should be created. */
  struct dir *create_dir;
  char parsed_name[NAME_MAX + 1];
  parse_path (dir, &create_dir, parsed_name);

  block_sector_t sector;
  /*Find a free sector for the directory.*/
  if (!free_map_allocate (1, &sector))
    {
      return success;
    }

  success = dir_create (sector, 16);
  if (!success)
    {
      free_map_release (sector, 1);
      return success;
    }

  success = dir_add (create_dir, parsed_name, sector);
  if (!success)
    {
      free_map_release (sector, 1);
      return success;
    }

  /* Get the dir struct of the directory that is just created and add "." and "..". */
  struct inode *inode = inode_open (sector);
  struct dir *new_dir = dir_open (inode);

  ASSERT (inode != NULL);
  ASSERT (new_dir != NULL);

  dir_add (new_dir, ".", sector);
  dir_add (new_dir, "..", create_dir->inode->sector);
  dir_close (new_dir);
  dir_close (create_dir);

  return success; 
}
Exemplo n.º 6
0
/* Closes INODE and writes it to disk.
   If this was the last reference to INODE, frees its memory.
   If INODE was also a removed inode, frees its blocks. */
void
inode_close (struct inode *inode)
{
    /* Ignore null pointer. */
    if (inode == NULL)
        return;
    /* Release resources if this was the last opener. */
    if (--inode->open_cnt == 0)
    {
        /* Remove from inode list and release lock. */
        list_remove (&inode->elem);

        /* Deallocate blocks if removed. */
        if (inode->removed)
        {

            int sectors = bytes_to_sectors(inode->data.length);
            block_sector_t bounce[128];
            block_sector_t inbounce[128];
            int i,j;
            int doublesec = DIV_ROUND_UP(sectors,128);

            free_map_release (inode->sector, 1);

            lock_acquire(&device_lock);
            block_read(fs_device,inode->data.start,bounce);
            lock_release(&device_lock);
            for(i=0; i<doublesec; i++)
            {
                int loop = sectors < 128 ? sectors : 128;
                lock_acquire(&device_lock);
                block_read(fs_device,bounce[i],inbounce);
                lock_release(&device_lock);
                for(j=0; j<loop; j++)
                {
                    free_map_release(inbounce[j],1);
                }
                sectors -=loop;
                free_map_release(bounce[i],1);
            }
            free_map_release(inode->data.start,1);

            //free_map_release (inode->data.start,
            //										bytes_to_sectors (inode->data.length));

        }

        free (inode);
    }
}
Exemplo n.º 7
0
/* Closes INODE and writes it to disk.
   If this was the last reference to INODE, frees its memory.
   If INODE was also a removed inode, frees its blocks. */
void
inode_close (struct inode *inode) 
{
  /* Ignore null pointer. */
  if (inode == NULL)
    return;

  /* Release resources if this was the last opener. */
  if (--inode->open_cnt == 0)
    {
      /* Remove from inode list and release lock. */
      list_remove (&inode->elem);
 
      /* Deallocate blocks if removed. */
      if (inode->removed) 
        {
          int num_sectors = bytes_to_sectors (inode->length);
          inode_release_allocated_sectors (inode, num_sectors); 
          uint8_t buf[BLOCK_SECTOR_SIZE];
          memset (buf, 0, BLOCK_SECTOR_SIZE);
          block_write (fs_device, inode->sector, buf);
          free_map_release (inode->sector, 1);
        }

      free (inode); 
    }
}
Exemplo n.º 8
0
/* Creates a file named NAME with the given INITIAL_SIZE.
   Returns true if successful, false otherwise.
   Fails if a file named NAME already exists,
   or if internal memory allocation fails. */
bool
filesys_create (const char *name, off_t initial_size) 
{

  block_sector_t inode_sector = 0;
  struct dir *dir;
  char parsed_name[NAME_MAX + 1];
  
  if (*name == NULL || (strlen (name) > NAME_MAX))
    {
      return false;
    }
  bool success = parse_path (name, &dir, parsed_name);
  if (!success)
    {
      return success;
    }

  struct inode *inode;

  success = (dir != NULL
                  && free_map_allocate (1, &inode_sector)
                  && inode_create (inode_sector, initial_size, false)
                  && dir_add (dir, parsed_name, inode_sector)
                  && dir_lookup (dir, ".", &inode));
  if (!success && inode_sector != 0) 
    free_map_release (inode_sector, 1);
  dir_close (dir);


  return success;
}
Exemplo n.º 9
0
/* Closes INODE and writes it to disk.
   If this was the last reference to INODE, frees its memory.
   If INODE was also a removed inode, frees its blocks. */
void
inode_close (struct inode *inode) 
{
  /* Ignore null pointer. */
  if (inode == NULL)
    return;

  /* Release resources if this was the last opener. */
  if (--inode->open_cnt == 0)
    {
      /* Remove from inode list and release lock. */
      list_remove (&inode->elem);
 
      /* Deallocate blocks if removed. */
      if (inode->removed) 
        {
          free_map_release (inode->sector, 1);
          //free_map_release (inode->data.start,
          //                  bytes_to_sectors (inode->data.length)); 
          deallocate_sectors(&inode->data);
        }

      free (inode); 
    }
}
Exemplo n.º 10
0
/* Creates a file named NAME with the given INITIAL_SIZE.
   Returns true if successful, false otherwise.
   Fails if a file named NAME already exists,
   or if internal memory allocation fails. */
bool
filesys_create (const char *path, off_t initial_size)
{
  block_sector_t inode_sector = 0;
  struct dir *dir = NULL;
  bool success = false;
  char *name = malloc (NAME_MAX + 1);
  if (name == NULL)
    goto done;
  if (!dir_follow_path (thread_current ()->cwd, path, &dir, name))
    goto done;

  success = (dir != NULL
             && free_map_allocate (1, &inode_sector)
             && inode_create (inode_sector, initial_size)
             && dir_add (dir, name, inode_sector));
  if (!success && inode_sector != 0)
  {
    cache_remove (fs_cache, inode_sector, 1);
    free_map_release (inode_sector, 1);
  }
done:
  dir_close (dir);
  free (name);
  return success;
}
Exemplo n.º 11
0
/* Creates a file named NAME with the given INITIAL_SIZE.
   Returns true if successful, false otherwise.
   Fails if a file named NAME already exists,
   or if internal memory allocation fails. */
bool
filesys_create (const char *name, off_t initial_size, enum file_type type) 
{
  block_sector_t inode_sector = 0;

  char * parse = parse_filename (name); 
  //get the correct dir

  struct dir *dir = dir_lookup_rec (parse);

  bool success = (dir != NULL
                  && free_map_allocate (1, &inode_sector)
                  && inode_create (inode_sector, initial_size, type)
                  && dir_add (dir, parse, inode_sector));

  if (!success && inode_sector != 0) 
    free_map_release (inode_sector, 1);
  if( success == true && type == FILE_DIR ) {
	//we want to add . and .. as well if it is a dir
		//open the created directory
		struct file * created = filesys_open(parse);
		struct dir * mydir = dir_open(file_get_inode (created));
		//add . to it
		dir_add (mydir, ".", inode_sector);
		struct inode * parent = dir_get_inode (dir);
		block_sector_t inode_sector_parent = inode_id(parent);
		//add .. to it
		dir_add (mydir, "..", inode_sector_parent);
		dir_close(mydir);
		file_close(created);
  }
  dir_close (dir);

  return success;
}
Exemplo n.º 12
0
/* help to free_map_release single indirect index sectors from beginning
 *  to end_idx (exclusive) */
static void free_map_release_single_indirect(struct indirect_block *ib,
		int end_idx){
	int i;
	for (i = 0; i < end_idx; i++) {
		free_map_release (ib->sectors[i], 1);
	}
}
Exemplo n.º 13
0
/* Creates a file named NAME with the given INITIAL_SIZE.
   Returns true if successful, false otherwise.
   Fails if a file named NAME already exists,
   or if internal memory allocation fails. */
bool
filesys_create (const char *name, off_t initial_size, bool isdir)
{
  block_sector_t inode_sector = 0;
  // Get directory
  struct dir *dir = get_containing_dir(name);

  char *file_name = get_filename(name);

  // Get file name
  char* file_name = get_filename(name);

  bool success = false;
  if (strcmp(file_name, ".") != 0 && strcmp(file_name, "..") != 0)
  {
    success = (dir != NULL
               && free_map_allocate (1, &inode_sector)
               && inode_create (inode_sector, initial_size, isdir)
               && dir_add (dir, file_name, inode_sector));
  }
  if (!success && inode_sector != 0)
    free_map_release (inode_sector, 1);
  dir_close (dir);
  free(file_name);

  return success;
}
Exemplo n.º 14
0
/* Closes INODE and writes it to disk.
   If this was the last reference to INODE, frees its memory.
   If INODE was also a removed inode, frees its blocks. */
void
inode_close (struct inode *inode)
{
  /* Ignore null pointer. */
  if (inode == NULL)
    return;

  /* Release resources if this was the last opener. */
  if (--inode->open_cnt == 0)
    {
      lock_acquire (&inode->lock);

      /* Remove from inode list and release lock. */
      list_remove (&inode->elem);

      /* Deallocate blocks if removed. */
      if (inode->removed)
        {
          inode_clear (inode);
          free_map_release (inode->sector, 1);
        }

      lock_release (&inode->lock);
      free (inode);
    }
}
Exemplo n.º 15
0
/* help to free_map_release direct index sectors from beginning to
 * end_idx (exclusive) */
static void free_map_release_direct(struct inode_disk *disk_inode,
		int end_idx) {
	int i;
	for (i = 0; i < end_idx; i++) {
		free_map_release(disk_inode->direct_idx[i], 1);
	}
}
Exemplo n.º 16
0
void inode_delete(disk_sector_t sector){
  struct inode_disk *disk_inode;
  disk_inode = calloc (1, sizeof *disk_inode);
  if(disk_inode != NULL){
    cache_read(sector, disk_inode, 0, DISK_SECTOR_SIZE);
    if(disk_inode->level == 0)
      free_map_release(disk_inode->inode_index, disk_inode->count);
    else{
      size_t i;
      for(i=0;i<disk_inode->count;i++)
        inode_delete(disk_inode->inode_index[i]);
    }
    free(disk_inode);
  }
  free_map_release(&sector, 1);
}
Exemplo n.º 17
0
/* Closes INODE and writes it to disk.
   If this was the last reference to INODE, frees its memory.
   If INODE was also a removed inode, frees its blocks. */
void
inode_close (struct inode *inode) 
{
  /* Ignore null pointer. */
  if (inode == NULL)
    return;

  /* Release resources if this was the last opener. */
  if (--inode->open_cnt == 0)
    {
      /* Remove from inode list and release lock. */
      list_remove (&inode->elem);
 
      /* Deallocate blocks if removed. */
      if (inode->removed) //inode is to be deleted
        {
		  cache_remove(inode,SECTOR_NONE);
		  inode_deallocate_data_blocks(inode);
          free_map_release (inode->sector, 1);
          //free_map_release (inode->data.start, bytes_to_sectors (inode->data.length)); 
          free(inode);
          return;
        }
	  cache_flush(inode,SECTOR_NONE);
	  cache_remove(inode,SECTOR_NONE);
      free (inode); 
    }
}
Exemplo n.º 18
0
/* Closes INODE and writes it to disk.
   If this was the last reference to INODE, frees its memory.
   If INODE was also a removed inode, frees its blocks. */
void
inode_close (struct inode *inode) 
{
	if(INODE_DEBUG || FILE_DEBUG) printf("INODE: closing inode %u \n", inode->sector);
	if(INODE_PRINT) inode_print(inode);

	/* Ignore null pointer. */
	if (inode == NULL)
		return;
	
	/* Release resources if this was the last opener. */
	if (--inode->open_cnt == 0)
	{
		lock_acquire(&inode->lock);

		/* Remove from inode list and release lock. */
		list_remove (&inode->elem);

		/* Deallocate blocks if removed. */
		if (inode->removed)
		{
			if(INODE_DEBUG) printf("INODE: removing inode %u\n", inode->sector);

			/* truncate inode to size 0 */
			inode_truncate(inode);

			/* release inode */
			free_map_release (inode->sector, 1);
		}

		lock_release(&inode->lock);

		free (inode);
	}
}
Exemplo n.º 19
0
/* Creates a file named NAME with the given INITIAL_SIZE.
   Returns true if successful, false otherwise.
   Fails if a file named NAME already exists,
   or if internal memory allocation fails. */
bool
filesys_create (const char *name, off_t initial_size,bool is_dir) 
{
//  printf("create start: %s\n",name);
//  printf("%s size: %d\n",name,initial_size);
  disk_sector_t inode_sector = 0;
  char *file_name = get_file_name(name);
  bool success=true;
  if( strcmp(file_name,"")==0 )
  {
    return false;
  }
//  if( is_dir)
//    printf("mkdir!\n");
//  printf("file name : %s\n",file_name);
  struct dir *dir = get_directory(name);
//  printf("sector of dir :  %d\n", inode_get_inumber(dir_get_inode(dir)));
//  if( inode_get_parent(dir_get_inode(dir)) ==0 )
//    {
//    printf("its on root directory!\n");
//    }
/*  if(dir == NULL)
  {
    printf("no directory\n");
    success=false;
  }
  if(!free_map_allocate(1,&inode_sector))
  {
    printf("no free map\n");
    success=false;
  }
  if(!inode_create(inode_sector,initial_size,is_dir))
  {
    printf("inode create fail\n");
    success=false;
  }
  if(!dir_add(dir,file_name,inode_sector))
  {
    printf("dir add fail\n");
    success=false;
  }*/
//  printf("file name:%s\n",file_name);
  success = (dir != NULL
                  && free_map_allocate (1, &inode_sector)
                  && inode_create (inode_sector, initial_size, is_dir)
                  && dir_add (dir, file_name, inode_sector));
  
  if (!success && inode_sector != 0)
  {
//    printf("haha\n");
    free_map_release (inode_sector, 1);
  }
  dir_close (dir);
//  printf("create end sector num : %d\n",inode_sector);
  free(file_name);
  return success;
}
Exemplo n.º 20
0
/* padding zeros from start_pos (inclusive) to end_pos (exclusive) */
bool zero_padding(struct inode *inode, struct inode_disk *id,
		off_t start_pos, off_t end_pos) {
	ASSERT(lock_held_by_current_thread (&inode->inode_lock));
	static char zeros[BLOCK_SECTOR_SIZE];
	/* padding the first partial sector */
	if (start_pos % BLOCK_SECTOR_SIZE != 0) {
		block_sector_t eof_sector = byte_to_sector(inode, start_pos-1);
		off_t sector_ofs = start_pos % BLOCK_SECTOR_SIZE;
		size_t zero_bytes = BLOCK_SECTOR_SIZE - sector_ofs;
		cache_write(eof_sector, zeros, sector_ofs, zero_bytes);
	}

	/* padding full sectors until end_pos-1 */
	int extra_sectors = (int)bytes_to_sectors(end_pos)-
			(int)bytes_to_sectors(start_pos);
	off_t* record_sectors=malloc(sizeof(off_t) * extra_sectors);
	off_t i,j;
	block_sector_t new_sector=-1;
	for(i=0;i<extra_sectors;i++){
		if (!free_map_allocate (1, &new_sector)) {
			for(j=0;j<i;j++){
				free_map_release(record_sectors[i],1);
			}
			free(record_sectors);
			return false;
		}
		if(!append_sector_to_inode(id,new_sector)){
			for(j=0;j<i;j++){
				free_map_release(record_sectors[i],1);
			}
			free(record_sectors);
			return false;
		}
		cache_write(new_sector, zeros, 0, BLOCK_SECTOR_SIZE);
		record_sectors[i]=new_sector;
		id->length += BLOCK_SECTOR_SIZE;
	}
	/*update the physical length info*/
	id->length=end_pos;
	cache_write(inode->sector, id, 0, BLOCK_SECTOR_SIZE);
	free(record_sectors);
	return true;

}
Exemplo n.º 21
0
static bool exit_now(struct inode_disk *disk_inode, off_t length){
    size_t cur = bytes_to_sectors(length);
    size_t i,loop;

    // Direct
    loop = cur > 124 ? 0 : cur;
    for (i = loop; i < 124; i++){
        free_map_release(disk_inode->start + i, 1);
    }
    disk_inode->length = length;
    return false;
}
Exemplo n.º 22
0
/*! Creates a file named NAME with the given INITIAL_SIZE.  Returns true if
    successful, false otherwise.  Fails if a file named NAME already exists,
    or if internal memory allocation fails. */
bool filesys_create(const char *name, off_t initial_size) {
    block_sector_t inode_sector = 0;
    struct dir *dir = dir_open_root();
    bool success = (dir != NULL &&
                    free_map_allocate(1, &inode_sector) &&
                    inode_create(inode_sector, initial_size) &&
                    dir_add(dir, name, inode_sector));
    if (!success && inode_sector != 0) 
        free_map_release(inode_sector, 1);
    dir_close(dir);

    return success;
}
Exemplo n.º 23
0
void dinode_free (struct inode_disk *dinode)
{
  /* Free double indirect block */
  while (dinode->dindir_cnt != 0)
  {
    struct indir_block d_block, block;
    
    block_read(fs_device, dinode->dindirect[dinode->dindir_cnt-1], &d_block);
     /* We've just got the level 1 block, so now we have to free the level 2 block. */

    while (dinode->dindir_curr_usage != 0)
    { 
      block_read(fs_device, d_block.ptr[dinode->dindir_curr_usage-1], &block);
      /* We've just got the level 2 block, so now we have to free the actual data block. */

      while (dinode->dindir_lv2_curr_usage != 0)
      {
        free_map_release(block.ptr[dinode->dindir_lv2_curr_usage-1],1);
        dinode->dindir_lv2_curr_usage--;
      } 
      
      /* erase the level 2 block */
      free_map_release(d_block.ptr[dinode->dindir_curr_usage-1],1);
      dinode->dindir_curr_usage--;
      if(dinode->dindir_curr_usage != 0) dinode->dindir_lv2_curr_usage = INDIR_BLOCK_PTRS;
    }
    
    /* erase the level 1 block */
    free_map_release(dinode->dindirect[dinode->dindir_cnt-1],1);
    dinode->dindir_cnt--;
    if(dinode->dindir_cnt != 0) dinode->dindir_curr_usage = INDIR_BLOCK_PTRS;
  }
  
  /* Free single indirect block */
  while (dinode->indir_cnt != 0)
  {
    struct indir_block block; 

    block_read(fs_device, dinode->indirect[dinode->indir_cnt-1], &block);

    while (dinode->indir_curr_usage != 0)
    {
      free_map_release(block.ptr[dinode->indir_curr_usage-1],1);
      dinode->indir_curr_usage--;
    }

    free_map_release(dinode->indirect[dinode->indir_cnt-1],1);
    dinode->indir_cnt--;
    if(dinode->indir_cnt != 0) dinode->indir_curr_usage = INDIR_BLOCK_PTRS;
  }

  while (dinode->dir_cnt != 0)
  {
    free_map_release (dinode->direct[dinode->dir_cnt-1],1);
    dinode->dir_cnt--;
  }
}
Exemplo n.º 24
0
/* Creates a file named NAME with the given INITIAL_SIZE.*/
bool
filesys_create (const char *name, off_t initial_size, bool isdir) 
{
  if (strlen(name) == 0) return false;
  block_sector_t inode_sector = 0;

  struct dir *dir_ = filesys_get_dir(name);
  char *name_ = filesys_get_name(name);
  bool success = false;

  if (strcmp (name_, "") == 0) goto done;
  success = (dir_ && free_map_allocate (1, &inode_sector)
    && inode_create (inode_sector, initial_size) 
    && dir_add (dir_, name_, inode_sector, isdir));

  struct inode *ninode = NULL;
  struct dir *ndir = NULL;
  bool success1 = true;
  if (success && isdir){
    success1 = ((ninode = inode_open (inode_sector))
      && (ndir = dir_open (ninode))
      && dir_add (ndir, ".", inode_sector, true)
      && dir_add (ndir, "..",inode_get_inumber (dir_get_inode (dir_)), true));
  }

  if (inode_sector != 0 && !success) 
    free_map_release (inode_sector, 1);

  if (success && !success1) {
    success = false;
    printf("Failure: create dir: %s\n", name);
    dir_remove (dir_, name_);
  }

  done:
    dir_close (dir_);

  free(name_);
  if (!ndir && ninode){
    inode_close(ninode);
  } else if (ndir) {
    dir_close(ndir);
  }

  return success;
}
Exemplo n.º 25
0
/* Free all blocks allocated for a given inode on close. */
static void close_blocks_for_inode (struct inode *inode) {
  unsigned i = 0, j = 0, k = 0;
  /* Free direct blocks. */
  for(; i < DIRECT_BLOCKS; i++) {
    if (inode->data.blocks[i] == NO_BLOCK) break;
    free_map_release (inode->data.blocks[i], 1);
  }
  
  /* Free indirect blocks. */
  block_sector_t data[INDIRECT_SIZE];
  for (; j < INDIRECT_BLOCKS; j++) {
    block_sector_t block = inode->data.blocks[j + DIRECT_BLOCKS];
    if (block == NO_BLOCK) break;
    block_read_cache (fs_device, block, 
                      data, 0, BLOCK_SECTOR_SIZE, true,
                      data[j + DIRECT_BLOCKS + 1]);
    for (; k < INDIRECT_SIZE; k++) {
      if (data[k] == NO_BLOCK) break;
      free_map_release (data[k], 1);
    }
    free_map_release (inode->data.blocks[j + DIRECT_BLOCKS], 1);
  }
  
  /* Free doubly indirect blocks && related storage. */
  if (inode->data.blocks[DIRECT_BLOCKS + INDIRECT_BLOCKS] != NO_BLOCK) {
    block_sector_t indirect_data[INDIRECT_SIZE];
    block_read_cache (fs_device, 
                      inode->data.blocks[DIRECT_BLOCKS + INDIRECT_BLOCKS],
                      indirect_data, 0, BLOCK_SECTOR_SIZE, true, -1);
    j = 0; k = 0;
    for (; j < INDIRECT_SIZE; j++) {
      block_sector_t indirect = indirect_data[j];
      if (indirect == NO_BLOCK) break;
      block_read_cache (fs_device, indirect, data,
                        0, BLOCK_SECTOR_SIZE, true, 
                        (j == INDIRECT_SIZE - 1) ? NO_BLOCK : 
                          indirect_data[j + 1]);
      for (; k < INDIRECT_SIZE; k++) {
        if (indirect == NO_BLOCK) break;
        free_map_release (data[k], 1);
      }
      free_map_release (indirect, 1);
    }
    free_map_release (inode->data.blocks[DIRECT_BLOCKS + INDIRECT_BLOCKS], 1);
  }
  
  free_map_release (inode->sector, 1);
}
Exemplo n.º 26
0
/* Creates a file named NAME with the given INITIAL_SIZE.
   Returns true if successful, false otherwise.
   Fails if a file named NAME already exists,
   or if internal memory allocation fails. */
bool
filesys_create (const char *path, off_t initial_size) 
{
  char *name = get_filename (path);
  block_sector_t inode_sector = 0;

  struct dir *dir = dir_get (path);
  bool success = (dir != NULL
                  && free_map_allocate (1, &inode_sector)
                  && inode_create (inode_sector, initial_size, false)
                  && dir_add (dir, name, inode_sector));

  if (!success && inode_sector != 0) 
    free_map_release (inode_sector, 1);

  dir_close (dir);
  free (name);
  return success;
}
Exemplo n.º 27
0
/*! Creates the directory named dir. Return true if successful, but false
 * if dir already exists or if any directory name in dir, besides the last
 * one does not exist. */
bool _mkdir(const char* dir) {
    /* Inode for the new directory created. */
    struct inode* next_inode;
    
    /* Parent directory. */
    struct dir* cur_dir;
    
    /* Name of the directory. */
    char name[15];
    
    /* Sector number allocated to the new directory. */
    block_sector_t sector;
    
    /* Check the validity of the pointer*/
    if (!checkva(dir))
       exit(-1);
    
    /* The compose the path to a final dir name and its parent directory. */
    if (!decompose_dir(dir, name, &cur_dir)){
        return false;
    }
    ASSERT(cur_dir != NULL);
    
    /* Allocate a new sector for this new directory;
     * Create a new directory */
    if (!free_map_allocate(1, &sector) || 
        !dir_create(sector, 0, dir_get_inode(cur_dir)->sector)){
        
        dir_close(cur_dir);
        return false;
    }
    
    /* Add the new directory to its parent directory. */
    if (!dir_add(cur_dir, name, sector)){
        free_map_release(sector, 1);
        dir_close(cur_dir);
        return false;
    }
    
    dir_close(cur_dir);
    return true;
}
/* Creates a file named NAME with the given INITIAL_SIZE.
   Returns true if successful, false otherwise.
   Fails if a file named NAME already exists,
   or if internal memory allocation fails. */
bool
filesys_create (const char *name, off_t initial_size) 
{
  block_sector_t inode_sector = 0;
  struct thread *cur = thread_current();
  struct dir *dir;
  if(cur->current_directory == NULL)
    dir = dir_open_root ();
  else
    dir = dir_open_current();
  bool success = (dir != NULL
                  && free_map_allocate (1, &inode_sector)
                  && inode_create (inode_sector, initial_size, false)
                  && dir_add (dir, name, inode_sector));
  if (!success && inode_sector != 0) 
    free_map_release (inode_sector, 1);
  dir_close (dir);

  return success;
}
Exemplo n.º 29
0
static void free_inode_blocks_rec (int level, block_sector_t b)
{
  if (b == 0)
    return;

  if (level > 0)
  {
    size_t i;
    size_t unit = sizeof(block_sector_t);
    for (i = 0; i < DIRECT_ENTRY_CNT; i++)
    {
      block_sector_t nb;
      cache_read (fs_cache, b, &nb, unit * i, unit);
      free_inode_blocks_rec (level-1, nb);
    }
  }

  cache_remove (fs_cache, b, 1);
  free_map_release (b, 1);
}
Exemplo n.º 30
0
/* Creates a file named NAME with the given INITIAL_SIZE.
   Returns true if successful, false otherwise.
   Fails if a file named NAME already exists,
   or if internal memory allocation fails. */
bool
filesys_create (const char *name, off_t initial_size) 
{
  char *cp_name   = malloc( sizeof(char) * (strlen(name) + 1) );
  char *file_name = malloc( sizeof(char) * (strlen(name) + 1) ); 
  if( cp_name == NULL || file_name == NULL)
	  return false;
  strlcpy(cp_name, name, strlen(name)+1);
  block_sector_t inode_sector = 0;
  struct dir *dir = parse_path (cp_name, file_name);
  bool success = (dir != NULL
                  && free_map_allocate (1, &inode_sector)
                  && inode_create (inode_sector, initial_size, IS_FILE)
                  && dir_add (dir, file_name, inode_sector));
  if (!success && inode_sector != 0) 
    free_map_release (inode_sector, 1);
  dir_close (dir);
  free(cp_name);
  free(file_name);
  return success;
}