qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] qemu-img: Require larger zero areas for sparse


From: Stefan Hajnoczi
Subject: Re: [Qemu-devel] [PATCH] qemu-img: Require larger zero areas for sparse handling
Date: Mon, 29 Aug 2011 13:00:22 +0100

On Fri, Aug 26, 2011 at 5:04 PM, Kevin Wolf <address@hidden> wrote:
> @@ -571,6 +573,48 @@ static int is_allocated_sectors(const uint8_t *buf, int 
> n, int *pnum)
>  }
>
>  /*
> + * Like is_allocated_sectors, but if the buffer starts with a used sector,
> + * up to 'min' consecutive sectors containing zeros are ignored. This avoids
> + * breaking up write requests for only small sparse areas.
> + */
> +static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
> +    int min)
> +{
> +    int ret;
> +    int num_checked, num_used;
> +
> +    if (n < min) {
> +        min = n;
> +    }
> +
> +    ret = is_allocated_sectors(buf, n, pnum);
> +    if (!ret) {
> +        return ret;
> +    }
> +
> +    num_used = *pnum;
> +    buf += 512 * *pnum;

BDRV_SECTOR_SIZE

> +    n -= *pnum;
> +    num_checked = num_used;
> +
> +    while (n > 0) {
> +        ret = is_allocated_sectors(buf, n, pnum);
> +
> +        buf += 512 * *pnum;
> +        n -= *pnum;
> +        num_checked += *pnum;
> +        if (ret) {
> +            num_used = num_checked;
> +        } else if (*pnum >= min) {
> +            break;
> +        }
> +    }
> +
> +    *pnum = num_used;
> +    return 1;
> +}
> +
> +/*
>  * Compares two buffers sector by sector. Returns 0 if the first sector of 
> both
>  * buffers matches, non-zero otherwise.
>  *
> @@ -620,6 +664,7 @@ static int img_convert(int argc, char **argv)
>     char *options = NULL;
>     const char *snapshot_name = NULL;
>     float local_progress;
> +    int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
>
>     fmt = NULL;
>     out_fmt = "raw";
> @@ -627,7 +672,7 @@ static int img_convert(int argc, char **argv)
>     out_baseimg = NULL;
>     compress = 0;
>     for(;;) {
> -        c = getopt(argc, argv, "f:O:B:s:hce6o:pt:");
> +        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");
>         if (c == -1) {
>             break;
>         }
> @@ -662,6 +707,18 @@ static int img_convert(int argc, char **argv)
>         case 's':
>             snapshot_name = optarg;
>             break;
> +        case 'S':
> +        {
> +            int64_t sval;
> +            sval = strtosz_suffix(optarg, NULL, STRTOSZ_DEFSUFFIX_B);
> +            if (sval < 0) {
> +                error_report("Invalid minimum zero buffer size for sparse 
> output specified");
> +                return 1;
> +            }
> +
> +            min_sparse = sval / BDRV_SECTOR_SIZE;
> +            break;
> +        }
>         case 'p':
>             progress = 1;
>             break;
> @@ -970,7 +1027,7 @@ static int img_convert(int argc, char **argv)
>                    sectors that are entirely 0, since whatever data was
>                    already there is garbage, not 0s. */
>                 if (!has_zero_init || out_baseimg ||
> -                    is_allocated_sectors(buf1, n, &n1)) {
> +                    is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
>                     ret = bdrv_write(out_bs, sector_num, buf1, n1);
>                     if (ret < 0) {
>                         error_report("error while writing sector %" PRId64
> diff --git a/qemu-img.texi b/qemu-img.texi
> index 495a1b6..a0579e7 100644
> --- a/qemu-img.texi
> +++ b/qemu-img.texi
> @@ -40,6 +40,9 @@ indicates that target image must be compressed (qcow format 
> only)
>  with or without a command shows help and lists the supported formats
> address@hidden -p
>  display progress bar (convert and rebase commands only)
> address@hidden -S @var{size}
> +indicates the consecutive number of bytes that must contain only zeros
> +for qemu-img to create a sparse image during conversion

For completeness (and to encourage people to use 1024 multiples
instead of 1000):
"This value is rounded down to the nearest 512 bytes."

> address@hidden table
>
>  Parameters to snapshot subcommand:
> @@ -86,7 +89,7 @@ it doesn't need to be specified separately in this case.
>
>  Commit the changes recorded in @var{filename} in its base image.
>
> address@hidden convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o 
> @var{options}] [-s @var{snapshot_name}] @var{filename} address@hidden [...]] 
> @var{output_filename}
> address@hidden convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o 
> @var{options}] [-s @var{snapshot_name}] [-S @var{sprase_size}] @var{filename} 
> address@hidden [...]] @var{output_filename}

s/sprase_size/sparse_size/

Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]