예제 #1
0
파일: ext2fs.c 프로젝트: GNUHurdTR/hurd
int
main (int argc, char **argv)
{
  error_t err;
  mach_port_t bootstrap;

  /* Initialize the diskfs library, parse arguments, and open the store.
     This starts the first diskfs thread for us.  */
  store = diskfs_init_main (&startup_argp, argc, argv,
			    &store_parsed, &bootstrap);

  if (store->size < SBLOCK_OFFS + SBLOCK_SIZE)
    ext2_panic ("device too small for superblock (%Ld bytes)", store->size);
  if (store->log2_blocks_per_page < 0)
    ext2_panic ("device block size (%zu) greater than page size (%zd)",
		store->block_size, vm_page_size);

  /* Map the entire disk. */
  create_disk_pager ();

  pokel_init (&global_pokel, diskfs_disk_pager, disk_cache);

  map_hypermetadata ();

  /* Set diskfs_root_node to the root inode. */
  err = diskfs_cached_lookup (EXT2_ROOT_INO, &diskfs_root_node);
  if (err)
    ext2_panic ("can't get root: %s", strerror (err));
  else if ((diskfs_root_node->dn_stat.st_mode & S_IFMT) == 0)
    ext2_panic ("no root node!");
  pthread_mutex_unlock (&diskfs_root_node->lock);

  /* Now that we are all set up to handle requests, and diskfs_root_node is
     set properly, it is safe to export our fsys control port to the
     outside world.  */
  diskfs_startup_diskfs (bootstrap, 0);

  /* and so we die, leaving others to do the real work.  */
  pthread_exit (NULL);
  /* NOTREACHED */
  return 0;
}
예제 #2
0
파일: ialloc.c 프로젝트: Larhard/hurd
/* The user must define this function.  Allocate a new node to be of
   mode MODE in locked directory DP (don't actually set the mode or
   modify the dir, that will be done by the caller); the user
   responsible for the request can be identified with CRED.  Set *NP
   to be the newly allocated node.  */
error_t
diskfs_alloc_node (struct node *dir, mode_t mode, struct node **node)
{
  error_t err;
  int sex, block;
  struct node *np;
  struct stat *st;
  ino_t inum;

  assert (!diskfs_readonly);

  inum = ext2_alloc_inode (dir->cache_id, mode);

  if (inum == 0)
    return ENOSPC;

  err = diskfs_cached_lookup (inum, &np);
  if (err)
    return err;

  st = &np->dn_stat;

  if (st->st_blocks)
    {
      st->st_blocks = 0;
      np->dn_set_ctime = 1;
    }
  /* Zero out the block pointers in case there's some noise left on disk.  */
  for (block = 0; block < EXT2_N_BLOCKS; block++)
    if (np->dn->info.i_data[block] != 0)
      {
	np->dn->info.i_data[block] = 0;
	np->dn_set_ctime = 1;
      }
  if (np->dn->info_i_translator != 0)
    {
      np->dn->info_i_translator = 0;
      np->dn_set_ctime = 1;
    }
  st->st_mode &= ~S_IPTRANS;
  if (np->allocsize)
    {
      st->st_size = 0;
      np->allocsize = 0;
      np->dn_set_ctime = 1;
    }

  /* Propagate initial inode flags from the directory, as Linux does.  */
  np->dn->info.i_flags =
    ext2_mask_flags(mode, dir->dn->info.i_flags & EXT2_FL_INHERITED);

  st->st_flags = 0;

  /*
   * Set up a new generation number for this inode.
   */
  pthread_spin_lock (&generation_lock);
  sex = diskfs_mtime->seconds;
  if (++next_generation < (u_long)sex)
    next_generation = sex;
  st->st_gen = next_generation;
  pthread_spin_unlock (&generation_lock);

  alloc_sync (np);

  *node = np;
  return 0;
}
예제 #3
0
/* Return in FILE & FILE_TYPE the file in FSYS corresponding to the NFS file
   handle HANDLE & HANDLE_LEN.  */
