[Libguestfs] [nbdkit PATCH v2 3/6] Revert "server: filters: Remove struct b_h."

Eric Blake eblake at redhat.com
Thu Feb 25 20:59:44 UTC 2021


This reverts commit fdbebe389f15bebbda8bf20c81043013396b66f5.

This has no semantic impact, but will allow the next patch to expand
the contents of b_h with one more field needed to make it possible to
implement a multi-conn filter.  The reversion is a bit more complex
than undoing the original because of new callbacks added in the
meantime, but it is still fairly mechanical.
---
 server/filters.c | 221 +++++++++++++++++++++++++++++++----------------
 1 file changed, 146 insertions(+), 75 deletions(-)

diff --git a/server/filters.c b/server/filters.c
index f4dbfea7..3e79ef5e 100644
--- a/server/filters.c
+++ b/server/filters.c
@@ -49,6 +49,16 @@ struct backend_filter {
   struct nbdkit_filter filter;
 };

+/* Literally a backend and the filter's handle.
+ *
+ * This is the implementation of our handle in .open, and serves as
+ * a stable ‘void *nxdata’ in the filter API.
+ */
+struct b_h {
+  struct backend *b;
+  void *handle;
+};
+
 /* Note this frees the whole chain. */
 static void
 filter_free (struct backend *b)
@@ -288,9 +298,8 @@ filter_default_export (struct backend *b, int readonly, int is_tls)
 static int
 next_open (void *nxdata, int readonly, const char *exportname)
 {
-  struct backend *b_next = nxdata;
-
-  return backend_open (b_next, readonly, exportname);
+  struct b_h *b_h = nxdata;
+  return backend_open (b_h->b, readonly, exportname);
 }

 static void *
@@ -298,180 +307,200 @@ filter_open (struct backend *b, int readonly, const char *exportname,
              int is_tls)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
-  void *handle;
+  struct b_h *nxdata = calloc (1, sizeof *nxdata);
+
+  if (!nxdata) {
+    nbdkit_error ("malloc: %m");
+    return NULL;
+  }
+
+  nxdata->b = b->next;

   /* Most filters will call next_open first, resulting in
    * inner-to-outer ordering.
    */
   if (f->filter.open)
-    handle = f->filter.open (next_open, b->next, readonly, exportname,
-                             is_tls);
+    nxdata->handle = f->filter.open (next_open, nxdata, readonly, exportname,
+                                     is_tls);
   else if (backend_open (b->next, readonly, exportname) == -1)
-    handle = NULL;
+    nxdata->handle = NULL;
   else
