Commit a946592212874f1e214e0db365c29e8de1179847

Authored by bellard
1 parent 1aacf348

handle read outside the backing file


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2093 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 33 additions and 9 deletions
block-qcow2.c
... ... @@ -696,11 +696,26 @@ static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
696 696 return 0;
697 697 }
698 698  
  699 +/* handle reading after the end of the backing file */
  700 +static int backing_read1(BlockDriverState *bs,
  701 + int64_t sector_num, uint8_t *buf, int nb_sectors)
  702 +{
  703 + int n1;
  704 + if ((sector_num + nb_sectors) <= bs->total_sectors)
  705 + return nb_sectors;
  706 + if (sector_num >= bs->total_sectors)
  707 + n1 = 0;
  708 + else
  709 + n1 = bs->total_sectors - sector_num;
  710 + memset(buf + n1 * 512, 0, 512 * (nb_sectors - n1));
  711 + return n1;
  712 +}
  713 +
699 714 static int qcow_read(BlockDriverState *bs, int64_t sector_num,
700 715 uint8_t *buf, int nb_sectors)
701 716 {
702 717 BDRVQcowState *s = bs->opaque;
703   - int ret, index_in_cluster, n;
  718 + int ret, index_in_cluster, n, n1;
704 719 uint64_t cluster_offset;
705 720  
706 721 while (nb_sectors > 0) {
... ... @@ -712,9 +727,12 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
712 727 if (!cluster_offset) {
713 728 if (bs->backing_hd) {
714 729 /* read from the base image */
715   - ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
716   - if (ret < 0)
717   - return -1;
  730 + n1 = backing_read1(bs->backing_hd, sector_num, buf, n);
  731 + if (n1 > 0) {
  732 + ret = bdrv_read(bs->backing_hd, sector_num, buf, n1);
  733 + if (ret < 0)
  734 + return -1;
  735 + }
718 736 } else {
719 737 memset(buf, 0, 512 * n);
720 738 }
... ... @@ -815,7 +833,7 @@ static void qcow_aio_read_cb(void *opaque, int ret)
815 833 BlockDriverState *bs = acb->bs;
816 834 BDRVQcowState *s = bs->opaque;
817 835 QCowAIOCB *acb1 = acb->opaque;
818   - int index_in_cluster;
  836 + int index_in_cluster, n1;
819 837  
820 838 if (ret < 0) {
821 839 fail:
... ... @@ -859,10 +877,16 @@ static void qcow_aio_read_cb(void *opaque, int ret)
859 877 if (!acb1->cluster_offset) {
860 878 if (bs->backing_hd) {
861 879 /* read from the base image */
862   - ret = bdrv_aio_read(acb1->backing_hd_aiocb, acb1->sector_num,
863   - acb1->buf, acb1->n, qcow_aio_read_cb, acb);
864   - if (ret < 0)
865   - goto fail;
  880 + n1 = backing_read1(bs->backing_hd, acb1->sector_num,
  881 + acb1->buf, acb1->n);
  882 + if (n1 > 0) {
  883 + ret = bdrv_aio_read(acb1->backing_hd_aiocb, acb1->sector_num,
  884 + acb1->buf, n1, qcow_aio_read_cb, acb);
  885 + if (ret < 0)
  886 + goto fail;
  887 + } else {
  888 + goto redo;
  889 + }
866 890 } else {
867 891 /* Note: in this case, no need to wait */
868 892 memset(acb1->buf, 0, 512 * acb1->n);
... ...