error_t
diskfs_S_fsys_getfile (mach_port_t fsys,
		       mach_port_t reply, mach_msg_type_name_t reply_type,
		       uid_t *uids, mach_msg_type_number_t nuids,
		       gid_t *gids, mach_msg_type_number_t ngids,
		       char *handle, mach_msg_type_number_t handle_len,
		       mach_port_t *file, mach_msg_type_name_t *file_type)
{
  int flags;
  error_t err;
  struct node *node;
  const union diskfs_fhandle *f;
  struct protid *new_cred;
  struct peropen *new_po;
  struct iouser *user;
  struct port_info *pt =
    ports_lookup_port (diskfs_port_bucket, fsys, diskfs_control_class);

  if (!pt)
    return EOPNOTSUPP;

  if (handle_len != sizeof *f)
    {
      ports_port_deref (pt);
      return EINVAL;
    }

  f = (const union diskfs_fhandle *) handle;

  err = diskfs_cached_lookup (f->data.cache_id, &node);
  if (err)
    {
      ports_port_deref (pt);
      return err;
    }

  if (node->dn_stat.st_gen != f->data.gen)
    {
      diskfs_nput (node);
      ports_port_deref (pt);
      return ESTALE;
    }

  err = iohelp_create_complex_iouser (&user, uids, nuids, gids, ngids);
  if (err)
    {
      diskfs_nput (node);
      ports_port_deref (pt);
      return err;
    }

  flags = 0;
  if (! fshelp_access (&node->dn_stat, S_IREAD, user))
    flags |= O_READ;
  if (! fshelp_access (&node->dn_stat, S_IEXEC, user))
    flags |= O_EXEC;
  if (! fshelp_access (&node->dn_stat, S_IWRITE, user)
      && ! S_ISDIR (node->dn_stat.st_mode)
      && ! diskfs_check_readonly ())
    flags |= O_WRITE;

  err = diskfs_make_peropen (node, flags, 0, &new_po);
  if (! err)
    {
      err = diskfs_create_protid (new_po, user, &new_cred);
      if (err)
	diskfs_release_peropen (new_po);
    }

  iohelp_free_iouser (user);

  diskfs_nput (node);
  ports_port_deref (pt);

  if (! err)
    {
      *file = ports_get_right (new_cred);
      *file_type = MACH_MSG_TYPE_MAKE_SEND;
    }

  return err;
}
예제 #4
0
/* The user must define this function.  Allocate a new node to be of
   mode MODE in locked directory DP (don't actually set the mode or
   modify the dir, that will be done by the caller); the user
   responsible for the request can be identified with CRED.  Set *NP
   to be the newly allocated node.  */
error_t
diskfs_alloc_node (struct node *dir, mode_t mode, struct node **node)
{
  error_t err;
  int zone_ptr, nzones = sblock_info->s_n_zones;
  struct node *np;
  struct stat *st;
  ino_t inum;

  assert (!diskfs_readonly);

  inum = minixfs_new_inode ();

  if (inum == 0)
    return ENOSPC;

  err = diskfs_cached_lookup (inum, &np);
  if (err)
    return err;

  st = &np->dn_stat;

  if (st->st_blocks)
    {
      st->st_blocks = 0;
      np->dn_set_ctime = 1;
    }

  /* Zero out the zone pointers in case there's some noise left on disk.  */
  if (sblock_info->s_version == MINIX_V1)
    {
      for (zone_ptr = 0; zone_ptr < nzones; zone_ptr++)
	if (np->dn->info.i_zone_V1[zone_ptr] != 0)
	  {
	    np->dn->info.i_zone_V1[zone_ptr] = 0;
	    np->dn_set_ctime = 1;
	  }
    }
  else
    {    
      for (zone_ptr = 0; zone_ptr < nzones; zone_ptr++)
	if (np->dn->info.i_zone_V2[zone_ptr] != 0)
	  {
	    np->dn->info.i_zone_V2[zone_ptr] = 0;
	    np->dn_set_ctime = 1;
	  }
    }

/*   if (np->dn->info_i_translator != 0) */
/*     { */
/*       np->dn->info_i_translator = 0; */
/*       np->dn_set_ctime = 1; */
/*     } */
/*   st->st_mode &= ~S_IPTRANS; */
  if (np->allocsize)
    {
      st->st_size = 0;
      np->allocsize = 0;
      np->dn_set_ctime = 1;
    }

  st->st_flags = 0;
  st->st_gen = 0;

  alloc_sync (np);

  *node = np;
  return 0;
}