Esempio n. 1
0
/* Shutdown the filesystem; flags are as for fsys_goaway. */
error_t
netfs_shutdown (int flags)
{
  error_t
  helper (struct node *node)
    {
      error_t err;
      mach_port_t control;

      err = fshelp_fetch_control (&node->transbox, &control);
      if (!err && (control != MACH_PORT_NULL))
        {
          mutex_unlock (&node->lock);
          err = fsys_goaway (control, flags);
          mach_port_deallocate (mach_task_self (), control);
          mutex_lock (&node->lock);
        }
      else
        err = 0;

      if ((err == MIG_SERVER_DIED) || (err == MACH_SEND_INVALID_DEST))
        err = 0;

      return err;
    }
Esempio n. 2
0
/* Implement fsys_set_options as described in <hurd/fsys.defs>. */
kern_return_t
diskfs_S_fsys_set_options (fsys_t fsys,
			   mach_port_t reply,
			   mach_msg_type_name_t replytype,
			   char *data, mach_msg_type_number_t len,
			   int do_children)
{
  error_t err = 0;
  struct port_info *pt =
    ports_lookup_port (diskfs_port_bucket, fsys, diskfs_control_class);

  error_t
    helper (struct node *np)
      {
	error_t error;
	mach_port_t control;

	error = fshelp_fetch_control (&np->transbox, &control);
	mutex_unlock (&np->lock);
	if (!error && (control != MACH_PORT_NULL))
	  {
	    error = fsys_set_options (control, data, len, do_children);
	    mach_port_deallocate (mach_task_self (), control);
	  }
	else
	  error = 0;
	mutex_lock (&np->lock);

	if ((error == MIG_SERVER_DIED) || (error == MACH_SEND_INVALID_DEST))
	  error = 0;
	return error;
      }
/* Implement file_get_translator_cntl as described in <hurd/fs.defs>. */
kern_return_t
diskfs_S_file_get_translator_cntl (struct protid *cred,
				   mach_port_t *ctl,
				   mach_msg_type_name_t *ctltype)
{
  struct node *np;
  error_t error;
  
  if (!cred)
    return EOPNOTSUPP;
  
  np = cred->po->np;

  mutex_lock (&np->lock);

  error = fshelp_isowner (&np->dn_stat, cred->user);
  if (!error)
    error = fshelp_fetch_control (&np->transbox, ctl);
  if (!error && *ctl == MACH_PORT_NULL)
    error = ENXIO;
  if (!error)
    *ctltype = MACH_MSG_TYPE_MOVE_SEND;

  mutex_unlock (&np->lock);

  return error;
}
Esempio n. 4
0
/* Implement fsys_syncfs as described in <hurd/fsys.defs>. */
kern_return_t
diskfs_S_fsys_syncfs (struct diskfs_control *pi,
		      mach_port_t reply,
		      mach_msg_type_name_t replytype,
		      int wait,
		      int children)
{
  error_t 
    helper (struct node *np)
      {
	error_t error;
	mach_port_t control;
	
	error = fshelp_fetch_control (&np->transbox, &control);
	pthread_mutex_unlock (&np->lock);
	if (!error && (control != MACH_PORT_NULL))
	  {
	    fsys_syncfs (control, wait, 1);
	    mach_port_deallocate (mach_task_self (), control);
	  }
	pthread_mutex_lock (&np->lock);
	return 0;
      }
Esempio n. 5
0
/* Implement dir_unlink as described in <hurd/fs.defs>. */
kern_return_t
diskfs_S_dir_unlink (struct protid *dircred,
		     char *name)
{
  struct node *dnp;
  struct node *np;
  struct dirstat *ds = alloca (diskfs_dirstat_size);
  error_t err;
  mach_port_t control = MACH_PORT_NULL;

  if (!dircred)
    return EOPNOTSUPP;

  dnp = dircred->po->np;
  if (diskfs_check_readonly ())
    return EROFS;

  pthread_mutex_lock (&dnp->lock);

  err = diskfs_lookup (dnp, name, REMOVE, &np, ds, dircred);
  if (err == EAGAIN)
    err = EPERM;	/* 1003.1-1996 5.5.1.4 */
  if (err)
    {
      diskfs_drop_dirstat (dnp, ds);
      pthread_mutex_unlock (&dnp->lock);
      return err;
    }

  /* This isn't the BSD behavior, but it is Posix compliant and saves
     us on several race conditions.*/
  if (S_ISDIR(np->dn_stat.st_mode))
    {
      if (np == dnp)		/* gotta catch '.' */
	diskfs_nrele (np);
      else
	diskfs_nput (np);
      diskfs_drop_dirstat (dnp, ds);
      pthread_mutex_unlock (&dnp->lock);
      return EPERM;		/* 1003.1-1996 5.5.1.4 */
    }

  err = diskfs_dirremove (dnp, np, name, ds);
  if (diskfs_synchronous)
    diskfs_node_update (dnp, 1);
  if (err)
    {
      diskfs_nput (np);
      pthread_mutex_unlock (&dnp->lock);
      return err;
    }

  np->dn_stat.st_nlink--;
  np->dn_set_ctime = 1;
  if (diskfs_synchronous)
    diskfs_node_update (np, 1);

  if (np->dn_stat.st_nlink == 0)
    fshelp_fetch_control (&np->transbox, &control);

  /* This check is necessary because we might get here on an error while
     checking the mode on something which happens to be `.'. */
  if (np == dnp)
    diskfs_nrele (np);
  else
    diskfs_nput (np);
  pthread_mutex_unlock (&dnp->lock);

  if (control)
    {
      fsys_goaway (control, FSYS_GOAWAY_UNLINK);
      mach_port_deallocate (mach_task_self (), control);
    }

  return err;
}