Am 10.01.2014 19:24, schrieb Paolo Bonzini: > Il 10/01/2014 19:07, Peter Lieven ha scritto: >> >> >> Von meinem iPad gesendet >> >> Am 10.01.2014 um 19:05 schrieb "Paolo Bonzini" <pbonz...@redhat.com>: >> >>> Il 10/01/2014 18:16, ronnie sahlberg ha scritto: >>>> There is a common exception though, for the case where you read past >>>> the end of file. >>>> So short reads should normally not happen. Unless QEMU or the guest >>>> sends a request to libnfs to read past the end of the file. >>> Yes, this can happen in QEMU and the various drivers are careful to pad >>> with zeroes. It could perhaps be moved to block.c, but for now each >>> driver handles it separately. >> ok i will add this as well. however, i thought i had seen code for this in >> block.c already?, > No, it corresponds to this code in block/raw-posix.c: > > static int aio_worker(void *arg) > { > RawPosixAIOData *aiocb = arg; > ssize_t ret = 0; > > switch (aiocb->aio_type & QEMU_AIO_TYPE_MASK) { > case QEMU_AIO_READ: > ret = handle_aiocb_rw(aiocb); > if (ret >= 0 && ret < aiocb->aio_nbytes && aiocb->bs->growable) { > iov_memset(aiocb->aio_iov, aiocb->aio_niov, ret, > 0, aiocb->aio_nbytes - ret); > > ret = aiocb->aio_nbytes; > } > if (ret == aiocb->aio_nbytes) { > ret = 0; > } else if (ret >= 0 && ret < aiocb->aio_nbytes) { > ret = -EINVAL; > } > break;
I am a little confused... but it seems what I had in mind just fills up full sectors....?! if (!(bs->zero_beyond_eof && bs->growable)) { ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov); } else { /* Read zeros after EOF of growable BDSes */ int64_t len, total_sectors, max_nb_sectors; len = bdrv_getlength(bs); if (len < 0) { ret = len; goto out; } total_sectors = DIV_ROUND_UP(len, BDRV_SECTOR_SIZE); max_nb_sectors = MAX(0, total_sectors - sector_num); if (max_nb_sectors > 0) { ret = drv->bdrv_co_readv(bs, sector_num, MIN(nb_sectors, max_nb_sectors), qiov); } else { ret = 0; } /* Reading beyond end of file is supposed to produce zeroes */ if (ret == 0 && total_sectors < sector_num + nb_sectors) { uint64_t offset = MAX(0, total_sectors - sector_num); uint64_t bytes = (sector_num + nb_sectors - offset) * BDRV_SECTOR_SIZE; qemu_iovec_memset(qiov, offset * BDRV_SECTOR_SIZE, 0, bytes); } } Peter > > Paolo