On Wed, Feb 16, 2022 at 04:20:38PM +0000, Richard W.M. Jones wrote:
---
docs/nbdkit-filter.pod | 9 +++++++++
docs/nbdkit-plugin.pod | 28 ++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/docs/nbdkit-filter.pod b/docs/nbdkit-filter.pod
index 36151e69..d63ee559 100644
--- a/docs/nbdkit-filter.pod
+++ b/docs/nbdkit-filter.pod
@@ -711,6 +711,15 @@ This intercepts the plugin C<.export_description> method and
can be
used to read or modify the export description that the NBD client
will see.
+=head2 C<.block_size>
+
+ int block_size (nbdkit_next *next, void *handle, uint32_t *minimum,
+ uint32_t *preferred, uint32_t *maximum);
+
+This intercepts the plugin C<.block_size> method and can be used to
+read or modify the block size constraints that the NBD client will
+see.
+
=head2 C<.can_write>
=head2 C<.can_flush>
diff --git a/docs/nbdkit-plugin.pod b/docs/nbdkit-plugin.pod
index 329bcd31..15573f0a 100644
--- a/docs/nbdkit-plugin.pod
+++ b/docs/nbdkit-plugin.pod
@@ -872,6 +872,34 @@ returning a compile-time constant string, you may find
C<nbdkit_strdup_intern> helpful for returning a value that avoids a
memory leak.
+=head2 C<.block_size>
+
+ int block_size (void *handle, uint32_t *minimum,
+ uint32_t *preferred, uint32_t *maximum);
+
+This is called during the option negotiation phase of the protocol to
+get the minimum, preferred and maximum block size (all in bytes) of
+the block device. The client should obey these by constraints by not
s/these by/these/
+making requests which are smaller than the minimum size or larger
than
+the maximum size, and usually making requests of the preferred size.
of a multiple of the preferred size
+Furthermore requests should be aligned to at least the minimum
block
+size, and usually the preferred block size.
+
+Even if the plugin implements this callback, this does B<not> mean
+that all client requests will obey the constraints. A client could
+still ignore the constraints. nbdkit passes all requests through to
+the plugin, because what the plugin does depends on the plugin's
+policy. It might decide to serve the requests correctly anyway, or
+reject them with an error.
This is where we could mention the use of the blocksize filter if you
want to isolate the plugin from a guest that doesn't obey constraints.
+
+The minimum block size must be E<ge> 1. The maximum block size must
+be E<le> 0xffff_ffff. minimum E<le> preferred E<le> maximum.
That's what the code enforced, but as mentioned in the earlier patch,
the NBD spec does permit hard-coding preferred to a fixed value (say
64k) but advertising maximum as min(export_size, 32M), where maximum <
preferred (indicating that because this file is short, there is no way
to get optimum I/O performance).
We may also want to be explicit that "preferred" here is not the I/O
size that gives optimal throughput, but the I/O size at which there is
no speed penalty for read-modify-write. For example, qemu-nbd tends
to advertise 512 or 4k, and not something larger like 64k or 1M. Of
the three values, minimum and maximum carry more value as describing
actual constraints (nothing too small for the underlying device, or
too large for the buffer size we are willing to support), while
preferred is more of a hint that may impact performance.
+
+If this callback is not used, then the NBD protocol assumes by default
+minimum = 1, preferred = 4096. (Maximum block size depends on various
+factors, see the NBD protocol specification, section "Block size
+constraints").
Missing documentation of the trick of returning all 0s to explicitly
not advertise sizes.
+
=head2 C<.can_write>
int can_write (void *handle);
--
2.35.1
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization:
qemu.org |
libvirt.org