Re: [Qemu-devel] [RFC PATCH 12/14] Add disk buffer for block replication

2015-02-23 Thread Max Reitz

On 2015-02-11 at 22:07, Wen Congyang wrote:

Signed-off-by: Wen Congyang we...@cn.fujitsu.com
Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com
Signed-off-by: Gonglei arei.gong...@huawei.com
---
  block/Makefile.objs|   1 +
  block/blkcolo-buffer.c | 324 +
  block/blkcolo.h|  35 ++
  3 files changed, 360 insertions(+)
  create mode 100644 block/blkcolo-buffer.c
  create mode 100644 block/blkcolo.h


In general: Can you please add some prefix to the non-static functions, 
like colo_*?


As for the design questions regarding this block driver, I should 
probably leave that to Fam and John (because they seemed to have an idea 
how to approach the issue at hand using a different implementation, 
based on functionality that's already (or close to become) part of qemu).


Therefore, I'm hesitating to review this patch (and the following ones) 
until you've reached a conclusion on how to proceed.


Max



[Qemu-devel] [RFC PATCH 12/14] Add disk buffer for block replication

2015-02-11 Thread Wen Congyang
Signed-off-by: Wen Congyang we...@cn.fujitsu.com
Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com
Signed-off-by: Gonglei arei.gong...@huawei.com
---
 block/Makefile.objs|   1 +
 block/blkcolo-buffer.c | 324 +
 block/blkcolo.h|  35 ++
 3 files changed, 360 insertions(+)
 create mode 100644 block/blkcolo-buffer.c
 create mode 100644 block/blkcolo.h

diff --git a/block/Makefile.objs b/block/Makefile.objs
index db2933e..1b7b458 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -21,6 +21,7 @@ block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
 block-obj-$(CONFIG_LIBSSH2) += ssh.o
 block-obj-y += accounting.o
 block-obj-y += write-threshold.o
+block-obj-y += blkcolo-buffer.o
 
 common-obj-y += stream.o
 common-obj-y += commit.o
diff --git a/block/blkcolo-buffer.c b/block/blkcolo-buffer.c
new file mode 100644
index 000..1f64542
--- /dev/null
+++ b/block/blkcolo-buffer.c
@@ -0,0 +1,324 @@
+/*
+ * Block driver for COLO
+ *
+ * Copyright Fujitsu, Corp. 2015
+ * Copyright (c) 2015 Intel Corporation
+ * Copyright (c) 2015 HUAWEI TECHNOLOGIES CO.,LTD.
+ *
+ * Authors:
+ * Wen Congyang we...@cn.fujitsu.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include qemu-common.h
+#include qemu/queue.h
+#include block/block.h
+#include block/blkcolo.h
+
+typedef struct buffered_request_state {
+uint64_t start_sector;
+int nb_sectors;
+void *data;
+QSIMPLEQ_ENTRY(buffered_request_state) entry;
+} buffered_request_state;
+
+/* common functions */
+/*
+ * The buffered data may eat too much memory, and glibc cannot work
+ * very well in such case.
+ */
+static void *alloc_buffered_data(int nb_sectors)
+{
+return g_malloc(nb_sectors * BDRV_SECTOR_SIZE);
+}
+
+static void free_buffered_data(void *data)
+{
+g_free(data);
+}
+
+typedef struct search_brs_state {
+uint64_t sector;
+buffered_request_state *prev;
+} search_brs_state;
+
+static buffered_request_state *search_brs(disk_buffer *disk_buffer,
+   search_brs_state *sbs)
+{
+buffered_request_state *brs;
+
+QSIMPLEQ_FOREACH(brs, disk_buffer-head, entry) {
+if (sbs-sector  brs-start_sector) {
+return NULL;
+}
+
+if (sbs-sector  brs-start_sector + brs-nb_sectors) {
+return brs;
+}
+
+sbs-prev = brs;
+}
+
+return NULL;
+}
+
+static buffered_request_state *get_next_brs(buffered_request_state *brs)
+{
+return QSIMPLEQ_NEXT(brs, entry);
+}
+
+static void add_brs_after(disk_buffer *disk_buffer,
+  buffered_request_state *new_brs,
+  buffered_request_state *prev)
+{
+if (!prev) {
+QSIMPLEQ_INSERT_HEAD(disk_buffer-head, new_brs, entry);
+} else {
+QSIMPLEQ_INSERT_AFTER(disk_buffer-head, prev, new_brs, entry);
+}
+}
+
+static bool disk_buffer_empty(disk_buffer *disk_buffer)
+{
+return QSIMPLEQ_EMPTY(disk_buffer-head);
+}
+
+/* Disk buffer */
+static buffered_request_state *create_new_brs(QEMUIOVector *qiov,
+  uint64_t iov_sector,
+  uint64_t sector, int nb_sectors)
+{
+buffered_request_state *brs;
+
+brs = g_slice_new(buffered_request_state);
+brs-start_sector = sector;
+brs-nb_sectors = nb_sectors;
+brs-data = alloc_buffered_data(nb_sectors);
+qemu_iovec_to_buf(qiov, (sector - iov_sector) * BDRV_SECTOR_SIZE,
+  brs-data, nb_sectors * BDRV_SECTOR_SIZE);
+
+return brs;
+}
+
+static void free_brs(buffered_request_state *brs)
+{
+free_buffered_data(brs-data);
+g_slice_free(buffered_request_state, brs);
+}
+
+bool buffer_has_empty_range(disk_buffer *disk_buffer,
+uint64_t sector, int nb_sectors)
+{
+buffered_request_state *brs;
+search_brs_state sbs;
+uint64_t cur_sector = sector;
+
+if (nb_sectors = 0) {
+return false;
+}
+
+sbs.sector = sector;
+sbs.prev = NULL;
+brs = search_brs(disk_buffer, sbs);
+if (!brs) {
+return true;
+}
+
+while (brs  cur_sector  sector + nb_sectors) {
+if (cur_sector  brs-start_sector) {
+return true;
+}
+
+if (brs-start_sector + brs-nb_sectors = sector + nb_sectors) {
+return false;
+}
+
+cur_sector = brs-start_sector + brs-nb_sectors;
+brs = get_next_brs(brs);
+}
+
+if (cur_sector  sector + nb_sectors) {
+return true;
+} else {
+return false;
+}
+}
+
+/* Note: only the sector that exists in the buffer will be overwriten */
+void qiov_read_from_buffer(disk_buffer *disk_buffer, QEMUIOVector *qiov,
+   uint64_t sector, int nb_sectors)
+{
+search_brs_state sbs;
+