All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alberto Faria <afaria@redhat.com>
To: qemu-block@nongnu.org, qemu-devel@nongnu.org
Cc: "Kevin Wolf" <kwolf@redhat.com>,
	"Hanna Reitz" <hreitz@redhat.com>,
	"Zhao Liu" <zhao1.liu@intel.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Stefan Hajnoczi" <stefanha@redhat.com>,
	"Cornelia Huck" <cohuck@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>,
	"Alberto Faria" <afaria@redhat.com>
Subject: [PATCH 2/2] virtio-blk: Add support for FUA write requests
Date: Wed, 21 Oct 2026 07:22:57 +0100	[thread overview]
Message-ID: <20261021062257.735757-3-afaria@redhat.com> (raw)
In-Reply-To: <20261021062257.735757-1-afaria@redhat.com>

Signed-off-by: Alberto Faria <afaria@redhat.com>
---
 hw/block/virtio-blk.c          | 27 +++++++++++++++++++++++++++
 hw/core/machine.c              |  1 +
 hw/virtio/virtio-qmp.c         |  4 ++++
 include/hw/virtio/virtio-blk.h |  1 +
 4 files changed, 33 insertions(+)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 61c341ce2c..3e01e043bd 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -219,6 +219,7 @@ static inline void submit_requests(VirtIOBlock *s, MultiReqBuffer *mrb,
     QEMUIOVector *qiov = &mrb->reqs[start]->qiov;
     int64_t sector_num = mrb->reqs[start]->sector_num;
     bool is_write = mrb->is_write;
+    bool is_fua = mrb->is_fua;
     BdrvRequestFlags flags = 0;
 
     if (num_reqs > 1) {
@@ -255,6 +256,9 @@ static inline void submit_requests(VirtIOBlock *s, MultiReqBuffer *mrb,
     }
 
     if (is_write) {
+        if (is_fua) {
+            flags |= BDRV_REQ_FUA;
+        }
         blk_aio_pwritev(blk, sector_num << BDRV_SECTOR_BITS, qiov,
                         flags, virtio_blk_rw_complete,
                         mrb->reqs[start]);
@@ -829,6 +833,7 @@ out:
 static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 {
     uint32_t type;
+    uint32_t flags;
     struct iovec *in_iov = req->elem.in_sg;
     struct iovec *out_iov = req->elem.out_sg;
     unsigned in_num = req->elem.in_num;
@@ -865,6 +870,7 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
                               &req->inhdr_undo);
 
     type = virtio_ldl_p(vdev, &req->out.type);
+    flags = virtio_ldl_p(vdev, &req->out.flags);
 
     /* VIRTIO_BLK_T_OUT defines the command direction. VIRTIO_BLK_T_BARRIER
      * is an optional flag. Although a guest should not send this flag if
@@ -873,6 +879,9 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
     case VIRTIO_BLK_T_IN:
     {
         bool is_write = type & VIRTIO_BLK_T_OUT;
+        bool is_fua = is_write &&
+            virtio_vdev_has_feature(vdev, VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA) &&
+            (flags & (1U << VIRTIO_BLK_REQ_FLAG_OUT_FUA));
         req->sector_num = virtio_ldq_p(vdev, &req->out.sector);
 
         if (is_write) {
@@ -900,6 +909,7 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
          * changes */
         if (mrb->num_reqs > 0 && (mrb->num_reqs == VIRTIO_BLK_MAX_MERGE_REQS ||
                                   is_write != mrb->is_write ||
+                                  is_fua != mrb->is_fua ||
                                   !s->conf.request_merging)) {
             virtio_blk_submit_multireq(s, mrb);
         }
@@ -907,6 +917,7 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
         assert(mrb->num_reqs < VIRTIO_BLK_MAX_MERGE_REQS);
         mrb->reqs[mrb->num_reqs++] = req;
         mrb->is_write = is_write;
+        mrb->is_fua = is_fua;
         break;
     }
     case VIRTIO_BLK_T_FLUSH:
@@ -1283,6 +1294,10 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
     /* Firstly sync all virtio-blk possible supported features */
     features |= s->host_features;
 
+    if (virtio_has_feature(features, VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA)) {
+        virtio_add_feature(&features, VIRTIO_BLK_F_REQ_FLAGS);
+    }
+
     virtio_add_feature(&features, VIRTIO_BLK_F_SEG_MAX);
     virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
     virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
@@ -1308,6 +1323,15 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features,
     return features;
 }
 
+static int virtio_blk_validate_features(VirtIODevice *vdev)
+{
+    if (virtio_vdev_has_feature(vdev, VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA) &&
+        !virtio_vdev_has_feature(vdev, VIRTIO_BLK_F_REQ_FLAGS)) {
+        return -EINVAL;
+    }
+    return 0;
+}
+
 static int virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
@@ -1925,6 +1949,8 @@ static const Property virtio_blk_properties[] = {
                        conf.max_discard_sectors, BDRV_REQUEST_MAX_SECTORS),
     DEFINE_PROP_UINT32("max-write-zeroes-sectors", VirtIOBlock,
                        conf.max_write_zeroes_sectors, BDRV_REQUEST_MAX_SECTORS),
+    DEFINE_PROP_BIT64("fua", VirtIOBlock, host_features,
+                      VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA, true),
     DEFINE_PROP_BOOL("x-enable-wce-if-config-wce", VirtIOBlock,
                      conf.x_enable_wce_if_config_wce, true),
 };
