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