<div dir="ltr"><font face="monospace, monospace">The patch add support L2 table cache for qcow2 disk. L2 table cache can improve IO read and write performance for <span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">qcow2 img</span>.</font><div><font face="monospace, monospace">Diff follows:<br></font></div><div><div><font face="monospace, monospace"> src/conf/domain_conf.c                               | 47 +++++++++++++++++++++++++++++++++++++++++++++++</font></div><div><font face="monospace, monospace"> src/conf/domain_conf.h                               |  5 +++++</font></div><div><font face="monospace, monospace"> src/qemu/qemu_command.c                              |  7 +++++++</font></div><div><font face="monospace, monospace"> src/qemu/qemu_domain.c                               |  6 ++++++</font></div><div><font face="monospace, monospace"> tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args |  2 +-</font></div><div><font face="monospace, monospace"> tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml  |  3 ++-</font></div><div><font face="monospace, monospace"> 6 files changed, 68 insertions(+), 2 deletions(-)</font></div></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><div><font face="monospace, monospace">diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c</font></div><div><font face="monospace, monospace">index beca0be..0a6afca 100644</font></div><div><font face="monospace, monospace">--- a/src/conf/domain_conf.c</font></div><div><font face="monospace, monospace">+++ b/src/conf/domain_conf.c</font></div><div><font face="monospace, monospace">@@ -8058,6 +8058,8 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,</font></div><div><font face="monospace, monospace">     char *domain_name = NULL;</font></div><div><font face="monospace, monospace">     int expected_secret_usage = -1;</font></div><div><font face="monospace, monospace">     int auth_secret_usage = -1;</font></div><div><font face="monospace, monospace">+    char *disk_l2_cache_size = NULL;</font></div><div><font face="monospace, monospace">+    char *disk_cache_clean_interval = NULL;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">     if (!(def = virDomainDiskDefNew(xmlopt)))</font></div><div><font face="monospace, monospace">         return NULL;</font></div><div><font face="monospace, monospace">@@ -8233,6 +8235,27 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,</font></div><div><font face="monospace, monospace">             }</font></div><div><font face="monospace, monospace">         } else if (xmlStrEqual(cur->name, BAD_CAST "boot")) {</font></div><div><font face="monospace, monospace">             /* boot is parsed as part of virDomainDeviceInfoParseXML */</font></div><div><font face="monospace, monospace">+        } else if (xmlStrEqual(cur->name, BAD_CAST "diskCache")) {</font></div><div><font face="monospace, monospace">+            disk_l2_cache_size =</font></div><div><font face="monospace, monospace">+                virXMLPropString(cur, "disk_l2_cache_size");</font></div><div><font face="monospace, monospace">+            if (disk_l2_cache_size &&</font></div><div><font face="monospace, monospace">+                virStrToLong_ui(disk_l2_cache_size, NULL, 0,</font></div><div><font face="monospace, monospace">+                                &def->disk_cache.disk_l2_cache_size) < 0) {</font></div><div><font face="monospace, monospace">+                virReportError(VIR_ERR_INTERNAL_ERROR,</font></div><div><font face="monospace, monospace">+                               _("invalid disk L2 cache size '%s'"),</font></div><div><font face="monospace, monospace">+                               disk_l2_cache_size);</font></div><div><font face="monospace, monospace">+                goto error;</font></div><div><font face="monospace, monospace">+            }</font></div><div><font face="monospace, monospace">+            disk_cache_clean_interval =</font></div><div><font face="monospace, monospace">+                virXMLPropString(cur, "disk_cache_clean_interval");</font></div><div><font face="monospace, monospace">+            if (disk_cache_clean_interval &&</font></div><div><font face="monospace, monospace">+                virStrToLong_ui(disk_cache_clean_interval, NULL, 0,</font></div><div><font face="monospace, monospace">+                                &def->disk_cache.disk_cache_clean_interval) < 0) {</font></div><div><font face="monospace, monospace">+                virReportError(VIR_ERR_INTERNAL_ERROR,</font></div><div><font face="monospace, monospace">+                               _("invalid disk cache clean interval '%s'"),</font></div><div><font face="monospace, monospace">+                               disk_cache_clean_interval);</font></div><div><font face="monospace, monospace">+                goto error;</font></div><div><font face="monospace, monospace">+            }</font></div><div><font face="monospace, monospace">         }</font></div><div><font face="monospace, monospace">     }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">@@ -8472,6 +8495,8 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,</font></div><div><font face="monospace, monospace">     VIR_FREE(vendor);</font></div><div><font face="monospace, monospace">     VIR_FREE(product);</font></div><div><font face="monospace, monospace">     VIR_FREE(domain_name);</font></div><div><font face="monospace, monospace">+    VIR_FREE(disk_l2_cache_size);</font></div><div><font face="monospace, monospace">+    VIR_FREE(disk_cache_clean_interval);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">     ctxt->node = save_ctxt;</font></div><div><font face="monospace, monospace">     return def;</font></div><div><font face="monospace, monospace">@@ -20646,6 +20671,27 @@ virDomainDiskBlockIoDefFormat(virBufferPtr buf,</font></div><div><font face="monospace, monospace">     }</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">+static void</font></div><div><font face="monospace, monospace">+virDomainDiskCacheDefFormat(virBufferPtr buf,</font></div><div><font face="monospace, monospace">+                              virDomainDiskDefPtr def)</font></div><div><font face="monospace, monospace">+{</font></div><div><font face="monospace, monospace">+    if (def->disk_cache.disk_l2_cache_size > 0 ||</font></div><div><font face="monospace, monospace">+        def->disk_cache.disk_cache_clean_interval > 0) {</font></div><div><font face="monospace, monospace">+        virBufferAddLit(buf, "<diskCache");</font></div><div><font face="monospace, monospace">+        if (def->disk_cache.disk_l2_cache_size > 0) {</font></div><div><font face="monospace, monospace">+            virBufferAsprintf(buf,</font></div><div><font face="monospace, monospace">+                              " disk_l2_cache_size='%u'",</font></div><div><font face="monospace, monospace">+                              def->disk_cache.disk_l2_cache_size);</font></div><div><font face="monospace, monospace">+        }</font></div><div><font face="monospace, monospace">+        if (def->disk_cache.disk_cache_clean_interval > 0) {</font></div><div><font face="monospace, monospace">+            virBufferAsprintf(buf,</font></div><div><font face="monospace, monospace">+                              " disk_cache_clean_interval='%u'",</font></div><div><font face="monospace, monospace">+                              def->disk_cache.disk_cache_clean_interval);</font></div><div><font face="monospace, monospace">+        }</font></div><div><font face="monospace, monospace">+        virBufferAddLit(buf, "/>\n");</font></div><div><font face="monospace, monospace">+    }</font></div><div><font face="monospace, monospace">+}</font></div><div><font face="monospace, monospace">+</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> /* virDomainSourceDefFormatSeclabel:</font></div><div><font face="monospace, monospace">  *</font></div><div><font face="monospace, monospace">@@ -20990,6 +21036,7 @@ virDomainDiskDefFormat(virBufferPtr buf,</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">     virDomainDiskGeometryDefFormat(buf, def);</font></div><div><font face="monospace, monospace">     virDomainDiskBlockIoDefFormat(buf, def);</font></div><div><font face="monospace, monospace">+    virDomainDiskCacheDefFormat(buf, def);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">     /* For now, mirroring is currently output-only: we only output it</font></div><div><font face="monospace, monospace">      * for live domains, therefore we ignore it on input except for</font></div><div><font face="monospace, monospace">diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h</font></div><div><font face="monospace, monospace">index 91a33cb..83ea9d3 100644</font></div><div><font face="monospace, monospace">--- a/src/conf/domain_conf.h</font></div><div><font face="monospace, monospace">+++ b/src/conf/domain_conf.h</font></div><div><font face="monospace, monospace">@@ -647,6 +647,11 @@ struct _virDomainDiskDef {</font></div><div><font face="monospace, monospace">         unsigned int physical_block_size;</font></div><div><font face="monospace, monospace">     } blockio;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">+    struct {</font></div><div><font face="monospace, monospace">+        unsigned int disk_l2_cache_size;</font></div><div><font face="monospace, monospace">+        unsigned int disk_cache_clean_interval;</font></div><div><font face="monospace, monospace">+    } disk_cache;</font></div><div><font face="monospace, monospace">+</font></div><div><font face="monospace, monospace">     virDomainBlockIoTuneInfo blkdeviotune;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">     char *serial;</font></div><div><font face="monospace, monospace">diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c</font></div><div><font face="monospace, monospace">index e087891..7c47cd3 100755</font></div><div><font face="monospace, monospace">--- a/src/qemu/qemu_command.c</font></div><div><font face="monospace, monospace">+++ b/src/qemu/qemu_command.c</font></div><div><font face="monospace, monospace">@@ -1662,6 +1662,13 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,</font></div><div><font face="monospace, monospace">     if (qemuBuildDriveSourceStr(disk, cfg, &opt, qemuCaps) < 0)</font></div><div><font face="monospace, monospace">         goto error;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">+    if (disk->disk_cache.disk_l2_cache_size > 0)</font></div><div><font face="monospace, monospace">+        virBufferAsprintf(&opt, "l2-cache-size=%u,",</font></div><div><font face="monospace, monospace">+                disk->disk_cache.disk_l2_cache_size);</font></div><div><font face="monospace, monospace">+    if (disk->disk_cache.disk_cache_clean_interval > 0)</font></div><div><font face="monospace, monospace">+        virBufferAsprintf(&opt, "cache-clean-interval=%u,",</font></div><div><font face="monospace, monospace">+                disk->disk_cache.disk_cache_clean_interval);</font></div><div><font face="monospace, monospace">+</font></div><div><font face="monospace, monospace">     if (emitDeviceSyntax)</font></div><div><font face="monospace, monospace">         virBufferAddLit(&opt, "if=none");</font></div><div><font face="monospace, monospace">     else</font></div><div><font face="monospace, monospace">diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c</font></div><div><font face="monospace, monospace">index 9f165c1..de334a7 100644</font></div><div><font face="monospace, monospace">--- a/src/qemu/qemu_domain.c</font></div><div><font face="monospace, monospace">+++ b/src/qemu/qemu_domain.c</font></div><div><font face="monospace, monospace">@@ -5408,6 +5408,12 @@ qemuDomainDiskChangeSupported(virDomainDiskDefPtr disk,</font></div><div><font face="monospace, monospace">     CHECK_EQ(ioeventfd, "ioeventfd", true);</font></div><div><font face="monospace, monospace">     CHECK_EQ(event_idx, "event_idx", true);</font></div><div><font face="monospace, monospace">     CHECK_EQ(copy_on_read, "copy_on_read", true);</font></div><div><font face="monospace, monospace">+</font></div><div><font face="monospace, monospace">+    CHECK_EQ(disk_cache.disk_l2_cache_size,</font></div><div><font face="monospace, monospace">+             "diskCache disk_l2_cache_size", true);</font></div><div><font face="monospace, monospace">+    CHECK_EQ(disk_cache.disk_cache_clean_interval,</font></div><div><font face="monospace, monospace">+             "diskCache disk_cache_clean_interval", true);</font></div><div><font face="monospace, monospace">+</font></div><div><font face="monospace, monospace">     /* "snapshot" is a libvirt internal field and thus can be changed */</font></div><div><font face="monospace, monospace">     /* startupPolicy is allowed to be updated. Therefore not checked here. */</font></div><div><font face="monospace, monospace">     CHECK_EQ(transient, "transient", true);</font></div><div><font face="monospace, monospace">diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args</font></div><div><font face="monospace, monospace">index b405242..b968302 100644</font></div><div><font face="monospace, monospace">--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args</font></div><div><font face="monospace, monospace">+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args</font></div><div><font face="monospace, monospace">@@ -22,7 +22,7 @@ QEMU_AUDIO_DRV=none \</font></div><div><font face="monospace, monospace"> -drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,media=cdrom,\</font></div><div><font face="monospace, monospace"> id=drive-ide0-1-0,readonly=on \</font></div><div><font face="monospace, monospace"> -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \</font></div><div><font face="monospace, monospace">--drive file=/tmp/data.img,format=raw,if=none,id=drive-virtio-disk0 \</font></div><div><font face="monospace, monospace">+-drive file=/tmp/data.img,format=qcow2,l2-cache-size=536870912,cache-clean-interval=900,if=none,id=drive-virtio-disk0 \</font></div><div><font face="monospace, monospace"> -device virtio-blk-pci,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,\</font></div><div><font face="monospace, monospace"> id=virtio-disk0 \</font></div><div><font face="monospace, monospace"> -drive file=/tmp/logs.img,format=raw,if=none,id=drive-virtio-disk1 \</font></div><div><font face="monospace, monospace">diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml</font></div><div><font face="monospace, monospace">index b843878..43298fb 100644</font></div><div><font face="monospace, monospace">--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml</font></div><div><font face="monospace, monospace">+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml</font></div><div><font face="monospace, monospace">@@ -28,8 +28,9 @@</font></div><div><font face="monospace, monospace">       <address type='drive' controller='0' bus='1' target='0' unit='0'/></font></div><div><font face="monospace, monospace">     </disk></font></div><div><font face="monospace, monospace">     <disk type='file' device='disk'></font></div><div><font face="monospace, monospace">-      <driver name='qemu' type='raw'/></font></div><div><font face="monospace, monospace">+      <driver name='qemu' type='qcow2'/></font></div><div><font face="monospace, monospace">       <source file='/tmp/data.img'/></font></div><div><font face="monospace, monospace">+      <diskCache disk_l2_cache_size='53687' disk_cache_clean_interval='900' /></font></div><div><font face="monospace, monospace">       <target dev='vda' bus='virtio'/></font></div><div><font face="monospace, monospace">     </disk></font></div><div><font face="monospace, monospace">     <disk type='file' device='disk'></font></div></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><span style="color:rgb(26,26,26);font-family:-apple-system,system-ui,"Helvetica Neue","PingFang SC","Microsoft YaHei","Source Han Sans SC","Noto Sans CJK SC","WenQuanYi Micro Hei",sans-serif;font-size:15px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">Thanks</span></div></div>