Beispiel #1
0
bool dir_add (struct dir *directory, block_sector_t block_sec,
    const char *file)
{
  struct dir_entry directory_element;
  off_t offset;
  bool success = false;

  ASSERT(directory != NULL);
  ASSERT(file != NULL);

  acquire_inode_lock (directory->inode);
  if (*file == '\0' || strlen (file) > MAXIMUM_FILE_NAME_LENGTH)
  {
    release_inode_lock (directory->inode);
    return success;
  }

  for (offset = 0;
      inode_read_at (directory->inode, &directory_element,
          sizeof directory_element, offset) == sizeof directory_element;
      offset += sizeof directory_element)
    if (directory_element.in_use
        && !strcmp (file, directory_element.name))
    {
      release_inode_lock (directory->inode);
      return success;
    }

  if (!inode_add_parent (get_inumber (directory->inode), block_sec))
  {
    release_inode_lock (directory->inode);
    return success;
  }

  for (offset = 0;
      inode_read_at (directory->inode, &directory_element,
          sizeof directory_element, offset) == sizeof directory_element;
      offset += sizeof directory_element)
    if (!directory_element.in_use)
      break;

  directory_element.in_use = true;
  strlcpy (directory_element.name, file,
      sizeof directory_element.name);
  directory_element.inode_sector = block_sec;
  success = inode_write_at (directory->inode, &directory_element,
      sizeof directory_element, offset) == sizeof directory_element;

  release_inode_lock (directory->inode);
  return success;
}
Beispiel #2
0
/* Adds a file named NAME to DIR, which must not already contain a
   file by that name.  The file's inode is in sector
   INODE_SECTOR.
   Returns true if successful, false on failure.
   Fails if NAME is invalid (i.e. too long) or a disk or memory
   error occurs. */
bool
dir_add (struct dir *dir, const char *name, block_sector_t inode_sector)
{
  struct dir_entry e;
  off_t ofs;
  bool success = false;

  ASSERT (dir != NULL);
  ASSERT (name != NULL);
  inode_lock(dir_get_inode (dir));
  /* Check NAME for validity. */
  if (*name == '\0' || strlen (name) > NAME_MAX)
  {  
      inode_unlock (dir_get_inode(dir));
      return false;
  }

  /* Check that NAME is not in use. */
  if (lookup (dir, name, NULL, NULL))
    goto done;

  if (!inode_add_parent (inode_get_inumber (dir_get_inode(dir)),inode_sector))
  {
      goto done;
  }
  
  /* Set OFS to offset of free slot.
     If there are no free slots, then it will be set to the
     current end-of-file.
     
     inode_read_at() will only return a short read at end of file.
     Otherwise, we'd need to verify that we didn't get a short
     read due to something intermittent such as low memory. */
  for (ofs = 0; inode_read_at (dir->inode, &e, sizeof e, ofs) == sizeof e;
       ofs += sizeof e) 
    if (!e.in_use)
      break;

  /* Write slot. */
  e.in_use = true;
  strlcpy (e.name, name, sizeof e.name);
  e.inode_sector = inode_sector;
  success = inode_write_at (dir->inode, &e, sizeof e, ofs) == sizeof e;

 done:
  inode_unlock (dir_get_inode(dir));
  return success;
}