On 25.04.2017 03:50, 858585 jemmy wrote: > On Mon, Apr 24, 2017 at 10:43 PM, Eric Blake <ebl...@redhat.com> wrote: >> On 04/23/2017 09:33 AM, jemmy858...@gmail.com wrote: >>> From: Lidong Chen <lidongc...@tencent.com> >>> >>> is_allocated_sectors_min don't guarantee to contain the >>> consecutive number of zero bytes. this patch fixes this bug. >> >> This message was sent without an 'In-Reply-To' header pointing to a 0/2 >> cover letter. When sending a series, please always thread things to a >> cover letter; you may find 'git config format.coverletter auto' to be >> helpful. > > Thanks for your kind advises. > >> >>> >>> Signed-off-by: Lidong Chen <lidongc...@tencent.com> >>> --- >>> qemu-img.c | 11 ++++++----- >>> 1 file changed, 6 insertions(+), 5 deletions(-) >>> >>> diff --git a/qemu-img.c b/qemu-img.c >>> index b220cf7..df6d165 100644 >>> --- a/qemu-img.c >>> +++ b/qemu-img.c >>> @@ -1060,9 +1060,9 @@ 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. >>> + * Like is_allocated_sectors, but 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) >>> @@ -1071,11 +1071,12 @@ static int is_allocated_sectors_min(const uint8_t >>> *buf, int n, int *pnum, >>> int num_checked, num_used; >>> >>> if (n < min) { >>> - min = n; >>> + *pnum = n; >>> + return 1; >>> } >>> >>> ret = is_allocated_sectors(buf, n, pnum); >>> - if (!ret) { >>> + if (!ret && *pnum >= min) { >> >> I seem to recall past attempts to try and patch this function, which >> were then turned down, although I haven't scrubbed the archives for a >> quick URL to point to. I'm worried that there are more subtleties here >> than what you realize. > > Hi Eric: > Do you mean this URL? > https://lists.gnu.org/archive/html/qemu-block/2017-01/msg00306.html > > But I think the code is not consistent with qemu-img --help. > qemu-img --help > '-S' indicates the consecutive number of bytes (defaults to 4k) that must > contain only zeros for qemu-img to create a sparse image during > conversion. If the number of bytes is 0, the source will not be > scanned for > unallocated or zero sectors, and the destination image will always be > fully allocated. > > another reason: > if s->has_zero_init is 1(the qcow2 image which have backing_file), the empty > space at the beginning of the buffer still need write and invoke > blk_co_pwrite_zeroes.
Right, that is indeed a reason that we may want to behave differently in these cases. But in other cases this is less efficient. > and split a single write operation into two just because there is small empty > space at the beginning. And then there's the fact that, in my opinion, this is actually a problem at qcow2 level. Some people are working on improving this (see e.g. Berto's subcluster RFC, which would allow us to implement bdrv_co_pwrite_zeroes() below cluster granularity). All in all, I don't think you can generically circumvent this issue here for all block drivers. The rule we'd have to implement here is: If some part of a cluster (to be written) is zero and another is not, we should write the whole cluster. If a whole cluster is zero, we should issue a write-zeroes request. But that would mean to check where some buffer passes a cluster boundary and so on, and on top of this all of it is qcow2-specific; so there goes the genericity... Max
signature.asc
Description: OpenPGP digital signature