Message ID | 1554483379-682051-2-git-send-email-andrey.shinkevich@virtuozzo.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | block/stream: get rid of the base | expand |
On Fri 05 Apr 2019 06:56:17 PM CEST, Andrey Shinkevich wrote: > +int bdrv_is_allocated_above(BlockDriverState *top, > + BlockDriverState *base, > + int64_t offset, int64_t bytes, int64_t *pnum) > +{ > + return bdrv_do_is_allocated_above(top, base, false, offset, bytes, pnum); > +} > + > +int bdrv_is_allocated_above_inclusive(BlockDriverState *top, > + BlockDriverState *base, > + int64_t offset, int64_t bytes, > + int64_t *pnum) > +{ > + return bdrv_do_is_allocated_above(top, base, true, offset, bytes, pnum); > +} Instead of having these two, isn't it simpler to add an 'include_base' parameter to the original function? Another alternative (I haven't checked this one so it could be more cumbersome): change the semantics of the function to always include the base and modify the callers. Berto
08.04.2019 18:03, Alberto Garcia wrote: > On Fri 05 Apr 2019 06:56:17 PM CEST, Andrey Shinkevich wrote: >> +int bdrv_is_allocated_above(BlockDriverState *top, >> + BlockDriverState *base, >> + int64_t offset, int64_t bytes, int64_t *pnum) >> +{ >> + return bdrv_do_is_allocated_above(top, base, false, offset, bytes, pnum); >> +} >> + >> +int bdrv_is_allocated_above_inclusive(BlockDriverState *top, >> + BlockDriverState *base, >> + int64_t offset, int64_t bytes, >> + int64_t *pnum) >> +{ >> + return bdrv_do_is_allocated_above(top, base, true, offset, bytes, pnum); >> +} > > Instead of having these two, isn't it simpler to add an 'include_base' > parameter to the original function? > > Another alternative (I haven't checked this one so it could be more > cumbersome): change the semantics of the function to always include the > base and modify the callers. > The idea was exactly to avoid modifying all callers.. And it seems good, at least as first step. We may want to modify other callers but it is out of stream series.
On 08/04/2019 18:03, Alberto Garcia wrote: > On Fri 05 Apr 2019 06:56:17 PM CEST, Andrey Shinkevich wrote: >> +int bdrv_is_allocated_above(BlockDriverState *top, >> + BlockDriverState *base, >> + int64_t offset, int64_t bytes, int64_t *pnum) >> +{ >> + return bdrv_do_is_allocated_above(top, base, false, offset, bytes, pnum); >> +} >> + >> +int bdrv_is_allocated_above_inclusive(BlockDriverState *top, >> + BlockDriverState *base, >> + int64_t offset, int64_t bytes, >> + int64_t *pnum) >> +{ >> + return bdrv_do_is_allocated_above(top, base, true, offset, bytes, pnum); >> +} > > Instead of having these two, isn't it simpler to add an 'include_base' > parameter to the original function? > > Another alternative (I haven't checked this one so it could be more > cumbersome): change the semantics of the function to always include the > base and modify the callers. > > Berto > The idea behind those two functions was to keep the rest of the code unmodified. Currently, we have the issue with the block-stream parallel jobs. What if we manage this case first and then, when proved to be robust, take care of the rest?
On Mon 08 Apr 2019 05:16:22 PM CEST, Andrey Shinkevich wrote: > On 08/04/2019 18:03, Alberto Garcia wrote: >> On Fri 05 Apr 2019 06:56:17 PM CEST, Andrey Shinkevich wrote: >>> +int bdrv_is_allocated_above(BlockDriverState *top, >>> + BlockDriverState *base, >>> + int64_t offset, int64_t bytes, int64_t *pnum) >>> +{ >>> + return bdrv_do_is_allocated_above(top, base, false, offset, bytes, pnum); >>> +} >>> + >>> +int bdrv_is_allocated_above_inclusive(BlockDriverState *top, >>> + BlockDriverState *base, >>> + int64_t offset, int64_t bytes, >>> + int64_t *pnum) >>> +{ >>> + return bdrv_do_is_allocated_above(top, base, true, offset, bytes, pnum); >>> +} >> >> Instead of having these two, isn't it simpler to add an 'include_base' >> parameter to the original function? >> >> Another alternative (I haven't checked this one so it could be more >> cumbersome): change the semantics of the function to always include the >> base and modify the callers. > > The idea behind those two functions was to keep the rest of the code > unmodified. Currently, we have the issue with the block-stream > parallel jobs. What if we manage this case first and then, when proved > to be robust, take care of the rest? Sure, that makes sense if you need to do significant changes to the other callers, but if you just need to pass an extra 'false' parameter... It's not a big deal, I just think you'd have a simpler patch. Berto
On 08/04/2019 18:22, Alberto Garcia wrote: > On Mon 08 Apr 2019 05:16:22 PM CEST, Andrey Shinkevich wrote: >> On 08/04/2019 18:03, Alberto Garcia wrote: >>> On Fri 05 Apr 2019 06:56:17 PM CEST, Andrey Shinkevich wrote: >>>> +int bdrv_is_allocated_above(BlockDriverState *top, >>>> + BlockDriverState *base, >>>> + int64_t offset, int64_t bytes, int64_t *pnum) >>>> +{ >>>> + return bdrv_do_is_allocated_above(top, base, false, offset, bytes, pnum); >>>> +} >>>> + >>>> +int bdrv_is_allocated_above_inclusive(BlockDriverState *top, >>>> + BlockDriverState *base, >>>> + int64_t offset, int64_t bytes, >>>> + int64_t *pnum) >>>> +{ >>>> + return bdrv_do_is_allocated_above(top, base, true, offset, bytes, pnum); >>>> +} >>> >>> Instead of having these two, isn't it simpler to add an 'include_base' >>> parameter to the original function? >>> >>> Another alternative (I haven't checked this one so it could be more >>> cumbersome): change the semantics of the function to always include the >>> base and modify the callers. >> >> The idea behind those two functions was to keep the rest of the code >> unmodified. Currently, we have the issue with the block-stream >> parallel jobs. What if we manage this case first and then, when proved >> to be robust, take care of the rest? > > Sure, that makes sense if you need to do significant changes to the > other callers, but if you just need to pass an extra 'false' > parameter... > > It's not a big deal, I just think you'd have a simpler patch. > > Berto > OK, I'll do that with the next v4.
diff --git a/block/io.c b/block/io.c index dfc153b..7e6019f 100644 --- a/block/io.c +++ b/block/io.c @@ -2317,7 +2317,8 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset, * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP] * * Return true if (a prefix of) the given range is allocated in any image - * between BASE and TOP (inclusive). BASE can be NULL to check if the given + * between BASE and TOP (TOP included). To check the BASE image, set the + * 'base_included' to 'true'. The BASE can be NULL to check if the given * offset is allocated in any image of the chain. Return false otherwise, * or negative errno on failure. * @@ -2329,16 +2330,19 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset, * but 'pnum' will only be 0 when end of file is reached. * */ -int bdrv_is_allocated_above(BlockDriverState *top, - BlockDriverState *base, - int64_t offset, int64_t bytes, int64_t *pnum) +static int bdrv_do_is_allocated_above(BlockDriverState *top, + BlockDriverState *base, + bool base_included, int64_t offset, + int64_t bytes, int64_t *pnum) { BlockDriverState *intermediate; int ret; int64_t n = bytes; + assert(base || !base_included); + intermediate = top; - while (intermediate && intermediate != base) { + while (base_included || intermediate != base) { int64_t pnum_inter; int64_t size_inter; @@ -2360,6 +2364,10 @@ int bdrv_is_allocated_above(BlockDriverState *top, n = pnum_inter; } + if (intermediate == base) { + break; + } + intermediate = backing_bs(intermediate); } @@ -2367,6 +2375,21 @@ int bdrv_is_allocated_above(BlockDriverState *top, return 0; } +int bdrv_is_allocated_above(BlockDriverState *top, + BlockDriverState *base, + int64_t offset, int64_t bytes, int64_t *pnum) +{ + return bdrv_do_is_allocated_above(top, base, false, offset, bytes, pnum); +} + +int bdrv_is_allocated_above_inclusive(BlockDriverState *top, + BlockDriverState *base, + int64_t offset, int64_t bytes, + int64_t *pnum) +{ + return bdrv_do_is_allocated_above(top, base, true, offset, bytes, pnum); +} + typedef struct BdrvVmstateCo { BlockDriverState *bs; QEMUIOVector *qiov; diff --git a/include/block/block.h b/include/block/block.h index c7a2619..be1e9a0 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -449,6 +449,10 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes, int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base, int64_t offset, int64_t bytes, int64_t *pnum); +int bdrv_is_allocated_above_inclusive(BlockDriverState *top, + BlockDriverState *base, + int64_t offset, int64_t bytes, + int64_t *pnum); bool bdrv_is_read_only(BlockDriverState *bs); int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, bool ignore_allow_rdw, Error **errp);