[Libguestfs] [nbdkit PATCH] RFC: noextents: Add extentmode=data config parameter

Eric Blake eblake at redhat.com
Fri Feb 4 16:44:38 UTC 2022


While writing tests for an nbdcopy bug, I found myself wanting a way
to easily view an entire image as data, but without disabling extents
support altogether.  The existing extentlist filter can do this, but
requires a secondary file.

Still an RFC because I need testsuite coverage similar to
test-nozero.sh (eek - we don't have any direct test of the noextent
filter, but only indirect coverage through other tests).  Also, are
there any other extentmode=MODE values that might make sense?
---
 filters/noextents/nbdkit-noextents-filter.pod | 32 ++++++++++--
 filters/noextents/noextents.c                 | 50 ++++++++++++++++++-
 2 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/filters/noextents/nbdkit-noextents-filter.pod b/filters/noextents/nbdkit-noextents-filter.pod
index 891b197d..aac2f097 100644
--- a/filters/noextents/nbdkit-noextents-filter.pod
+++ b/filters/noextents/nbdkit-noextents-filter.pod
@@ -4,7 +4,7 @@ nbdkit-noextents-filter - disable extents in the underlying plugin

 =head1 SYNOPSIS

- nbdkit --filter=noextents plugin
+ nbdkit --filter=noextents plugin [plugin-args...] [extentmode=MODE]

 =head1 DESCRIPTION

@@ -23,9 +23,31 @@ performance (C<tmpfs> is known to be one such system).

 =head1 PARAMETERS

-There are no parameters specific to nbdkit-noextents-filter.  Any
-parameters are passed through to and processed by the underlying
-plugin in the normal way.
+The parameter C<extentmode> is optional, and controls which mode the
+filter will use.
+
+=over 4
+
+=item B<extentmode=mask>
+
+Extent support is not advertised to the client; clients should not
+query for extent information, and must assume the entire disk is
+allocated.
+
+This is the default if the C<extentmode> parameter is not specified.
+
+=item B<extentmode=data>
+
+(nbdkit E<ge> 1.30)
+
+Extent support is advertised, but extent requests from the client will
+be answered with a claim that the entire disk forms a single allocated
+data extent.
+
+=back
+
+All other parameters are passed through to and processed by the
+underlying plugin in the normal way.

 =head1 FILES

@@ -61,4 +83,4 @@ Richard W.M. Jones

 =head1 COPYRIGHT

-Copyright (C) 2019 Red Hat Inc.
+Copyright (C) 2019-2022 Red Hat Inc.
diff --git a/filters/noextents/noextents.c b/filters/noextents/noextents.c
index f3044809..36231a35 100644
--- a/filters/noextents/noextents.c
+++ b/filters/noextents/noextents.c
@@ -1,5 +1,5 @@
 /* nbdkit
- * Copyright (C) 2019 Red Hat Inc.
+ * Copyright (C) 2019-2022 Red Hat Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -32,19 +32,65 @@

 #include <config.h>

+#include <string.h>
+#include <assert.h>
+
 #include <nbdkit-filter.h>

+static enum ExtentMode {
+  MASK,
+  DATA,
+} extentmode;
+
+static int
+noextents_config (nbdkit_next_config *next, nbdkit_backend *nxdata,
+                  const char *key, const char *value)
+{
+  if (strcmp (key, "extentmode") == 0) {
+    if (strcmp (value, "mask") == 0)
+      extentmode = MASK;
+    else if (strcmp (value, "data") == 0)
+      extentmode = DATA;
+    else {
+      nbdkit_error ("unknown extentmode '%s'", value);
+      return -1;
+    }
+    return 0;
+  }
+
+  return next (nxdata, key, value);
+}
+
+#define noextents_config_help \
+  "extentmode=<MODE>    One of 'mask' (default), 'data'.\n"
+
+/* Advertise desired extents support. */
 static int
 noextents_can_extents (nbdkit_next *next,
                        void *handle)
 {
-  return 0;
+  return extentmode == DATA;
+}
+
+/* Produce single data extent. */
+static int
+noextents_extents (nbdkit_next *next,
+                   void *handle, uint32_t count, uint64_t offset,
+                   uint32_t flags,
+                   struct nbdkit_extents *ret_extents,
+                   int *err)
+{
+  assert (extentmode == DATA);
+  return nbdkit_add_extent (ret_extents, offset, count, 0);
 }

 static struct nbdkit_filter filter = {
   .name              = "noextents",
   .longname          = "nbdkit noextents filter",
+  .config            = noextents_config,
+  .config_help       = noextents_config_help,
   .can_extents       = noextents_can_extents,
+  .extents           = noextents_extents,
 };

 NBDKIT_REGISTER_FILTER(filter)
-- 
2.34.1




More information about the Libguestfs mailing list