[Libguestfs] [nbdkit PATCH v2 4/6] filters: Track next handle alongside next backend

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


The next patch will introduce a new multi-conn filter, which needs to
track all client connections in order to coordinate a flush across
each open handle into the plugin.  We already guarantee that next_ops
and nxdata have a lifetime that is stable as long as the connection
exists.  However, if next_ops->flush merely calls
backend_flush(b_next), it will not do what we want, because
backend_flush starts with GET_CONN and grabs the handle associated
with the current client connection.  Instead, we want to call
backend_handle_flush(b_next, h) with the handle into the plugin
learned at the time that other connection was opened.  The solution is
obvious: add a field to our struct b_h which tracks the appropriate
plugin handle on .open and .reopen, so that all filter calls through
next_ops are now independent of the current connection that called
into the plugin.

This will also make it easier for a future patch to add the ability
for a filter to open a single background context into the plugin which
gets shared among all connections into the filter.

The patch is fairly mechanical.
---
 server/filters.c | 98 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 74 insertions(+), 24 deletions(-)

diff --git a/server/filters.c b/server/filters.c
index 3e79ef5e..975053d4 100644
--- a/server/filters.c
+++ b/server/filters.c
@@ -49,13 +49,15 @@ struct backend_filter {
   struct nbdkit_filter filter;
 };

-/* Literally a backend and the filter's handle.
+/* Literally a backend, the context for calling into that 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;
+  struct handle *h;
   void *handle;
 };

@@ -306,6 +308,7 @@ static void *
 filter_open (struct backend *b, int readonly, const char *exportname,
              int is_tls)
 {
+  GET_CONN;
   struct backend_filter *f = container_of (b, struct backend_filter, backend);
   struct b_h *nxdata = calloc (1, sizeof *nxdata);

@@ -331,6 +334,8 @@ filter_open (struct backend *b, int readonly, const char *exportname,
     return NULL;
   }

+  nxdata->h = get_handle (conn, b->i-1);
+
   return nxdata;
 }

@@ -357,92 +362,123 @@ filter_close (struct backend *b, void *handle)
 static int
 next_reopen (void *nxdata, int readonly, const char *exportname)
 {
+  GET_CONN;
   struct b_h *b_h = nxdata;
-  return backend_reopen (b_h->b, readonly, exportname);
+
+  if (backend_reopen (b_h->b, readonly, exportname) == -1) {
+    b_h->h = NULL;
+    return -1;
+  }
+  b_h->h = get_handle (conn, b_h->b->i);
+  return 0;
 }

 static int64_t
 next_get_size (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_get_size (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_get_size (b_h->b, b_h->h);
 }

 static const char *
 next_export_description (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_export_description (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_export_description (b_h->b, b_h->h);
 }

 static int
 next_can_write (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_can_write (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_can_write (b_h->b, b_h->h);
 }

 static int
 next_can_flush (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_can_flush (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_can_flush (b_h->b, b_h->h);
 }

 static int
 next_is_rotational (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_is_rotational (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_is_rotational (b_h->b, b_h->h);
 }

 static int
 next_can_trim (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_can_trim (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_can_trim (b_h->b, b_h->h);
 }

 static int
 next_can_zero (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_can_zero (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_can_zero (b_h->b, b_h->h);
 }

 static int
 next_can_fast_zero (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_can_fast_zero (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_can_fast_zero (b_h->b, b_h->h);
 }

 static int
 next_can_extents (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_can_extents (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_can_extents (b_h->b, b_h->h);
 }

 static int
 next_can_fua (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_can_fua (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_can_fua (b_h->b, b_h->h);
 }

 static int
 next_can_multi_conn (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_can_multi_conn (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_can_multi_conn (b_h->b, b_h->h);
 }

 static int
 next_can_cache (void *nxdata)
 {
   struct b_h *b_h = nxdata;
-  return backend_can_cache (b_h->b);
+
+  assert (b_h->h);
+  return backend_handle_can_cache (b_h->b, b_h->h);
 }

 static int
@@ -450,8 +486,10 @@ next_pread (void *nxdata, void *buf, uint32_t count, uint64_t offset,
             uint32_t flags, int *err)
 {
   struct b_h *b_h = nxdata;
-  return backend_pread (b_h->b, buf, count, offset, flags,
-                        err);
+
+  assert (b_h->h);
+  return backend_handle_pread (b_h->b, b_h->h, buf, count, offset, flags,
+                               err);
 }

 static int
@@ -459,15 +497,19 @@ next_pwrite (void *nxdata, const void *buf, uint32_t count, uint64_t offset,
              uint32_t flags, int *err)
 {
   struct b_h *b_h = nxdata;
-  return backend_pwrite (b_h->b, buf, count, offset, flags,
-                         err);
+
+  assert (b_h->h);
+  return backend_handle_pwrite (b_h->b, b_h->h, buf, count, offset, flags,
+                                err);
 }

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

 static int
@@ -475,7 +517,9 @@ next_trim (void *nxdata, uint32_t count, uint64_t offset, uint32_t flags,
            int *err)
 {
   struct b_h *b_h = nxdata;
-  return backend_trim (b_h->b, count, offset, flags, err);
+
+  assert (b_h->h);
+  return backend_handle_trim (b_h->b, b_h->h, count, offset, flags, err);
 }

 static int
@@ -483,7 +527,9 @@ next_zero (void *nxdata, uint32_t count, uint64_t offset, uint32_t flags,
            int *err)
 {
   struct b_h *b_h = nxdata;
-  return backend_zero (b_h->b, count, offset, flags, err);
+
+  assert (b_h->h);
+  return backend_handle_zero (b_h->b, b_h->h, count, offset, flags, err);
 }

 static int
@@ -491,8 +537,10 @@ next_extents (void *nxdata, uint32_t count, uint64_t offset, uint32_t flags,
               struct nbdkit_extents *extents, int *err)
 {
   struct b_h *b_h = nxdata;
-  return backend_extents (b_h->b, count, offset, flags,
-                          extents, err);
+
+  assert (b_h->h);
+  return backend_handle_extents (b_h->b, b_h->h, count, offset, flags,
+                                 extents, err);
 }

 static int
@@ -500,7 +548,9 @@ next_cache (void *nxdata, uint32_t count, uint64_t offset,
             uint32_t flags, int *err)
 {
   struct b_h *b_h = nxdata;
-  return backend_cache (b_h->b, count, offset, flags, err);
+
+  assert (b_h->h);
+  return backend_handle_cache (b_h->b, b_h->h, count, offset, flags, err);
 }

 static struct nbdkit_next_ops next_ops = {
-- 
2.30.1




More information about the Libguestfs mailing list