[Libguestfs] [nbdkit PATCH 1/4] retry: Handle can_fua and can_fast_zero changes

Eric Blake eblake at redhat.com
Thu Oct 3 02:50:44 UTC 2019


Although it is less common for a plugin to change its mind on whether
FUA or fast zeroes are supported, the backend will assert if the
original connection advertised support to the client, but a retry
causes the client's request with a flag to pass to a reopened plugin
without support.

For FUA, act the same as can_write and similar failures, forcing a
retry to see if the support appears yet again (and not trying to
fallback to a direct flush call).

For fast zero, fail fast without any retry.

As with other retry fixes, the test will be in the next patch.

Fixes: f0f0ec49
Signed-off-by: Eric Blake <eblake at redhat.com>
---
 filters/retry/retry.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/filters/retry/retry.c b/filters/retry/retry.c
index ad31552c..840d7383 100644
--- a/filters/retry/retry.c
+++ b/filters/retry/retry.c
@@ -230,6 +230,11 @@ retry_pwrite (struct nbdkit_next_ops *next_ops, void *nxdata,
     *err = EROFS;
     r = -1;
   }
+  else if (flags & NBDKIT_FLAG_FUA &&
+           next_ops->can_fua (nxdata) <= NBDKIT_FUA_NONE) {
+    *err = EIO;
+    r = -1;
+  }
   else
     r = next_ops->pwrite (nxdata, buf, count, offset, flags, err);
   if (r == -1 && do_retry (h, &data, next_ops, nxdata, err)) goto again;
@@ -257,6 +262,11 @@ retry_trim (struct nbdkit_next_ops *next_ops, void *nxdata,
     *err = EROFS;
     r = -1;
   }
+  else if (flags & NBDKIT_FLAG_FUA &&
+           next_ops->can_fua (nxdata) <= NBDKIT_FUA_NONE) {
+    *err = EIO;
+    r = -1;
+  }
   else
     r = next_ops->trim (nxdata, count, offset, flags, err);
   if (r == -1 && do_retry (h, &data, next_ops, nxdata, err)) goto again;
@@ -302,10 +312,20 @@ retry_zero (struct nbdkit_next_ops *next_ops, void *nxdata,
     *err = EROFS;
     return -1;
   }
+  if (flags & NBDKIT_FLAG_FAST_ZERO &&
+           next_ops->can_fast_zero (nxdata) != 1) {
+    *err = EOPNOTSUPP;
+    return -1;
+  }
   if (next_ops->can_zero (nxdata) <= NBDKIT_ZERO_NONE) {
     *err = EROFS;
     r = -1;
   }
+  else if (flags & NBDKIT_FLAG_FUA &&
+           next_ops->can_fua (nxdata) <= NBDKIT_FUA_NONE) {
+    *err = EIO;
+    r = -1;
+  }
   else
     r = next_ops->zero (nxdata, count, offset, flags, err);
   if (r == -1 && do_retry (h, &data, next_ops, nxdata, err)) goto again;
-- 
2.21.0




More information about the Libguestfs mailing list