Re: [Qemu-devel] [Patch v8 2/3] quorum: implement bdrv_add_child() and bdrv_del_child()
On 11/27/2015 02:06 PM, Wen Congyang wrote: Signed-off-by: Wen CongyangSigned-off-by: zhanghailiang Signed-off-by: Gonglei --- block.c | 8 ++-- block/quorum.c| 124 +- include/block/block.h | 4 ++ 3 files changed, 130 insertions(+), 6 deletions(-) diff --git a/block.c b/block.c index 255a36e..bfc2be8 100644 --- a/block.c +++ b/block.c @@ -1196,10 +1196,10 @@ static int bdrv_fill_options(QDict **options, const char *filename, return 0; } -static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, -BlockDriverState *child_bs, -const char *child_name, -const BdrvChildRole *child_role) +BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, + BlockDriverState *child_bs, + const char *child_name, + const BdrvChildRole *child_role) { BdrvChild *child = g_new(BdrvChild, 1); *child = (BdrvChild) { diff --git a/block/quorum.c b/block/quorum.c index 2810e37..b7df14b 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -23,6 +23,7 @@ #include "qapi/qmp/qstring.h" #include "qapi-event.h" #include "crypto/hash.h" +#include "qemu/bitmap.h" #define HASH_LENGTH 32 @@ -80,6 +81,8 @@ typedef struct BDRVQuorumState { bool rewrite_corrupted;/* true if the driver must rewrite-on-read corrupted * block if Quorum is reached. */ +unsigned long *index_bitmap; +int bsize; QuorumReadPattern read_pattern; } BDRVQuorumState; @@ -875,9 +878,9 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, ret = -EINVAL; goto exit; } -if (s->num_children < 2) { +if (s->num_children < 1) { error_setg(_err, - "Number of provided children must be greater than 1"); + "Number of provided children must be 1 or more"); ret = -EINVAL; goto exit; } @@ -926,6 +929,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, /* allocate the children array */ s->children = g_new0(BdrvChild *, s->num_children); opened = g_new0(bool, s->num_children); +s->index_bitmap = bitmap_new(s->num_children); for (i = 0; i < s->num_children; i++) { char indexstr[32]; @@ -941,6 +945,8 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, opened[i] = true; } +bitmap_set(s->index_bitmap, 0, s->num_children); +s->bsize = s->num_children; g_free(opened); goto exit; @@ -997,6 +1003,117 @@ static void quorum_attach_aio_context(BlockDriverState *bs, } } +static int get_new_child_index(BDRVQuorumState *s) +{ +int index; + +index = find_next_zero_bit(s->index_bitmap, s->bsize, 0); +if (index < s->bsize) { +return index; +} + +if ((s->bsize % BITS_PER_LONG) == 0) { +s->index_bitmap = bitmap_zero_extend(s->index_bitmap, s->bsize, + s->bsize + 1); +} + +return s->bsize++; +} + +static void remove_child_index(BDRVQuorumState *s, int index) +{ +int last_index; +long new_len; + +assert(index < s->bsize); + +clear_bit(index, s->index_bitmap); +if (index < s->bsize - 1) { +/* + * The last bit is always set, and we don't clear + * the last bit. + */ +return; +} + +last_index = find_last_bit(s->index_bitmap, s->bsize); +if (BITS_TO_LONGS(last_index + 1) == BITS_TO_LONGS(s->bsize)) { +s->bsize = last_index + 1; +return; +} + +new_len = BITS_TO_LONGS(last_index + 1) * sizeof(unsigned long); +s->index_bitmap = g_realloc(s->index_bitmap, new_len); +s->bsize = last_index + 1; +} + +static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs, + Error **errp) +{ +BDRVQuorumState *s = bs->opaque; +BdrvChild *child; +char indexstr[32]; +int index = find_next_zero_bit(s->index_bitmap, s->bsize, 0); +int ret; + +index = get_new_child_index(s); double assignment of 'index', remove the first one pls Thanks Li +ret = snprintf(indexstr, 32, "children.%d", index); +if (ret < 0 || ret >= 32) { +error_setg(errp, "cannot generate child name"); +return; +} + +bdrv_drain(bs); + +assert(s->num_children <= INT_MAX / sizeof(BdrvChild *)); +if (s->num_children == INT_MAX / sizeof(BdrvChild *)) { +error_setg(errp, "Too many children"); +return; +} +s->children = g_renew(BdrvChild *, s->children, s->num_children + 1); + +bdrv_ref(child_bs); +child =
[Qemu-devel] [Patch v8 2/3] quorum: implement bdrv_add_child() and bdrv_del_child()
Signed-off-by: Wen CongyangSigned-off-by: zhanghailiang Signed-off-by: Gonglei --- block.c | 8 ++-- block/quorum.c| 124 +- include/block/block.h | 4 ++ 3 files changed, 130 insertions(+), 6 deletions(-) diff --git a/block.c b/block.c index 255a36e..bfc2be8 100644 --- a/block.c +++ b/block.c @@ -1196,10 +1196,10 @@ static int bdrv_fill_options(QDict **options, const char *filename, return 0; } -static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, -BlockDriverState *child_bs, -const char *child_name, -const BdrvChildRole *child_role) +BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, + BlockDriverState *child_bs, + const char *child_name, + const BdrvChildRole *child_role) { BdrvChild *child = g_new(BdrvChild, 1); *child = (BdrvChild) { diff --git a/block/quorum.c b/block/quorum.c index 2810e37..b7df14b 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -23,6 +23,7 @@ #include "qapi/qmp/qstring.h" #include "qapi-event.h" #include "crypto/hash.h" +#include "qemu/bitmap.h" #define HASH_LENGTH 32 @@ -80,6 +81,8 @@ typedef struct BDRVQuorumState { bool rewrite_corrupted;/* true if the driver must rewrite-on-read corrupted * block if Quorum is reached. */ +unsigned long *index_bitmap; +int bsize; QuorumReadPattern read_pattern; } BDRVQuorumState; @@ -875,9 +878,9 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, ret = -EINVAL; goto exit; } -if (s->num_children < 2) { +if (s->num_children < 1) { error_setg(_err, - "Number of provided children must be greater than 1"); + "Number of provided children must be 1 or more"); ret = -EINVAL; goto exit; } @@ -926,6 +929,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, /* allocate the children array */ s->children = g_new0(BdrvChild *, s->num_children); opened = g_new0(bool, s->num_children); +s->index_bitmap = bitmap_new(s->num_children); for (i = 0; i < s->num_children; i++) { char indexstr[32]; @@ -941,6 +945,8 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, opened[i] = true; } +bitmap_set(s->index_bitmap, 0, s->num_children); +s->bsize = s->num_children; g_free(opened); goto exit; @@ -997,6 +1003,117 @@ static void quorum_attach_aio_context(BlockDriverState *bs, } } +static int get_new_child_index(BDRVQuorumState *s) +{ +int index; + +index = find_next_zero_bit(s->index_bitmap, s->bsize, 0); +if (index < s->bsize) { +return index; +} + +if ((s->bsize % BITS_PER_LONG) == 0) { +s->index_bitmap = bitmap_zero_extend(s->index_bitmap, s->bsize, + s->bsize + 1); +} + +return s->bsize++; +} + +static void remove_child_index(BDRVQuorumState *s, int index) +{ +int last_index; +long new_len; + +assert(index < s->bsize); + +clear_bit(index, s->index_bitmap); +if (index < s->bsize - 1) { +/* + * The last bit is always set, and we don't clear + * the last bit. + */ +return; +} + +last_index = find_last_bit(s->index_bitmap, s->bsize); +if (BITS_TO_LONGS(last_index + 1) == BITS_TO_LONGS(s->bsize)) { +s->bsize = last_index + 1; +return; +} + +new_len = BITS_TO_LONGS(last_index + 1) * sizeof(unsigned long); +s->index_bitmap = g_realloc(s->index_bitmap, new_len); +s->bsize = last_index + 1; +} + +static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs, + Error **errp) +{ +BDRVQuorumState *s = bs->opaque; +BdrvChild *child; +char indexstr[32]; +int index = find_next_zero_bit(s->index_bitmap, s->bsize, 0); +int ret; + +index = get_new_child_index(s); +ret = snprintf(indexstr, 32, "children.%d", index); +if (ret < 0 || ret >= 32) { +error_setg(errp, "cannot generate child name"); +return; +} + +bdrv_drain(bs); + +assert(s->num_children <= INT_MAX / sizeof(BdrvChild *)); +if (s->num_children == INT_MAX / sizeof(BdrvChild *)) { +error_setg(errp, "Too many children"); +return; +} +s->children = g_renew(BdrvChild *, s->children, s->num_children + 1); + +bdrv_ref(child_bs); +child = bdrv_attach_child(bs, child_bs, indexstr, _format); +s->children[s->num_children++] = child; +set_bit(index, s->index_bitmap); +} + +static void