Exemple #1
0
/*===========================================================================*
 *				check_vnode_locks			     *
 *===========================================================================*/
PUBLIC void check_vnode_locks()
{
  struct vnode *vp;
  int count = 0;

  for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; vp++)
	if (is_vnode_locked(vp)) {
		count++;
	}

  if (count) panic("%d locked vnodes\n", count);
#if 0
  printf("check_vnode_locks OK\n");
#endif
}
Exemple #2
0
/*===========================================================================*
 *				get_free_vnode				     *
 *===========================================================================*/
struct vnode *get_free_vnode()
{
/* Find a free vnode slot in the vnode table (it's not actually allocated) */
  struct vnode *vp;

  for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; ++vp) {
	if (vp->v_ref_count == 0 && !is_vnode_locked(vp)) {
		vp->v_uid  = -1;
		vp->v_gid  = -1;
		vp->v_sdev = NO_DEV;
		vp->v_mapfs_e = NONE;
		vp->v_mapfs_count = 0;
		vp->v_mapinode_nr = 0;
		return(vp);
	}
  }

  err_code = ENFILE;
  return(NULL);
}
Exemple #3
0
/*===========================================================================*
 *                              unmount					     *
 *===========================================================================*/
int unmount(
  dev_t dev,			/* block-special device */
  char label[LABEL_MAX]		/* buffer to retrieve label, or NULL */
)
{
  struct vnode *vp;
  struct vmnt *vmp_i = NULL, *vmp = NULL;
  int count, locks, r;

  /* Find vmnt that is to be unmounted */
  for (vmp_i = &vmnt[0]; vmp_i < &vmnt[NR_MNTS]; ++vmp_i) {
	  if (vmp_i->m_dev == dev) {
		  if(vmp) panic("device mounted more than once: %d", dev);
		  vmp = vmp_i;
	  }
  }

  /* Did we find the vmnt (i.e., was dev a mounted device)? */
  if(!vmp) return(EINVAL);

  if ((r = lock_vmnt(vmp, VMNT_EXCL)) != OK) return(r);

  /* See if the mounted device is busy.  Only 1 vnode using it should be
   * open -- the root vnode -- and that inode only 1 time. */
  locks = count = 0;
  for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; vp++)
	  if (vp->v_ref_count > 0 && vp->v_dev == dev) {
		count += vp->v_ref_count;
		if (is_vnode_locked(vp)) locks++;
	  }

  if (count > 1 || locks > 1 || tll_haspendinglock(&vmp->m_lock)) {
	unlock_vmnt(vmp);
	return(EBUSY);    /* can't umount a busy file system */
  }

  /* Tell FS to drop all inode references for root inode except 1. */
  vnode_clean_refs(vmp->m_root_node);

  if (vmp->m_mounted_on) {
	put_vnode(vmp->m_mounted_on);
	vmp->m_mounted_on = NULL;
  }

  vmp->m_comm.c_max_reqs = 1;	/* Force max concurrent reqs to just one, so
				 * we won't send any messages after the
				 * unmount request */

  /* Tell FS to unmount */
  if ((r = req_unmount(vmp->m_fs_e)) != OK)              /* Not recoverable. */
	printf("VFS: ignoring failed umount attempt FS endpoint: %d (%d)\n",
	       vmp->m_fs_e, r);

  if (is_nonedev(vmp->m_dev)) free_nonedev(vmp->m_dev);

  if (label != NULL) strlcpy(label, vmp->m_label, LABEL_MAX);

  if (vmp->m_root_node) {	/* PFS lacks a root node */
	vmp->m_root_node->v_ref_count = 0;
	vmp->m_root_node->v_fs_count = 0;
	vmp->m_root_node->v_sdev = NO_DEV;
	vmp->m_root_node = NULL;
  }
  mark_vmnt_free(vmp);

  unlock_vmnt(vmp);

  /* The root FS will handle block I/O requests for this device now. */
  lock_bsf();
  update_bspec(dev, ROOT_FS_E, 1 /* send new driver endpoint */);
  unlock_bsf();

  return(OK);
}