[Libguestfs] [nbdkit PATCH v3 11/15] plugins: Expose new FUA callbacks
Eric Blake
eblake at redhat.com
Wed Apr 11 04:10:16 UTC 2018
On 03/08/2018 05:03 PM, Eric Blake wrote:
> The NBD protocol supports Forced Unit Access (FUA) as a more efficient
> way to wait for just one write to land in persistent storage, rather
> than all outstanding writes at the time of a flush; modeled after
> the kernel's block I/O flag of the same name. While we can emulate
> the proper semantics with a full-blown flush, there are some plugins
> that can properly pass the FUA flag on to the end storage and thereby
> avoid some overhead.
>
> This patch introduces new callbacks, and updates the documentation
> to the new API, while ensuring that plugins compiled to the old API
> still work. The new API adds .can_fua, then adds a flags parameter
> to all five data callbacks, even though only three of them will use
> a flag at the moment. A plugin client has to opt in to both the
> version 2 API and provide .can_fua with a return of NBDKIT_FUA_NATIVE
> before nbdkit will pass the NBDKIT_FLAG_FUA to the plugin.
>
>
> +=head2 C<.can_fua>
> +
> + int can_fua (void *handle);
> +
> +This is called during the option negotiation phase to find out if the
> +plugin supports the Forced Unit Access (FUA) flag on write, zero, and
> +trim requests. If this returns C<NBDKIT_FUA_NONE>, FUA support is not
> +advertised to the guest; if this returns C<NBDKIT_FUA_EMULATE>, the
> +C<.flush> callback must work (even if C<.can_flush> returns false),
> +and FUA support is emulated by calling C<.flush> after any write
> +operation; if this returns C<NBDKIT_FUA_NATIVE>, then the C<.pwrite>,
> +C<.zero>, and C<.trim> callbacks (if implemented) must handle the flag
> +C<NBDKIT_FLAG_FUA>, by not returning until that action has landed in
> +persistent storage.
> +
> +If there is an error, C<.can_fua> should call C<nbdkit_error> with an
> +error message and return C<-1>.
> +
> +This callback is not required unless a plugin wants to specifically
> +handle FUA requests. If omitted, nbdkit checks C<.can_flush>, and
> +behaves as if this function returns C<NBDKIT_FUA_NONE> or
> +C<NBDKIT_FUA_EMULATE> as appropriate.
That documentation doesn't quite match the code, although I prefer the
documentation...
> +++ b/src/plugins.c
> @@ -377,14 +383,20 @@ plugin_can_fua (struct backend *b, struct connection *conn)
> struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
> int r;
>
> + assert (connection_get_handle (conn, 0));
> +
> debug ("can_fua");
>
> - /* TODO - wire FUA flag support into plugins. Until then, this copies
> - * can_flush, since that's how we emulate FUA. */
> + if (p->plugin.can_fua) {
> + r = p->plugin.can_fua (connection_get_handle (conn, 0));
> + if (r > NBDKIT_FUA_EMULATE && p->plugin._api_version == 1)
> + r = NBDKIT_FUA_EMULATE;
> + return r;
> + }
> r = plugin_can_flush (b, conn);
> if (r == -1)
> return -1;
> - if (r == 0 || !p->plugin.flush)
> + if (r == 0 || !(p->plugin.flush || p->plugin._flush_old))
> return NBDKIT_FUA_NONE;
> return NBDKIT_FUA_EMULATE;
According to the documentation, the result of .can_flush should have no
impact on the return; we want to return NBDKIT_FUA_EMULATE if .flush
exists, even when can_flush returns false. I'll be pushing this as
followup:
diff --git i/src/plugins.c w/src/plugins.c
index ff4facf..8ee58fb 100644
--- i/src/plugins.c
+++ w/src/plugins.c
@@ -386,18 +386,18 @@ plugin_can_fua (struct backend *b, struct
connection *conn)
debug ("can_fua");
+ /* The plugin MUST provide .can_fua with a return of NBDKIT_FUA_NATIVE
+ before we will pass FUA on to the plugin. */
if (p->plugin.can_fua) {
r = p->plugin.can_fua (connection_get_handle (conn, 0));
if (r > NBDKIT_FUA_EMULATE && p->plugin._api_version == 1)
r = NBDKIT_FUA_EMULATE;
return r;
}
- r = plugin_can_flush (b, conn);
- if (r == -1)
- return -1;
- if (r == 0 || !(p->plugin.flush || p->plugin._flush_old))
- return NBDKIT_FUA_NONE;
- return NBDKIT_FUA_EMULATE;
+ /* We intend to call .flush even if .can_flush returns false */
+ if (p->plugin.flush || p->plugin._flush_old)
+ return NBDKIT_FUA_EMULATE;
+ return NBDKIT_FUA_NONE;
}
/* Grab the appropriate error value.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 619 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libguestfs/attachments/20180410/60db2072/attachment.sig>
More information about the Libguestfs
mailing list