-    handle = NBDKIT_HANDLE_NOT_NEEDED;
-  return handle;
+    nxdata->handle = NBDKIT_HANDLE_NOT_NEEDED;
+  if (nxdata->handle == NULL) {
+    free (nxdata);
+    return NULL;
+  }
+
+  return nxdata;
 }

 static void
 filter_close (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

-  if (handle && f->filter.close)
-    f->filter.close (handle);
+  if (handle && f->filter.close) {
+    assert (nxdata->b == b->next);
+    f->filter.close (nxdata->handle);
+  }
+  free (nxdata);
 }

 /* The next_functions structure contains pointers to backend
- * functions.  These are only needed for type safety (nxdata is void
- * pointer, backend_* functions expect a struct backend * parameter).
- * nxdata is a pointer to the next backend in the linked list.
+ * functions.  However because these functions are all expecting a
+ * backend and a handle, we cannot call them directly, but must
+ * write some next_* functions that unpack the two parameters from a
+ * single ‘void *nxdata’ struct pointer (‘b_h’).
  */

 static int
 next_reopen (void *nxdata, int readonly, const char *exportname)
 {
-  struct backend *b_next = nxdata;
-  return backend_reopen (b_next, readonly, exportname);
+  struct b_h *b_h = nxdata;
+  return backend_reopen (b_h->b, readonly, exportname);
 }

 static int64_t
 next_get_size (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_get_size (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_get_size (b_h->b);
 }

 static const char *
 next_export_description (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_export_description (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_export_description (b_h->b);
 }

 static int
 next_can_write (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_can_write (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_can_write (b_h->b);
 }

 static int
 next_can_flush (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_can_flush (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_can_flush (b_h->b);
 }

 static int
 next_is_rotational (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_is_rotational (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_is_rotational (b_h->b);
 }

 static int
 next_can_trim (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_can_trim (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_can_trim (b_h->b);
 }

 static int
 next_can_zero (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_can_zero (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_can_zero (b_h->b);
 }

 static int
 next_can_fast_zero (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_can_fast_zero (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_can_fast_zero (b_h->b);
 }

 static int
 next_can_extents (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_can_extents (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_can_extents (b_h->b);
 }

 static int
 next_can_fua (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_can_fua (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_can_fua (b_h->b);
 }

 static int
 next_can_multi_conn (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_can_multi_conn (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_can_multi_conn (b_h->b);
 }

 static int
 next_can_cache (void *nxdata)
 {
-  struct backend *b_next = nxdata;
-  return backend_can_cache (b_next);
+  struct b_h *b_h = nxdata;
+  return backend_can_cache (b_h->b);
 }

 static int
 next_pread (void *nxdata, void *buf, uint32_t count, uint64_t offset,
             uint32_t flags, int *err)
 {
-  struct backend *b_next = nxdata;
-  return backend_pread (b_next, buf, count, offset, flags, err);
+  struct b_h *b_h = nxdata;
+  return backend_pread (b_h->b, buf, count, offset, flags,
+                        err);
 }

 static int
 next_pwrite (void *nxdata, const void *buf, uint32_t count, uint64_t offset,
              uint32_t flags, int *err)
 {
-  struct backend *b_next = nxdata;
-  return backend_pwrite (b_next, buf, count, offset, flags, err);
+  struct b_h *b_h = nxdata;
+  return backend_pwrite (b_h->b, buf, count, offset, flags,
+                         err);
 }

 static int
 next_flush (void *nxdata, uint32_t flags, int *err)
 {
-  struct backend *b_next = nxdata;
-  return backend_flush (b_next, flags, err);
+  struct b_h *b_h = nxdata;
+  return backend_flush (b_h->b, flags, err);
 }

 static int
 next_trim (void *nxdata, uint32_t count, uint64_t offset, uint32_t flags,
            int *err)
 {
-  struct backend *b_next = nxdata;
-  return backend_trim (b_next, count, offset, flags, err);
+  struct b_h *b_h = nxdata;
+  return backend_trim (b_h->b, count, offset, flags, err);
 }

 static int
 next_zero (void *nxdata, uint32_t count, uint64_t offset, uint32_t flags,
            int *err)
 {
-  struct backend *b_next = nxdata;
-  return backend_zero (b_next, count, offset, flags, err);
+  struct b_h *b_h = nxdata;
+  return backend_zero (b_h->b, count, offset, flags, err);
 }

 static int
 next_extents (void *nxdata, uint32_t count, uint64_t offset, uint32_t flags,
               struct nbdkit_extents *extents, int *err)
 {
-  struct backend *b_next = nxdata;
-  return backend_extents (b_next, count, offset, flags, extents, err);
+  struct b_h *b_h = nxdata;
+  return backend_extents (b_h->b, count, offset, flags,
+                          extents, err);
 }

 static int
 next_cache (void *nxdata, uint32_t count, uint64_t offset,
             uint32_t flags, int *err)
 {
-  struct backend *b_next = nxdata;
-  return backend_cache (b_next, count, offset, flags, err);
+  struct b_h *b_h = nxdata;
+  return backend_cache (b_h->b, count, offset, flags, err);
 }

 static struct nbdkit_next_ops next_ops = {
@@ -501,9 +530,11 @@ static int
 filter_prepare (struct backend *b, void *handle, int readonly)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.prepare &&
-      f->filter.prepare (&next_ops, b->next, handle, readonly) == -1)
+      f->filter.prepare (&next_ops, nxdata, nxdata->handle, readonly) == -1)
     return -1;

   return 0;
@@ -513,9 +544,11 @@ static int
 filter_finalize (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.finalize &&
-      f->filter.finalize (&next_ops, b->next, handle) == -1)
+      f->filter.finalize (&next_ops, nxdata, nxdata->handle) == -1)
     return -1;
   return 0;
 }
@@ -524,9 +557,11 @@ static const char *
 filter_export_description (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.export_description)
-    return f->filter.export_description (&next_ops, b->next, handle);
+    return f->filter.export_description (&next_ops, nxdata, nxdata->handle);
   else
     return backend_export_description (b->next);
 }
@@ -535,9 +570,11 @@ static int64_t
 filter_get_size (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.get_size)
-    return f->filter.get_size (&next_ops, b->next, handle);
+    return f->filter.get_size (&next_ops, nxdata, nxdata->handle);
   else
     return backend_get_size (b->next);
 }
@@ -546,9 +583,11 @@ static int
 filter_can_write (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.can_write)
-    return f->filter.can_write (&next_ops, b->next, handle);
+    return f->filter.can_write (&next_ops, nxdata, nxdata->handle);
   else
     return backend_can_write (b->next);
 }
@@ -557,9 +596,11 @@ static int
 filter_can_flush (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.can_flush)
-    return f->filter.can_flush (&next_ops, b->next, handle);
+    return f->filter.can_flush (&next_ops, nxdata, nxdata->handle);
   else
     return backend_can_flush (b->next);
 }
@@ -568,9 +609,11 @@ static int
 filter_is_rotational (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.is_rotational)
-    return f->filter.is_rotational (&next_ops, b->next, handle);
+    return f->filter.is_rotational (&next_ops, nxdata, nxdata->handle);
   else
     return backend_is_rotational (b->next);
 }
@@ -579,9 +622,11 @@ static int
 filter_can_trim (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.can_trim)
-    return f->filter.can_trim (&next_ops, b->next, handle);
+    return f->filter.can_trim (&next_ops, nxdata, nxdata->handle);
   else
     return backend_can_trim (b->next);
 }
@@ -590,9 +635,11 @@ static int
 filter_can_zero (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.can_zero)
-    return f->filter.can_zero (&next_ops, b->next, handle);
+    return f->filter.can_zero (&next_ops, nxdata, nxdata->handle);
   else
     return backend_can_zero (b->next);
 }
@@ -601,9 +648,11 @@ static int
 filter_can_fast_zero (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.can_fast_zero)
-    return f->filter.can_fast_zero (&next_ops, b->next, handle);
+    return f->filter.can_fast_zero (&next_ops, nxdata, nxdata->handle);
   else
     return backend_can_fast_zero (b->next);
 }
