[Libguestfs] [nbdkit PATCH 6/7] nbd: Wire up FUA flag passthrough

Eric Blake eblake at redhat.com
Tue Jan 16 02:51:46 UTC 2018


If the target server supports FUA, then we should pass the client
flag through rather than emulating things with a less-efficient
flush.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 plugins/nbd/nbd.c | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c
index c9727f7..09cefe5 100644
--- a/plugins/nbd/nbd.c
+++ b/plugins/nbd/nbd.c
@@ -616,6 +616,14 @@ nbd_can_trim (void *handle)
   return h->flags & NBD_FLAG_SEND_TRIM;
 }

+static int
+nbd_can_fua (void *handle)
+{
+  struct handle *h = handle;
+
+  return h->flags & NBD_FLAG_SEND_FUA;
+}
+
 /* Read data from the file. */
 static int
 nbd_pread (void *handle, void *buf, uint32_t count, uint64_t offset)
@@ -631,23 +639,26 @@ nbd_pread (void *handle, void *buf, uint32_t count, uint64_t offset)

 /* Write data to the file. */
 static int
-nbd_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset)
+nbd_pwrite (void *handle, const void *buf, uint32_t count, uint64_t offset,
+            int fua)
 {
   struct handle *h = handle;
   int c;

   /* TODO Auto-fragment this if the client has a larger max transfer
      limit than the server */
-  c = nbd_request_full (h, 0, NBD_CMD_WRITE, offset, count, buf, NULL);
+  c = nbd_request_full (h, fua ? NBD_CMD_FLAG_FUA : 0,
+                        NBD_CMD_WRITE, offset, count, buf, NULL);
   return c < 0 ? c : nbd_reply (h, c);
 }

 /* Write zeroes to the file. */
 static int
-nbd_zero (void *handle, uint32_t count, uint64_t offset, int may_trim)
+nbd_zero (void *handle, uint32_t count, uint64_t offset, int may_trim, int fua)
 {
   struct handle *h = handle;
   int c;
+  int flags = 0;

   if (!(h->flags & NBD_FLAG_SEND_WRITE_ZEROES)) {
     /* Trigger a fall back to regular writing */
@@ -655,19 +666,22 @@ nbd_zero (void *handle, uint32_t count, uint64_t offset, int may_trim)
     return -1;
   }

-  c = nbd_request (h, may_trim ? 0 : NBD_CMD_FLAG_NO_HOLE,
-                   NBD_CMD_WRITE_ZEROES, offset, count);
+  if (!may_trim)
+    flags |= NBD_CMD_FLAG_NO_HOLE;
+  if (fua)
+    flags |= NBD_CMD_FLAG_FUA;
+  c = nbd_request (h, flags, NBD_CMD_WRITE_ZEROES, offset, count);
   return c < 0 ? c : nbd_reply (h, c);
 }

 /* Trim a portion of the file. */
 static int
-nbd_trim (void *handle, uint32_t count, uint64_t offset)
+nbd_trim (void *handle, uint32_t count, uint64_t offset, int fua)
 {
   struct handle *h = handle;
   int c;

-  c = nbd_request (h, 0, NBD_CMD_TRIM, offset, count);
+  c = nbd_request (h, fua ? NBD_CMD_FLAG_FUA : 0, NBD_CMD_TRIM, offset, count);
   return c < 0 ? c : nbd_reply (h, c);
 }

@@ -697,11 +711,12 @@ static struct nbdkit_plugin plugin = {
   .can_flush          = nbd_can_flush,
   .is_rotational      = nbd_is_rotational,
   .can_trim           = nbd_can_trim,
+  .can_fua            = nbd_can_fua,
   .pread              = nbd_pread,
-  .pwrite             = nbd_pwrite,
-  .zero               = nbd_zero,
+  .pwrite_fua         = nbd_pwrite,
+  .zero_fua           = nbd_zero,
   .flush              = nbd_flush,
-  .trim               = nbd_trim,
+  .trim_fua           = nbd_trim,
   .errno_is_preserved = 1,
 };

-- 
2.14.3




More information about the Libguestfs mailing list