qemu-img: round down request length to an aligned sector
this patch shortens requests to end at an aligned sector so that the next request starts aligned. [Squashed Peter's fix for bdrv_get_info() failure discussed on the mailing list. --Stefan] Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Peter Lieven <pl@kamp.de> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
		
							parent
							
								
									f2521c9023
								
							
						
					
					
						commit
						24f833cd43
					
				
							
								
								
									
										28
									
								
								qemu-img.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								qemu-img.c
									
									
									
									
									
								
							@ -1129,8 +1129,7 @@ out3:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static int img_convert(int argc, char **argv)
 | 
					static int img_convert(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int c, n, n1, bs_n, bs_i, compress, cluster_size,
 | 
					    int c, n, n1, bs_n, bs_i, compress, cluster_sectors, skip_create;
 | 
				
			||||||
        cluster_sectors, skip_create;
 | 
					 | 
				
			||||||
    int64_t ret = 0;
 | 
					    int64_t ret = 0;
 | 
				
			||||||
    int progress = 0, flags;
 | 
					    int progress = 0, flags;
 | 
				
			||||||
    const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
 | 
					    const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;
 | 
				
			||||||
@ -1424,19 +1423,23 @@ static int img_convert(int argc, char **argv)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (compress) {
 | 
					    cluster_sectors = 0;
 | 
				
			||||||
    ret = bdrv_get_info(out_bs, &bdi);
 | 
					    ret = bdrv_get_info(out_bs, &bdi);
 | 
				
			||||||
    if (ret < 0) {
 | 
					    if (ret < 0) {
 | 
				
			||||||
 | 
					        if (compress) {
 | 
				
			||||||
            error_report("could not get block driver info");
 | 
					            error_report("could not get block driver info");
 | 
				
			||||||
            goto out;
 | 
					            goto out;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        cluster_size = bdi.cluster_size;
 | 
					    } else {
 | 
				
			||||||
        if (cluster_size <= 0 || cluster_size > bufsectors * BDRV_SECTOR_SIZE) {
 | 
					        cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (compress) {
 | 
				
			||||||
 | 
					        if (cluster_sectors <= 0 || cluster_sectors > bufsectors) {
 | 
				
			||||||
            error_report("invalid cluster size");
 | 
					            error_report("invalid cluster size");
 | 
				
			||||||
            ret = -1;
 | 
					            ret = -1;
 | 
				
			||||||
            goto out;
 | 
					            goto out;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        cluster_sectors = cluster_size >> 9;
 | 
					 | 
				
			||||||
        sector_num = 0;
 | 
					        sector_num = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        nb_sectors = total_sectors;
 | 
					        nb_sectors = total_sectors;
 | 
				
			||||||
@ -1569,6 +1572,19 @@ static int img_convert(int argc, char **argv)
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            n = MIN(nb_sectors, bufsectors);
 | 
					            n = MIN(nb_sectors, bufsectors);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* round down request length to an aligned sector, but
 | 
				
			||||||
 | 
					             * do not bother doing this on short requests. They happen
 | 
				
			||||||
 | 
					             * when we found an all-zero area, and the next sector to
 | 
				
			||||||
 | 
					             * write will not be sector_num + n. */
 | 
				
			||||||
 | 
					            if (cluster_sectors > 0 && n >= cluster_sectors) {
 | 
				
			||||||
 | 
					                int64_t next_aligned_sector = (sector_num + n);
 | 
				
			||||||
 | 
					                next_aligned_sector -= next_aligned_sector % cluster_sectors;
 | 
				
			||||||
 | 
					                if (sector_num + n > next_aligned_sector) {
 | 
				
			||||||
 | 
					                    n = next_aligned_sector - sector_num;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            n = MIN(n, bs_sectors - (sector_num - bs_offset));
 | 
					            n = MIN(n, bs_sectors - (sector_num - bs_offset));
 | 
				
			||||||
            n1 = n;
 | 
					            n1 = n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user