@@ -612,9 +661,11 @@ static int
 filter_can_extents (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.can_extents)
-    return f->filter.can_extents (&next_ops, b->next, handle);
+    return f->filter.can_extents (&next_ops, nxdata, nxdata->handle);
   else
     return backend_can_extents (b->next);
 }
@@ -623,9 +674,11 @@ static int
 filter_can_fua (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.can_fua)
-    return f->filter.can_fua (&next_ops, b->next, handle);
+    return f->filter.can_fua (&next_ops, nxdata, nxdata->handle);
   else
     return backend_can_fua (b->next);
 }
@@ -634,9 +687,11 @@ static int
 filter_can_multi_conn (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.can_multi_conn)
-    return f->filter.can_multi_conn (&next_ops, b->next, handle);
+    return f->filter.can_multi_conn (&next_ops, nxdata, nxdata->handle);
   else
     return backend_can_multi_conn (b->next);
 }
@@ -645,9 +700,11 @@ static int
 filter_can_cache (struct backend *b, void *handle)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.can_cache)
-    return f->filter.can_cache (&next_ops, b->next, handle);
+    return f->filter.can_cache (&next_ops, nxdata, nxdata->handle);
   else
     return backend_can_cache (b->next);
 }
@@ -658,9 +715,11 @@ filter_pread (struct backend *b, void *handle,
               uint32_t flags, int *err)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.pread)
-    return f->filter.pread (&next_ops, b->next, handle,
+    return f->filter.pread (&next_ops, nxdata, nxdata->handle,
                             buf, count, offset, flags, err);
   else
     return backend_pread (b->next, buf, count, offset, flags, err);
@@ -672,9 +731,11 @@ filter_pwrite (struct backend *b, void *handle,
                uint32_t flags, int *err)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.pwrite)
-    return f->filter.pwrite (&next_ops, b->next, handle,
+    return f->filter.pwrite (&next_ops, nxdata, nxdata->handle,
                              buf, count, offset, flags, err);
   else
     return backend_pwrite (b->next, buf, count, offset, flags, err);
@@ -685,9 +746,11 @@ filter_flush (struct backend *b, void *handle,
               uint32_t flags, int *err)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.flush)
-    return f->filter.flush (&next_ops, b->next, handle, flags, err);
+    return f->filter.flush (&next_ops, nxdata, nxdata->handle, flags, err);
   else
     return backend_flush (b->next, flags, err);
 }
@@ -698,9 +761,11 @@ filter_trim (struct backend *b, void *handle,
              uint32_t flags, int *err)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.trim)
-    return f->filter.trim (&next_ops, b->next, handle, count, offset,
+    return f->filter.trim (&next_ops, nxdata, nxdata->handle, count, offset,
                            flags, err);
   else
     return backend_trim (b->next, count, offset, flags, err);
@@ -711,9 +776,11 @@ filter_zero (struct backend *b, void *handle,
              uint32_t count, uint64_t offset, uint32_t flags, int *err)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.zero)
-    return f->filter.zero (&next_ops, b->next, handle,
+    return f->filter.zero (&next_ops, nxdata, nxdata->handle,
                            count, offset, flags, err);
   else
     return backend_zero (b->next, count, offset, flags, err);
@@ -725,9 +792,11 @@ filter_extents (struct backend *b, void *handle,
                 struct nbdkit_extents *extents, int *err)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.extents)
-    return f->filter.extents (&next_ops, b->next, handle,
+    return f->filter.extents (&next_ops, nxdata, nxdata->handle,
                               count, offset, flags,
                               extents, err);
   else
@@ -741,9 +810,11 @@ filter_cache (struct backend *b, void *handle,
               uint32_t flags, int *err)
 {
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
+  struct b_h *nxdata = handle;

+  assert (nxdata->b == b->next);
   if (f->filter.cache)
-    return f->filter.cache (&next_ops, b->next, handle,
+    return f->filter.cache (&next_ops, nxdata, nxdata->handle,
                             count, offset, flags, err);
   else
     return backend_cache (b->next, count, offset, flags, err);
-- 
2.30.1




More information about the Libguestfs mailing list