[Libguestfs] [nbdkit PATCH v2 08/13] connections: Allow multiple handles to be stored in the connection object.

Eric Blake eblake at redhat.com
Fri Jan 19 13:40:24 UTC 2018


From: "Richard W.M. Jones" <rjones at redhat.com>

Previously only one handle could be stored, but we will need to store
multiple handles when we have filters.

The plugin handle is defined as index 0.  Filters will use indices > 0.
Message-Id: <20180117205356.8699-6-rjones at redhat.com>
[eblake: rework for FUA support]
Signed-off-by: Eric Blake <eblake at redhat.com>
---
 src/connections.c | 37 ++++++++++++++++++++++++++++++-------
 src/internal.h    |  4 ++--
 src/plugins.c     | 53 +++++++++++++++++++++++++++--------------------------
 3 files changed, 59 insertions(+), 35 deletions(-)

diff --git a/src/connections.c b/src/connections.c
index 7a4c7bb..e225b5c 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -69,10 +69,12 @@ struct connection {
   pthread_mutex_t write_lock;
   pthread_mutex_t status_lock;
   int status; /* 1 for more I/O with client, 0 for shutdown, -1 on error */
-  void *handle;
   void *crypto_session;
   int nworkers;

+  void **handles;
+  size_t nr_handles;
+
   uint64_t exportsize;
   int readonly;
   int can_flush;
@@ -100,16 +102,37 @@ static void raw_close (struct connection *);
 /* Accessors for public fields in the connection structure.
  * Everything else is private to this file.
  */
-void
-connection_set_handle (struct connection *conn, void *handle)
+int
+connection_set_handle (struct connection *conn, size_t i, void *handle)
 {
-  conn->handle = handle;
+  size_t j;
+
+  if (i < conn->nr_handles)
+    conn->handles[i] = handle;
+  else {
+    j = conn->nr_handles;
+    conn->nr_handles = i+1;
+    conn->handles = realloc (conn->handles,
+                             conn->nr_handles * sizeof (void *));
+    if (conn->handles == NULL) {
+      perror ("realloc");
+      conn->nr_handles = 0;
+      return -1;
+    }
+    for (; j < i; ++j)
+      conn->handles[j] = NULL;
+    conn->handles[i] = handle;
+  }
+  return 0;
 }

 void *
-connection_get_handle (struct connection *conn)
+connection_get_handle (struct connection *conn, size_t i)
 {
-  return conn->handle;
+  if (i < conn->nr_handles)
+    return conn->handles[i];
+  else
+    return NULL;
 }

 pthread_mutex_t *
@@ -341,7 +364,7 @@ free_connection (struct connection *conn)
    * callback should always be called.
    */
   if (!quit) {
-    if (conn->handle)
+    if (conn->nr_handles > 0 && conn->handles[0])
       backend->close (backend, conn);
   }

diff --git a/src/internal.h b/src/internal.h
index 9d01c2b..28b1aaf 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -134,8 +134,8 @@ typedef int (*connection_recv_function) (struct connection *, void *buf, size_t
 typedef int (*connection_send_function) (struct connection *, const void *buf, size_t len);
 typedef void (*connection_close_function) (struct connection *);
 extern int handle_single_connection (int sockin, int sockout);
-extern void connection_set_handle (struct connection *conn, void *handle);
-extern void *connection_get_handle (struct connection *conn);
+extern int connection_set_handle (struct connection *conn, size_t i, void *handle);
+extern void *connection_get_handle (struct connection *conn, size_t i);
 extern pthread_mutex_t *connection_get_request_lock (struct connection *conn);
 extern void connection_set_crypto_session (struct connection *conn, void *session);
 extern void *connection_get_crypto_session (struct connection *conn);
diff --git a/src/plugins.c b/src/plugins.c
index 4442a50..137bae3 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -238,7 +238,7 @@ plugin_open (struct backend *b, struct connection *conn, int readonly)
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
   void *handle;

-  assert (connection_get_handle (conn) == NULL);
+  assert (connection_get_handle (conn, 0) == NULL);
   assert (p->plugin.open != NULL);

   debug ("%s: open readonly=%d", p->filename, readonly);
@@ -247,7 +247,7 @@ plugin_open (struct backend *b, struct connection *conn, int readonly)
   if (!handle)
     return -1;

-  connection_set_handle (conn, handle);
+  connection_set_handle (conn, 0, handle);
   return 0;
 }

@@ -256,14 +256,14 @@ plugin_close (struct backend *b, struct connection *conn)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));

   debug ("close");

   if (p->plugin.close)
-    p->plugin.close (connection_get_handle (conn));
+    p->plugin.close (connection_get_handle (conn, 0));

-  connection_set_handle (conn, NULL);
+  connection_set_handle (conn, 0, NULL);
 }

 static int64_t
@@ -271,12 +271,12 @@ plugin_get_size (struct backend *b, struct connection *conn)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));
   assert (p->plugin.get_size != NULL);

   debug ("get_size");

