Esempio n. 1
0
/* Open system call. */
static int
sys_open (const char *ufile) 
{
  char *kfile = copy_in_string (ufile);
  struct file_descriptor *fd;
  int handle = -1;
 
  fd = calloc (1, sizeof *fd);
  if (fd != NULL)
    {
      struct inode *inode = filesys_open (kfile);
      if (inode != NULL)
        {
          if (inode_get_type (inode) == FILE_INODE)
            fd->file = file_open (inode);
          else
            fd->dir = dir_open (inode);
          if (fd->file != NULL || fd->dir != NULL)
            {
              struct thread *cur = thread_current ();
              handle = fd->handle = cur->next_handle++;
              list_push_front (&cur->fds, &fd->elem);
            }
          else 
            {
              free (fd);
              inode_close (inode);
            }
        }
    }
  
  palloc_free_page (kfile);
  return handle;
}
Esempio n. 2
0
/*******************************************************************************
 fs_ialloc: allocates any free disk inode.
	It allocates the -first- free inode it finds on disk.
*******************************************************************************/
struct inode * fs_ialloc(dev_nr_t dev_nr)
{
	struct super *sp;
	struct inode *ip;
	uint16_t nr_imap_blocks;
	struct buffer *bp;
	mfs_inode_nr_t inode_nr;
	unsigned long int nr_inodes;
	unsigned int i;

	assert(dev_nr, "fs_ialloc(): Zero device number");
	sp = fs_mount_table_get_super(dev_nr);
	/* POSSIBLE INCREMENT OF THE SUPERBLOCK REFERENCE COUNT */

/* IT SHOULD BE ANY WAY OF LOCKING THIS DEVICE SO NO OTHER PROCESS COULD
	UNMOUNT IT */
repeat:
	nr_imap_blocks = super_get_nr_imap_blocks(sp);
	assert(nr_imap_blocks, "fs_ialloc(): Zero # of inode bitmap blocks");
	nr_inodes = super_get_nr_inodes(sp);	

	/* search for any free inode on disk */	
	for (i = 0; i < nr_imap_blocks; i++) {
		if( !(bp = cache_bread(dev_nr, FIRST_IMAP_BLOCK_NR + i)) ) {
			assert(0, "fs_ialloc(): Unable to get inode map block");
		if ( (inode_nr = inode_bitmap_get_zero(bp, i)) )
			break; /* found free inode on inode bitmap */
			/* do not release the bitmap block yet, so we can
			 * mark that free inode as busy later */
		/* did not find a free inode in this inode bitmap */
		cache_brelse(bp);
		}
	}
	/* search for a free inode completed */

	if (!inode_nr)
		return NULL; /* there are no available free inodes */

	assert(inode_nr <= nr_inodes, "fs_ialloc(): wrong inode number");
	
	/* update the inode bitmap, so no other process tries to allocate
		this inode */
	bitmap_set_bit(bp, inode_nr % NR_BITS_PER_BLOCK);
	buffer_set_dirty(bp);
	cache_brelse(bp);
	
	if ( (ip = fs_iget(dev_nr, inode_nr)) )
		assert(0, "fs_ialloc(): Unable to read inode");

	/* check whether the inode is actually free */
	if (0 != inode_get_type(ip)) { /* the inode bitmap is corrupted */
		fs_iput(ip); /* release the inode */		
		goto repeat;
	}
	return ip;
}
Esempio n. 3
0
/* Removes any entry for NAME in DIR.
   Returns true if successful, false on failure,
   which occurs only if there is no file with the given NAME. */
bool
dir_remove (struct dir *dir, const char *name) 
{
  struct dir_entry e;
  struct inode *inode = NULL;
  bool success = false;
  off_t ofs;

  ASSERT (dir != NULL);
  ASSERT (name != NULL);

  /* Find directory entry. */
  if (!lookup (dir, name, &e, &ofs))
    goto done;

  /* Open inode. */
  inode = inode_open (e.inode_sector);
  if (inode == NULL)
    goto done;

  if (inode_get_type(inode) == TYPE_DIRECTORY)
  {
    struct dir *dir = dir_open(inode);
    if (dir_is_empty(dir) == false)
    {
      dir_close(dir);
      goto done;
    }
    dir_close(dir);
  }

  /* Erase directory entry. */
  e.in_use = false;
  if (inode_write_at (dir->inode, &e, sizeof e, ofs) != sizeof e) 
    goto done;

  /* Remove inode. */
  inode_remove (inode);
  success = true;

 done:
  inode_close (inode);
  return success;
}