@@ -1942,6 +1968,7 @@ static void virtio_blk_class_init(ObjectClass *klass, const void *data)
     vdc->get_config = virtio_blk_update_config;
     vdc->set_config = virtio_blk_set_config;
     vdc->get_features = virtio_blk_get_features;
+    vdc->validate_features = virtio_blk_validate_features;
     vdc->set_status = virtio_blk_set_status;
     vdc->reset = virtio_blk_reset;
     vdc->save = virtio_blk_save_device;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index d9ac4b419a..7fc1853dab 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -43,6 +43,7 @@
 GlobalProperty hw_compat_11_1[] = {
     { "sysbus-ehci-usb", "x-migrate-fetch-addr-64bit", "off" },
     { "pci-ehci-usb", "x-migrate-fetch-addr-64bit", "off" },
+    { "virtio-blk-device", "fua", "off" },
 };
 const size_t hw_compat_11_1_len = G_N_ELEMENTS(hw_compat_11_1);
 
diff --git a/hw/virtio/virtio-qmp.c b/hw/virtio/virtio-qmp.c
index 5aaeebdd96..4aaab650c6 100644
--- a/hw/virtio/virtio-qmp.c
+++ b/hw/virtio/virtio-qmp.c
@@ -171,6 +171,10 @@ static const qmp_virtio_feature_map_t virtio_blk_feature_map[] = {
             "VIRTIO_BLK_F_SECURE_ERASE: Secure erase supported"),
     FEATURE_ENTRY(VIRTIO_BLK_F_ZONED, \
             "VIRTIO_BLK_F_ZONED: Zoned block devices"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_REQ_FLAGS, \
+            "VIRTIO_BLK_F_REQ_FLAGS: Request flags supported"),
+    FEATURE_ENTRY(VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA, \
+            "VIRTIO_BLK_F_REQ_FLAGS_OUT_FUA: FUA flag for OUT requests"),
     FEATURE_ENTRY(VIRTIO_BLK_F_BARRIER, \
             "VIRTIO_BLK_F_BARRIER: Request barriers supported"),
     FEATURE_ENTRY(VIRTIO_BLK_F_SCSI, \
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index 3d8dee7ec1..916df26b6f 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -98,6 +98,7 @@ typedef struct MultiReqBuffer {
     VirtIOBlockReq *reqs[VIRTIO_BLK_MAX_MERGE_REQS];
     unsigned int num_reqs;
     bool is_write;
+    bool is_fua;
 } MultiReqBuffer;
 
 typedef struct VirtIOBlkClass {
-- 
2.56.0



  parent reply	other threads:[~2026-10-21  6:25 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-21  6:22 [PATCH 0/2] virtio-blk: Add support for FUA write requests Alberto Faria
2026-10-21  6:22 ` [PATCH 1/2] include: Add virtio-blk request flag FUA definitions Alberto Faria
2026-10-21  7:59   ` Cornelia Huck
2026-10-21 12:22     ` Kevin Wolf
2026-10-21 12:37       ` Cornelia Huck
2026-10-21  6:22 ` Alberto Faria [this message]
2026-10-28 19:55   ` [PATCH 2/2] virtio-blk: Add support for FUA write requests Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261021062257.735757-3-afaria@redhat.com \
    --to=afaria@redhat.com \
    --cc=cohuck@redhat.com \
    --cc=hreitz@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=philmd@oss.qualcomm.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    --cc=zhao1.liu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.