-  return p->plugin.get_size (connection_get_handle (conn));
+  return p->plugin.get_size (connection_get_handle (conn, 0));
 }

 static int
@@ -284,12 +284,12 @@ plugin_can_write (struct backend *b, struct connection *conn)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));

   debug ("can_write");

   if (p->plugin.can_write)
-    return p->plugin.can_write (connection_get_handle (conn));
+    return p->plugin.can_write (connection_get_handle (conn, 0));
   else
     return p->plugin.pwrite != NULL;
 }
@@ -299,12 +299,12 @@ plugin_can_flush (struct backend *b, struct connection *conn)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));

   debug ("can_flush");

   if (p->plugin.can_flush)
-    return p->plugin.can_flush (connection_get_handle (conn));
+    return p->plugin.can_flush (connection_get_handle (conn, 0));
   else
     return p->plugin.flush != NULL;
 }
@@ -314,12 +314,12 @@ plugin_is_rotational (struct backend *b, struct connection *conn)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));

   debug ("is_rotational");

   if (p->plugin.is_rotational)
-    return p->plugin.is_rotational (connection_get_handle (conn));
+    return p->plugin.is_rotational (connection_get_handle (conn, 0));
   else
     return 0; /* assume false */
 }
@@ -329,12 +329,12 @@ plugin_can_trim (struct backend *b, struct connection *conn)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));

   debug ("can_trim");

   if (p->plugin.can_trim)
-    return p->plugin.can_trim (connection_get_handle (conn));
+    return p->plugin.can_trim (connection_get_handle (conn, 0));
   else
     return p->plugin.trim != NULL;
 }
@@ -345,13 +345,13 @@ plugin_pread (struct backend *b, struct connection *conn,
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));
   assert (p->plugin.pread != NULL);
   assert (!flags);

   debug ("pread count=%" PRIu32 " offset=%" PRIu64, count, offset);

-  return p->plugin.pread (connection_get_handle (conn), buf, count, offset);
+  return p->plugin.pread (connection_get_handle (conn, 0), buf, count, offset);
 }

 static int
@@ -359,13 +359,13 @@ plugin_flush (struct backend *b, struct connection *conn, uint32_t flags)
 {
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));
   assert (!flags);

   debug ("flush");

   if (p->plugin.flush != NULL)
-    return p->plugin.flush (connection_get_handle (conn));
+    return p->plugin.flush (connection_get_handle (conn, 0));
   else {
     errno = EINVAL;
     return -1;
@@ -380,14 +380,15 @@ plugin_pwrite (struct backend *b, struct connection *conn,
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
   bool fua = flags & NBDKIT_FLAG_FUA;

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));
   assert (!(flags & ~NBDKIT_FLAG_FUA));

   debug ("pwrite count=%" PRIu32 " offset=%" PRIu64 " fua=%d", count, offset,
          fua);

   if (p->plugin.pwrite != NULL)
-    r = p->plugin.pwrite (connection_get_handle (conn), buf, count, offset);
+    r = p->plugin.pwrite (connection_get_handle (conn, 0),
+                          buf, count, offset);
   else {
     errno = EROFS;
     return -1;
@@ -407,14 +408,14 @@ plugin_trim (struct backend *b, struct connection *conn,
   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
   bool fua = flags & NBDKIT_FLAG_FUA;

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));
   assert (!(flags & ~NBDKIT_FLAG_FUA));

   debug ("trim count=%" PRIu32 " offset=%" PRIu64 " fua=%d", count, offset,
          fua);

   if (p->plugin.trim != NULL)
-    r = p->plugin.trim (connection_get_handle (conn), count, offset);
+    r = p->plugin.trim (connection_get_handle (conn, 0), count, offset);
   else {
     errno = EINVAL;
     return -1;
@@ -438,7 +439,7 @@ plugin_zero (struct backend *b, struct connection *conn,
   int may_trim = (flags & NBDKIT_FLAG_MAY_TRIM) != 0;
   bool fua = flags & NBDKIT_FLAG_FUA;

-  assert (connection_get_handle (conn));
+  assert (connection_get_handle (conn, 0));
   assert (!(flags & ~(NBDKIT_FLAG_MAY_TRIM | NBDKIT_FLAG_FUA)));

   debug ("zero count=%" PRIu32 " offset=%" PRIu64 " may_trim=%d fua=%d",
@@ -448,7 +449,7 @@ plugin_zero (struct backend *b, struct connection *conn,
     return 0;
   if (p->plugin.zero) {
     errno = 0;
-    result = p->plugin.zero (connection_get_handle (conn),
+    result = p->plugin.zero (connection_get_handle (conn, 0),
                              count, offset, may_trim);
     if (result == -1) {
       err = threadlocal_get_error ();
@@ -469,7 +470,7 @@ plugin_zero (struct backend *b, struct connection *conn,
   }

   while (count) {
-    result = p->plugin.pwrite (connection_get_handle (conn),
+    result = p->plugin.pwrite (connection_get_handle (conn, 0),
                                buf, limit, offset);
     if (result < 0)
       break;
-- 
2.14.3




More information about the Libguestfs mailing list