Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_virtio_block.c
Show First 20 Lines • Show All 302 Lines • ▼ Show 20 Lines | |||||
pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq) | pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq) | ||||
{ | { | ||||
struct virtio_blk_hdr *vbh; | struct virtio_blk_hdr *vbh; | ||||
struct pci_vtblk_ioreq *io; | struct pci_vtblk_ioreq *io; | ||||
int i, n; | int i, n; | ||||
int err; | int err; | ||||
ssize_t iolen; | ssize_t iolen; | ||||
int writeop, type; | int writeop, type; | ||||
struct vi_req req; | |||||
struct iovec iov[BLOCKIF_IOV_MAX + 2]; | struct iovec iov[BLOCKIF_IOV_MAX + 2]; | ||||
uint16_t idx, flags[BLOCKIF_IOV_MAX + 2]; | |||||
struct virtio_blk_discard_write_zeroes *discard; | struct virtio_blk_discard_write_zeroes *discard; | ||||
n = vq_getchain(vq, &idx, iov, BLOCKIF_IOV_MAX + 2, flags); | n = vq_getchain(vq, iov, BLOCKIF_IOV_MAX + 2, &req); | ||||
/* | /* | ||||
* The first descriptor will be the read-only fixed header, | * The first descriptor will be the read-only fixed header, | ||||
* and the last is for status (hence +2 above and below). | * and the last is for status (hence +2 above and below). | ||||
* The remaining iov's are the actual data I/O vectors. | * The remaining iov's are the actual data I/O vectors. | ||||
* | * | ||||
* XXX - note - this fails on crash dump, which does a | * XXX - note - this fails on crash dump, which does a | ||||
* VIRTIO_BLK_T_FLUSH with a zero transfer length | * VIRTIO_BLK_T_FLUSH with a zero transfer length | ||||
*/ | */ | ||||
assert(n >= 2 && n <= BLOCKIF_IOV_MAX + 2); | assert(n >= 2 && n <= BLOCKIF_IOV_MAX + 2); | ||||
io = &sc->vbsc_ios[idx]; | io = &sc->vbsc_ios[req.idx]; | ||||
assert((flags[0] & VRING_DESC_F_WRITE) == 0); | assert(req.rd_niov != 0); | ||||
assert(iov[0].iov_len == sizeof(struct virtio_blk_hdr)); | assert(req.rd_iov[0].iov_len == sizeof(struct virtio_blk_hdr)); | ||||
vbh = (struct virtio_blk_hdr *)iov[0].iov_base; | vbh = (struct virtio_blk_hdr *)iov[0].iov_base; | ||||
memcpy(&io->io_req.br_iov, &iov[1], sizeof(struct iovec) * (n - 2)); | memcpy(&io->io_req.br_iov, &iov[1], sizeof(struct iovec) * (n - 2)); | ||||
io->io_req.br_iovcnt = n - 2; | io->io_req.br_iovcnt = n - 2; | ||||
io->io_req.br_offset = vbh->vbh_sector * VTBLK_BSIZE; | io->io_req.br_offset = vbh->vbh_sector * VTBLK_BSIZE; | ||||
io->io_status = (uint8_t *)iov[--n].iov_base; | io->io_status = (uint8_t *)iov[--n].iov_base; | ||||
assert(iov[n].iov_len == 1); | assert(req.wr_niov != 0); | ||||
assert(flags[n] & VRING_DESC_F_WRITE); | assert(req.wr_iov[req.wr_niov - 1].iov_len == 1); | ||||
/* | /* | ||||
* XXX | * XXX | ||||
* The guest should not be setting the BARRIER flag because | * The guest should not be setting the BARRIER flag because | ||||
* we don't advertise the capability. | * we don't advertise the capability. | ||||
*/ | */ | ||||
type = vbh->vbh_type & ~VBH_FLAG_BARRIER; | type = vbh->vbh_type & ~VBH_FLAG_BARRIER; | ||||
writeop = (type == VBH_OP_WRITE || type == VBH_OP_DISCARD); | writeop = (type == VBH_OP_WRITE || type == VBH_OP_DISCARD); | ||||
assert(n == (writeop ? req.rd_niov : req.wr_niov)); | |||||
iolen = 0; | iolen = 0; | ||||
for (i = 1; i < n; i++) { | for (i = 1; i < n; i++) { | ||||
philip: The previous comment inside the loop (deleted lines 348-354 in this diff) was a little clearer. | |||||
/* | |||||
* - write op implies read-only descriptor, | |||||
* - read/ident op implies write-only descriptor, | |||||
* therefore test the inverse of the descriptor bit | |||||
* to the op. | |||||
*/ | |||||
assert(((flags[i] & VRING_DESC_F_WRITE) == 0) == writeop); | |||||
iolen += iov[i].iov_len; | iolen += iov[i].iov_len; | ||||
} | } | ||||
io->io_req.br_resid = iolen; | io->io_req.br_resid = iolen; | ||||
DPRINTF(("virtio-block: %s op, %zd bytes, %d segs, offset %ld", | DPRINTF(("virtio-block: %s op, %zd bytes, %d segs, offset %ld", | ||||
writeop ? "write/discard" : "read/ident", iolen, i - 1, | writeop ? "write/discard" : "read/ident", iolen, i - 1, | ||||
io->io_req.br_offset)); | io->io_req.br_offset)); | ||||
▲ Show 20 Lines • Show All 214 Lines • Show Last 20 Lines |
The previous comment inside the loop (deleted lines 348-354 in this diff) was a little clearer. I agree that the assertion should be outside the loop but the comment could be a little clearer. To a casual reader, the assertion is inverted.