On Wed, Feb 06, 2013 at 01:31:58PM +0100, Benoît Canet wrote:
> This fix the sub cluster sized writes race conditions while waiting
> for a more faster solution.
>
> Signed-off-by: Benoit Canet <[email protected]>
> ---
> block/qcow2.c | 14 +++++++++++++-
> block/qcow2.h | 1 +
> 2 files changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/block/qcow2.c b/block/qcow2.c
> index f39b6d5..5cfffd2 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -524,6 +524,7 @@ static int qcow2_open(BlockDriverState *bs, int flags)
>
> /* Initialise locks */
> qemu_co_mutex_init(&s->lock);
> + qemu_co_mutex_init(&s->dedup_lock);
>
> /* Repair image if dirty */
> if (!(flags & BDRV_O_CHECK) && !bs->read_only &&
> @@ -815,8 +816,15 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState
> *bs,
> s->cluster_cache_offset = -1; /* disable compressed cache */
>
> qemu_co_mutex_lock(&s->lock);
> -
> atomic_dedup_is_running = qcow2_dedup_is_running(bs);
> + qemu_co_mutex_unlock(&s->lock);
No need to lock/unlock around qcow2_dedup_is_running(bs) because it
doesn't yield. No other coroutine can run while our thread of control
is active here.
> +
> + if (atomic_dedup_is_running) {
> + qemu_co_mutex_lock(&s->dedup_lock);
> + }
What exactly does dedup_lock protect? Please document it.
> +
> + qemu_co_mutex_lock(&s->lock);
> +
> if (atomic_dedup_is_running) {
> QTAILQ_INIT(&ds.undedupables);
> ds.phash.reuse = false;
> @@ -983,6 +991,10 @@ fail:
> g_free(l2meta);
> }
>
> + if (atomic_dedup_is_running) {
> + qemu_co_mutex_unlock(&s->dedup_lock);
> + }
> +
> qemu_iovec_destroy(&hd_qiov);
> qemu_vfree(cluster_data);
> qemu_vfree(dedup_cluster_data);
> diff --git a/block/qcow2.h b/block/qcow2.h
> index a13ec75..81dc0ea 100644
> --- a/block/qcow2.h
> +++ b/block/qcow2.h
> @@ -236,6 +236,7 @@ typedef struct BDRVQcowState {
> GTree *dedup_tree_by_sect;
>
> CoMutex lock;
> + CoMutex dedup_lock;
>
> uint32_t crypt_method; /* current crypt method, 0 if no key yet */
> uint32_t crypt_method_header;
> --
> 1.7.10.4
>