static void flash_sync_page(Flash *s, int page) { int blk_sector, nb_sectors; QEMUIOVector iov; if (!s->blk || blk_is_read_only(s->blk)) { return; } blk_sector = (page * s->pi->page_size) / BDRV_SECTOR_SIZE; nb_sectors = DIV_ROUND_UP(s->pi->page_size, BDRV_SECTOR_SIZE); qemu_iovec_init(&iov, 1); qemu_iovec_add(&iov, s->storage + blk_sector * BDRV_SECTOR_SIZE, nb_sectors * BDRV_SECTOR_SIZE); blk_aio_writev(s->blk, blk_sector, &iov, nb_sectors, blk_sync_complete, NULL); }
static inline void submit_requests(BlockBackend *blk, MultiReqBuffer *mrb, int start, int num_reqs, int niov) { QEMUIOVector *qiov = &mrb->reqs[start]->qiov; int64_t sector_num = mrb->reqs[start]->sector_num; int nb_sectors = mrb->reqs[start]->qiov.size / BDRV_SECTOR_SIZE; bool is_write = mrb->is_write; if (num_reqs > 1) { int i; struct iovec *tmp_iov = qiov->iov; int tmp_niov = qiov->niov; /* mrb->reqs[start]->qiov was initialized from external so we can't * modifiy it here. We need to initialize it locally and then add the * external iovecs. */ qemu_iovec_init(qiov, niov); for (i = 0; i < tmp_niov; i++) { qemu_iovec_add(qiov, tmp_iov[i].iov_base, tmp_iov[i].iov_len); } for (i = start + 1; i < start + num_reqs; i++) { qemu_iovec_concat(qiov, &mrb->reqs[i]->qiov, 0, mrb->reqs[i]->qiov.size); mrb->reqs[i - 1]->mr_next = mrb->reqs[i]; nb_sectors += mrb->reqs[i]->qiov.size / BDRV_SECTOR_SIZE; } assert(nb_sectors == qiov->size / BDRV_SECTOR_SIZE); trace_virtio_blk_submit_multireq(mrb, start, num_reqs, sector_num, nb_sectors, is_write); block_acct_merge_done(blk_get_stats(blk), is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ, num_reqs - 1); } if (is_write) { blk_aio_writev(blk, sector_num, qiov, nb_sectors, virtio_blk_rw_complete, mrb->reqs[start]); } else { blk_aio_readv(blk, sector_num, qiov, nb_sectors, virtio_blk_rw_complete, mrb->reqs[start]); } }
static inline void flash_sync_area(Flash *s, int64_t off, int64_t len) { int64_t start, end, nb_sectors; QEMUIOVector iov; if (!s->blk || blk_is_read_only(s->blk)) { return; } assert(!(len % BDRV_SECTOR_SIZE)); start = off / BDRV_SECTOR_SIZE; end = (off + len) / BDRV_SECTOR_SIZE; nb_sectors = end - start; qemu_iovec_init(&iov, 1); qemu_iovec_add(&iov, s->storage + (start * BDRV_SECTOR_SIZE), nb_sectors * BDRV_SECTOR_SIZE); blk_aio_writev(s->blk, start, &iov, nb_sectors, blk_sync_complete, NULL); }