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; }
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; }
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; }
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; }