Esempio n. 1
0
int bdev_minor_reopen(dev_t dev)
{
    /* Reopen all minor devices on a major device. This function duplicates some
     * code from elsewhere, because in this case we must avoid performing recovery.
     * FIXME: if reopening fails with a non-IPC error, we should attempt to close
     * all minors that we did manage to reopen so far, or they might stay open
     * forever.
     */
    endpoint_t endpt;
    message m;
    int i, j, r, major;

    major = major(dev);
    endpt = bdev_driver_get(dev);

    assert(endpt != NONE);

    for (i = 0; i < NR_OPEN_DEVS; i++) {
        if (major(open_dev[i].dev) != major)
            continue;

        /* Each minor device may have been opened multiple times. Send an open
         * request for each time that it was opened before. We could reopen it
         * just once, but then we'd have to keep a shadow open count as well.
         */
        for (j = 0; j < open_dev[i].count; j++) {
            memset(&m, 0, sizeof(m));
            m.m_type = BDEV_OPEN;
            m.m_lbdev_lblockdriver_msg.minor = minor(open_dev[i].dev);
            m.m_lbdev_lblockdriver_msg.access = open_dev[i].access;
            m.m_lbdev_lblockdriver_msg.id = NO_ID;

            if ((r = ipc_sendrec(endpt, &m)) != OK) {
                printf("bdev: IPC to driver (%d) failed (%d)\n",
                       endpt, r);
                return r;
            }

            if (m.m_type != BDEV_REPLY) {
                printf("bdev: driver (%d) sent weird response (%d)\n",
                       endpt, m.m_type);
                return EINVAL;
            }

            if (m.m_lblockdriver_lbdev_reply.id != NO_ID) {
                printf("bdev: driver (%d) sent invalid ID (%ld)\n",
                       endpt, m.m_lblockdriver_lbdev_reply.id);
                return EINVAL;
            }

            if ((r = m.m_lblockdriver_lbdev_reply.status) != OK) {
                printf("bdev: driver (%d) failed device reopen (%d)\n",
                       endpt, r);
                return r;
            }
        }
    }

    return OK;
}
Esempio n. 2
0
static int bdev_rdwt_setup(int req, dev_t dev, u64_t pos, char *buf,
  size_t count, int flags, message *m)
{
/* Set up a single-buffer read/write request.
 */
  endpoint_t endpt;
  cp_grant_id_t grant;
  int access;

  assert((ssize_t) count >= 0);

  if ((endpt = bdev_driver_get(dev)) == NONE)
	return EDEADSRCDST;

  access = (req == BDEV_READ) ? CPF_WRITE : CPF_READ;

  grant = cpf_grant_direct(endpt, (vir_bytes) buf, count, access);

  if (!GRANT_VALID(grant)) {
	printf("bdev: unable to allocate grant!\n");
	return EINVAL;
  }

  memset(m, 0, sizeof(*m));
  m->m_type = req;
  m->BDEV_MINOR = minor(dev);
  m->BDEV_POS_LO = ex64lo(pos);
  m->BDEV_POS_HI = ex64hi(pos);
  m->BDEV_COUNT = count;
  m->BDEV_GRANT = grant;
  m->BDEV_FLAGS = flags;

  return OK;
}
Esempio n. 3
0
static int bdev_ioctl_setup(dev_t dev, int request, void *buf, message *m)
{
/* Set up an I/O control request.
 */
  endpoint_t endpt;
  size_t size;
  cp_grant_id_t grant;
  int access;

  if ((endpt = bdev_driver_get(dev)) == NONE)
	return EDEADSRCDST;

  if (_MINIX_IOCTL_BIG(request))
	size = _MINIX_IOCTL_SIZE_BIG(request);
  else
	size = _MINIX_IOCTL_SIZE(request);

  access = 0;
  if (_MINIX_IOCTL_IOR(access)) access |= CPF_WRITE;
  if (_MINIX_IOCTL_IOW(access)) access |= CPF_READ;

  /* The size may be 0, in which case 'buf' need not be a valid pointer. */
  grant = cpf_grant_direct(endpt, (vir_bytes) buf, size, access);

  if (!GRANT_VALID(grant)) {
	printf("bdev: unable to allocate grant!\n");
	return EINVAL;
  }

  memset(m, 0, sizeof(*m));
  m->m_type = BDEV_IOCTL;
  m->BDEV_MINOR = minor(dev);
  m->BDEV_REQUEST = request;
  m->BDEV_GRANT = grant;

  return OK;
}
Esempio n. 4
0
static int bdev_vrdwt_setup(int req, dev_t dev, u64_t pos, iovec_t *vec,
  int count, int flags, message *m, iovec_s_t *gvec)
{
/* Set up a vectored read/write request.
 */
  ssize_t size;
  endpoint_t endpt;
  cp_grant_id_t grant;
  int i, access;

  assert(count <= NR_IOREQS);

  if ((endpt = bdev_driver_get(dev)) == NONE)
	return EDEADSRCDST;

  access = (req == BDEV_GATHER) ? CPF_WRITE : CPF_READ;
  size = 0;

  for (i = 0; i < count; i++) {
	grant = cpf_grant_direct(endpt, vec[i].iov_addr, vec[i].iov_size,
		access);

	if (!GRANT_VALID(grant)) {
		printf("bdev: unable to allocate grant!\n");

		for (i--; i >= 0; i--)
			cpf_revoke(gvec[i].iov_grant);

		return EINVAL;
	}

	gvec[i].iov_grant = grant;
	gvec[i].iov_size = vec[i].iov_size;

	assert((ssize_t) (size + vec[i].iov_size) > size);

	size += vec[i].iov_size;
  }

  grant = cpf_grant_direct(endpt, (vir_bytes) gvec, sizeof(gvec[0]) * count,
	CPF_READ);

  if (!GRANT_VALID(grant)) {
	printf("bdev: unable to allocate grant!\n");

	for (i = count - 1; i >= 0; i--)
		cpf_revoke(gvec[i].iov_grant);

	return EINVAL;
  }

  memset(m, 0, sizeof(*m));
  m->m_type = req;
  m->BDEV_MINOR = minor(dev);
  m->BDEV_POS_LO = ex64lo(pos);
  m->BDEV_POS_HI = ex64hi(pos);
  m->BDEV_COUNT = count;
  m->BDEV_GRANT = grant;
  m->BDEV_FLAGS = flags;

  return OK;
}