block: perform zero-detection during copy-on-read
Copy-on-Read populates the image file with data read from a backing image. In order to avoid bloating the image file when all zeroes are read we should scan the buffer and perform an optimized zero write operation. Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
		
							parent
							
								
									f08f2ddae0
								
							
						
					
					
						commit
						79c053bde9
					
				
							
								
								
									
										14
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								block.c
									
									
									
									
									
								
							@ -1517,6 +1517,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs,
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    void *bounce_buffer;
 | 
					    void *bounce_buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    BlockDriver *drv = bs->drv;
 | 
				
			||||||
    struct iovec iov;
 | 
					    struct iovec iov;
 | 
				
			||||||
    QEMUIOVector bounce_qiov;
 | 
					    QEMUIOVector bounce_qiov;
 | 
				
			||||||
    int64_t cluster_sector_num;
 | 
					    int64_t cluster_sector_num;
 | 
				
			||||||
@ -1537,14 +1538,21 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs,
 | 
				
			|||||||
    iov.iov_base = bounce_buffer = qemu_blockalign(bs, iov.iov_len);
 | 
					    iov.iov_base = bounce_buffer = qemu_blockalign(bs, iov.iov_len);
 | 
				
			||||||
    qemu_iovec_init_external(&bounce_qiov, &iov, 1);
 | 
					    qemu_iovec_init_external(&bounce_qiov, &iov, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = bs->drv->bdrv_co_readv(bs, cluster_sector_num, cluster_nb_sectors,
 | 
					    ret = drv->bdrv_co_readv(bs, cluster_sector_num, cluster_nb_sectors,
 | 
				
			||||||
                                 &bounce_qiov);
 | 
					                             &bounce_qiov);
 | 
				
			||||||
    if (ret < 0) {
 | 
					    if (ret < 0) {
 | 
				
			||||||
        goto err;
 | 
					        goto err;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = bs->drv->bdrv_co_writev(bs, cluster_sector_num, cluster_nb_sectors,
 | 
					    if (drv->bdrv_co_write_zeroes &&
 | 
				
			||||||
 | 
					        buffer_is_zero(bounce_buffer, iov.iov_len)) {
 | 
				
			||||||
 | 
					        ret = drv->bdrv_co_write_zeroes(bs, cluster_sector_num,
 | 
				
			||||||
 | 
					                                        cluster_nb_sectors);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        ret = drv->bdrv_co_writev(bs, cluster_sector_num, cluster_nb_sectors,
 | 
				
			||||||
                                  &bounce_qiov);
 | 
					                                  &bounce_qiov);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (ret < 0) {
 | 
					    if (ret < 0) {
 | 
				
			||||||
        /* It might be okay to ignore write errors for guest requests.  If this
 | 
					        /* It might be okay to ignore write errors for guest requests.  If this
 | 
				
			||||||
         * is a deliberate copy-on-read then we don't want to ignore the error.
 | 
					         * is a deliberate copy-on-read then we don't want to ignore the error.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user