[Libguestfs] [nbdkit PATCH v3 12/15] nbd: Wire up FUA flag passthrough

Eric Blake eblake at redhat.com
Thu Mar 8 23:03:08 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>

---
v3: rebase to API changes
---
 plugins/nbd/nbd.c | 42 +++++++++++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 9 deletions(-)

diff --git a/plugins/nbd/nbd.c b/plugins/nbd/nbd.c
index c9727f7..db53746 100644
--- a/plugins/nbd/nbd.c
+++ b/plugins/nbd/nbd.c
@@ -46,6 +46,8 @@
 #include <assert.h>
 #include <pthread.h>

+#define NBDKIT_API_VERSION 2
+
 #include <nbdkit-plugin.h>
 #include "protocol.h"

@@ -616,68 +618,89 @@ 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 ? NBDKIT_FUA_NATIVE : NBDKIT_FUA_NONE;
+}
+
 /* Read data from the file. */
 static int
-nbd_pread (void *handle, void *buf, uint32_t count, uint64_t offset)
+nbd_pread (void *handle, void *buf, uint32_t count, uint64_t offset,
+           uint32_t flags)
 {
   struct handle *h = handle;
   int c;

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

 /* 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,
+            uint32_t flags)
 {
   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);
+  assert (!(flags & ~NBDKIT_FLAG_FUA));
+  c = nbd_request_full (h, flags & NBDKIT_FLAG_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, uint32_t flags)
 {
   struct handle *h = handle;
   int c;
+  int f = 0;

+  assert (!(flags & ~(NBDKIT_FLAG_FUA | NBDKIT_FLAG_MAY_TRIM)));
   if (!(h->flags & NBD_FLAG_SEND_WRITE_ZEROES)) {
     /* Trigger a fall back to regular writing */
     errno = EOPNOTSUPP;
     return -1;
   }

-  c = nbd_request (h, may_trim ? 0 : NBD_CMD_FLAG_NO_HOLE,
-                   NBD_CMD_WRITE_ZEROES, offset, count);
+  if (!(flags & NBDKIT_FLAG_MAY_TRIM))
+    f |= NBD_CMD_FLAG_NO_HOLE;
+  if (flags & NBDKIT_FLAG_FUA)
+    f |= NBD_CMD_FLAG_FUA;
+  c = nbd_request (h, f, 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, uint32_t flags)
 {
   struct handle *h = handle;
   int c;

-  c = nbd_request (h, 0, NBD_CMD_TRIM, offset, count);
+  assert (!(flags & ~NBDKIT_FLAG_FUA));
+  c = nbd_request (h, flags & NBDKIT_FLAG_FUA ? NBD_CMD_FLAG_FUA : 0,
+                   NBD_CMD_TRIM, offset, count);
   return c < 0 ? c : nbd_reply (h, c);
 }

 /* Flush the file to disk. */
 static int
-nbd_flush (void *handle)
+nbd_flush (void *handle, uint32_t flags)
 {
   struct handle *h = handle;
   int c;

+  assert (!flags);
   c = nbd_request (h, 0, NBD_CMD_FLUSH, 0, 0);
   return c < 0 ? c : nbd_reply (h, c);
 }
@@ -697,6 +720,7 @@ 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,
-- 
2.14.3




More information about the Libguestfs mailing list