qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC 4/6] block: request overlap detection


From: Zhi Yong Wu
Subject: Re: [Qemu-devel] [RFC 4/6] block: request overlap detection
Date: Mon, 7 Nov 2011 19:49:13 +0800

On Mon, Oct 17, 2011 at 11:47 PM, Stefan Hajnoczi
<address@hidden> wrote:
> Detect overlapping requests and remember to align to cluster boundaries
> if the image format uses them.  This assumes that allocating I/O is
> performed in cluster granularity - which is true for qcow2, qed, etc.
>
> Signed-off-by: Stefan Hajnoczi <address@hidden>
> ---
>  block.c |   39 +++++++++++++++++++++++++++++++++++++--
>  1 files changed, 37 insertions(+), 2 deletions(-)
>
> diff --git a/block.c b/block.c
> index cc3202c..0c22741 100644
> --- a/block.c
> +++ b/block.c
> @@ -1052,21 +1052,56 @@ static BdrvTrackedRequest 
> *tracked_request_add(BlockDriverState *bs,
>     return req;
>  }
>
> +/**
> + * Round a region to cluster boundaries
> + */
> +static void round_to_clusters(BlockDriverState *bs,
> +                              int64_t sector_num, int nb_sectors,
> +                              int64_t *cluster_sector_num,
> +                              int *cluster_nb_sectors)
> +{
> +    BlockDriverInfo bdi;
> +
> +    if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
> +        *cluster_sector_num = sector_num;
> +        *cluster_nb_sectors = nb_sectors;
> +    } else {
> +        int64_t c = bdi.cluster_size / BDRV_SECTOR_SIZE;
> +        *cluster_sector_num = (sector_num / c) * c;
             I can understand the above formula, but the one below is
very magic. :) and can not be understood by me.
> +        *cluster_nb_sectors = ((sector_num % c) + nb_sectors + c - 1) / c * 
> c;

> +    }
> +}
> +
>  static bool tracked_request_overlaps(BdrvTrackedRequest *req,
>                                      int64_t sector_num, int nb_sectors) {
> -    return false; /* not yet implemented */
> +    /*        aaaa   bbbb */
> +    if (sector_num >= req->sector_num + req->nb_sectors) {
> +        return false;
> +    }
> +    /* bbbb   aaaa        */
> +    if (req->sector_num >= sector_num + nb_sectors) {
> +        return false;
> +    }
> +    return true;
>  }
>
>  static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs,
>         int64_t sector_num, int nb_sectors)
>  {
>     BdrvTrackedRequest *req;
> +    int64_t cluster_sector_num;
> +    int cluster_nb_sectors;
>     bool retry;
>
> +    /* If we touch the same cluster it counts as an overlap */
> +    round_to_clusters(bs, sector_num, nb_sectors,
> +                      &cluster_sector_num, &cluster_nb_sectors);
> +
>     do {
>         retry = false;
>         QLIST_FOREACH(req, &bs->tracked_requests, list) {
> -            if (tracked_request_overlaps(req, sector_num, nb_sectors)) {
> +            if (tracked_request_overlaps(req, cluster_sector_num,
> +                                         cluster_nb_sectors)) {
>                 qemu_co_queue_wait(&req->wait_queue);
>                 retry = true;
>                 break;
> --
> 1.7.6.3
>
>
>



-- 
Regards,

Zhi Yong Wu



reply via email to

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