We no longer need a 'struct nbdkit_next' now that a single pointer is
sufficient for calling into the backend.
There's still more to do with the filter to allow multiple client
plugins to share a single context into the plugin, but that requires a
bit more work (for starters, we need a way to clean up that single
context; .unload is too late, but doing it in .close requires tracking
how many open client connections there are).
---
filters/ext2/io.h | 12 +++-----
filters/ext2/ext2.c | 43 +++++++++++++-------------
filters/ext2/io.c | 73 ++++++++++++++++++++++-----------------------
3 files changed, 61 insertions(+), 67 deletions(-)
diff --git a/filters/ext2/io.h b/filters/ext2/io.h
index da286812..2112e541 100644
--- a/filters/ext2/io.h
+++ b/filters/ext2/io.h
@@ -1,5 +1,5 @@
/* nbdkit
- * Copyright (C) 2020 Red Hat Inc.
+ * Copyright (C) 2020-2021 Red Hat Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -35,19 +35,15 @@
#include <ext2_io.h>
+#define NBDKIT_TYPESAFE /* HACK to get type-safe parameters. */
#include <nbdkit-filter.h>
#define EXT2_ET_MAGIC_NBDKIT_IO_CHANNEL EXT2_ET_MAGIC_RESERVED_19
-struct nbdkit_next {
- struct nbdkit_next_ops *next_ops;
- void *nxdata;
-};
-
/* Utility functions for encoding nbdkit_next as a name usable by ext2fs */
-extern char *nbdkit_io_encode(const struct nbdkit_next *next)
+extern char *nbdkit_io_encode(const nbdkit_next *next)
__attribute__ ((__nonnull__ (1)));
-extern int nbdkit_io_decode(const char *name, struct nbdkit_next *out)
+extern int nbdkit_io_decode(const char *name, nbdkit_next **out)
__attribute__ ((__nonnull__ (1, 2)));
/* Custom io manager that performs all ext2fs I/O on the next nbdkit layer */
diff --git a/filters/ext2/ext2.c b/filters/ext2/ext2.c
index 1151effd..9a6eec94 100644
--- a/filters/ext2/ext2.c
+++ b/filters/ext2/ext2.c
@@ -45,6 +45,7 @@
#define NBDKIT_API_VERSION 2
+#define NBDKIT_TYPESAFE /* HACK to get type-safe parameters. */
#include <nbdkit-filter.h>
#include "cleanup.h"
@@ -62,7 +63,7 @@ ext2_load (void)
}
static int
-ext2_config (nbdkit_next_config *next, void *nxdata,
+ext2_config (nbdkit_next_config *next, nbdkit_backend *nxdata,
const char *key, const char *value)
{
if (strcmp (key, "ext2file") == 0) {
@@ -78,7 +79,7 @@ ext2_config (nbdkit_next_config *next, void *nxdata,
}
static int
-ext2_config_complete (nbdkit_next_config_complete *next, void *nxdata)
+ext2_config_complete (nbdkit_next_config_complete *next, nbdkit_backend *nxdata)
{
if (file == NULL) {
nbdkit_error ("you must supply ext2file=<FILE> parameter "
@@ -106,12 +107,12 @@ struct handle {
ext2_filsys fs; /* Filesystem handle. */
ext2_ino_t ino; /* Inode of open file. */
ext2_file_t file; /* File handle. */
- struct nbdkit_next next; /* "name" parameter to ext2fs_open. */
+ nbdkit_next *next; /* "name" parameter to ext2fs_open. */
};
/* Export list. */
static int
-ext2_list_exports (nbdkit_next_list_exports *next, void *nxdata,
+ext2_list_exports (nbdkit_next_list_exports *next, nbdkit_backend *nxdata,
int readonly, int is_tls, struct nbdkit_exports *exports)
{
/* If we are honoring export names, the default export "" won't
@@ -133,7 +134,7 @@ ext2_list_exports (nbdkit_next_list_exports *next, void *nxdata,
/* Default export. */
static const char *
-ext2_default_export (nbdkit_next_default_export *next, void *nxdata,
+ext2_default_export (nbdkit_next_default_export *next, nbdkit_backend *nxdata,
int readonly, int is_tls)
{
/* If we are honoring exports, "" will fail (even if we resolve to
@@ -152,7 +153,7 @@ ext2_default_export (nbdkit_next_default_export *next, void *nxdata,
/* Create the per-connection handle. */
static void *
-ext2_open (nbdkit_next_open *next, void *nxdata,
+ext2_open (nbdkit_next_open *next, nbdkit_context *nxdata,
int readonly, const char *exportname, int is_tls)
{
struct handle *h;
@@ -185,7 +186,7 @@ ext2_open (nbdkit_next_open *next, void *nxdata,
}
static int
-ext2_prepare (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle,
+ext2_prepare (nbdkit_next *next_ops, nbdkit_next *nxdata, void *handle,
int readonly)
{
struct handle *h = handle;
@@ -214,9 +215,8 @@ ext2_prepare (struct nbdkit_next_ops *next_ops, void *nxdata, void
*handle,
if (!readonly)
fs_flags |= EXT2_FLAG_RW;
- h->next.next_ops = next_ops;
- h->next.nxdata = nxdata;
- name = nbdkit_io_encode (&h->next);
+ h->next = next_ops;
+ name = nbdkit_io_encode (next_ops);
if (!name) {
nbdkit_error ("nbdkit_io_encode: %m");
return -1;
@@ -293,20 +293,20 @@ ext2_close (void *handle)
}
static int
-ext2_can_fua (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle)
+ext2_can_fua (nbdkit_next *next_ops, nbdkit_next *nxdata, void *handle)
{
return NBDKIT_FUA_NATIVE;
}
static int
-ext2_can_cache (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle)
+ext2_can_cache (nbdkit_next *next_ops, nbdkit_next *nxdata, void *handle)
{
/* Let nbdkit call pread to populate the file system cache. */
return NBDKIT_CACHE_EMULATE;
}
static int
-ext2_can_multi_conn (struct nbdkit_next_ops *next_ops, void *nxdata,
+ext2_can_multi_conn (nbdkit_next *next_ops, nbdkit_next *nxdata,
void *handle)
{
/* Since we do not permit parallel connections, it does not matter
@@ -320,7 +320,8 @@ ext2_can_multi_conn (struct nbdkit_next_ops *next_ops, void *nxdata,
}
static int
-ext2_can_flush (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle)
+ext2_can_flush (nbdkit_next *next_ops, nbdkit_next *nxdata,
+ void *handle)
{
/* Regardless of the underlying plugin, we handle flush at the level
* of the filesystem. However, we also need to cache the underlying
@@ -337,7 +338,7 @@ ext2_can_flush (struct nbdkit_next_ops *next_ops, void *nxdata, void
*handle)
* is very obscure.
*/
static int
-ext2_can_zero (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle)
+ext2_can_zero (nbdkit_next *next_ops, nbdkit_next *nxdata, void *handle)
{
/* For now, tell nbdkit to call .pwrite instead of any optimization.
* However, we also want to cache the underlying plugin support.
@@ -348,7 +349,7 @@ ext2_can_zero (struct nbdkit_next_ops *next_ops, void *nxdata, void
*handle)
}
static int
-ext2_can_trim (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle)
+ext2_can_trim (nbdkit_next *next_ops, nbdkit_next *nxdata, void *handle)
{
/* For now, tell nbdkit to never call .trim. However, we also want
* to cache the underlying plugin support.
@@ -377,7 +378,7 @@ static int ext2_thread_model (void)
/* Description. */
static const char *
-ext2_export_description (struct nbdkit_next_ops *next_ops, void *nxdata,
+ext2_export_description (nbdkit_next *next_ops, nbdkit_next *nxdata,
void *handle)
{
struct handle *h = handle;
@@ -393,7 +394,7 @@ ext2_export_description (struct nbdkit_next_ops *next_ops, void
*nxdata,
/* Get the disk size. */
static int64_t
-ext2_get_size (struct nbdkit_next_ops *next_ops, void *nxdata, void *handle)
+ext2_get_size (nbdkit_next *next_ops, nbdkit_next *nxdata, void *handle)
{
struct handle *h = handle;
errcode_t err;
@@ -409,7 +410,7 @@ ext2_get_size (struct nbdkit_next_ops *next_ops, void *nxdata, void
*handle)
/* Read data. */
static int
-ext2_pread (struct nbdkit_next_ops *next_ops, void *nxdata,
+ext2_pread (nbdkit_next *next_ops, nbdkit_next *nxdata,
void *handle, void *buf, uint32_t count, uint64_t offset,
uint32_t flags, int *errp)
{
@@ -446,7 +447,7 @@ ext2_pread (struct nbdkit_next_ops *next_ops, void *nxdata,
/* Write data to the file. */
static int
-ext2_pwrite (struct nbdkit_next_ops *next_ops, void *nxdata,
+ext2_pwrite (nbdkit_next *next_ops, nbdkit_next *nxdata,
void *handle, const void *buf, uint32_t count, uint64_t offset,
uint32_t flags, int *errp)
{
@@ -487,7 +488,7 @@ ext2_pwrite (struct nbdkit_next_ops *next_ops, void *nxdata,
}
static int
-ext2_flush (struct nbdkit_next_ops *next_ops, void *nxdata,
+ext2_flush (nbdkit_next *next_ops, nbdkit_next *nxdata,
void *handle, uint32_t flags, int *errp)
{
struct handle *h = handle;
diff --git a/filters/ext2/io.c b/filters/ext2/io.c
index 32c50683..e2f7e43e 100644
--- a/filters/ext2/io.c
+++ b/filters/ext2/io.c
@@ -60,8 +60,7 @@
struct io_private_data {
int magic;
- struct nbdkit_next_ops *next_ops;
- void *nxdata;
+ nbdkit_next *next;
ext2_loff_t offset;
struct struct_io_stats io_stats;
};
@@ -103,7 +102,7 @@ raw_read_blk (io_channel channel,
location = ((ext2_loff_t) block * channel->block_size) + data->offset;
/* TODO is 32-bit overflow ever likely to be a problem? */
- if (data->next_ops->pread (data->nxdata, buf, size, location, 0, &errno)
== 0)
+ if (data->next->pread (data->next, buf, size, location, 0, &errno) == 0)
return 0;
retval = errno;
@@ -138,8 +137,8 @@ raw_write_blk (io_channel channel,
location = ((ext2_loff_t) block * channel->block_size) + data->offset;
/* TODO is 32-bit overflow ever likely to be a problem? */
- if (data->next_ops->pwrite (data->nxdata, buf, size, location, 0,
- &errno) == 0)
+ if (data->next->pwrite (data->next, buf, size, location, 0,
+ &errno) == 0)
return 0;
retval = errno;
@@ -150,22 +149,21 @@ raw_write_blk (io_channel channel,
}
char *
-nbdkit_io_encode (const struct nbdkit_next *next)
+nbdkit_io_encode (const nbdkit_next *next)
{
char *ret;
- if (asprintf (&ret, "nbdkit:%p:%p", next->next_ops, next->nxdata)
< 0)
+ if (asprintf (&ret, "nbdkit:%p", next) < 0)
return NULL;
return ret;
}
int
-nbdkit_io_decode (const char *name, struct nbdkit_next *next)
+nbdkit_io_decode (const char *name, nbdkit_next **next)
{
int n;
- if (sscanf (name, "nbdkit:%p:%p%n", &next->next_ops,
&next->nxdata,
- &n) != 2 || n != strlen (name))
+ if (sscanf (name, "nbdkit:%p%n", next, &n) != 1 || n != strlen (name))
return -1;
return 0;
}
@@ -174,7 +172,7 @@ static errcode_t
io_open (const char *name, int flags,
io_channel *channel)
{
- struct nbdkit_next next;
+ nbdkit_next *next;
io_channel io = NULL;
struct io_private_data *data = NULL;
errcode_t retval;
@@ -206,14 +204,13 @@ io_open (const char *name, int flags,
memset (data, 0, sizeof (struct io_private_data));
data->magic = EXT2_ET_MAGIC_NBDKIT_IO_CHANNEL;
data->io_stats.num_fields = 2;
- data->next_ops = next.next_ops;
- data->nxdata = next.nxdata;
+ data->next = next;
- /* Too bad NBD doesn't tell us if next_ops->trim guarantees read as zero. */
- /* if (next_ops-> XXX (...)
+ /* Too bad NBD doesn't tell us if next->trim guarantees read as zero. */
+ /* if (next-> XXX (...)
io->flags |= CHANNEL_FLAGS_DISCARD_ZEROES; */
- if (flags & IO_FLAG_RW && next.next_ops->can_write (next.nxdata) != 1)
{
+ if (flags & IO_FLAG_RW && next->can_write (next) != 1) {
retval = EPERM;
goto cleanup;
}
@@ -310,13 +307,13 @@ io_cache_readahead (io_channel channel,
data = (struct io_private_data *)channel->private_data;
EXT2_CHECK_MAGIC (data, EXT2_ET_MAGIC_NBDKIT_IO_CHANNEL);
- if (data->next_ops->can_cache (data->nxdata) == NBDKIT_CACHE_NATIVE) {
+ if (data->next->can_cache (data->next) == NBDKIT_CACHE_NATIVE) {
/* TODO is 32-bit overflow ever likely to be a problem? */
- if (data->next_ops->cache (data->nxdata,
- (ext2_loff_t)count * channel->block_size,
- ((ext2_loff_t)block * channel->block_size +
- data->offset),
- 0, &errno) == -1)
+ if (data->next->cache (data->next,
+ (ext2_loff_t)count * channel->block_size,
+ ((ext2_loff_t)block * channel->block_size +
+ data->offset),
+ 0, &errno) == -1)
return errno;
return 0;
}
@@ -342,8 +339,8 @@ io_write_byte (io_channel channel, unsigned long offset,
data = (struct io_private_data *) channel->private_data;
EXT2_CHECK_MAGIC (data, EXT2_ET_MAGIC_NBDKIT_IO_CHANNEL);
- if (data->next_ops->pwrite (data->nxdata, buf, size,
- offset + data->offset, 0, &errno) == -1)
+ if (data->next->pwrite (data->next, buf, size,
+ offset + data->offset, 0, &errno) == -1)
return errno;
return 0;
@@ -362,8 +359,8 @@ io_flush (io_channel channel)
data = (struct io_private_data *) channel->private_data;
EXT2_CHECK_MAGIC (data, EXT2_ET_MAGIC_NBDKIT_IO_CHANNEL);
- if (data->next_ops->can_flush (data->nxdata) == 1)
- if (data->next_ops->flush (data->nxdata, 0, &errno) == -1)
+ if (data->next->can_flush (data->next) == 1)
+ if (data->next->flush (data->next, 0, &errno) == -1)
return errno;
return retval;
}
@@ -405,13 +402,13 @@ io_discard (io_channel channel, unsigned long long block,
data = (struct io_private_data *) channel->private_data;
EXT2_CHECK_MAGIC (data, EXT2_ET_MAGIC_NBDKIT_IO_CHANNEL);
- if (data->next_ops->can_trim (data->nxdata) == 1) {
+ if (data->next->can_trim (data->next) == 1) {
/* TODO is 32-bit overflow ever likely to be a problem? */
- if (data->next_ops->trim (data->nxdata,
- (off_t)(count) * channel->block_size,
- ((off_t)(block) * channel->block_size +
- data->offset),
- 0, &errno) == 0)
+ if (data->next->trim (data->next,
+ (off_t)(count) * channel->block_size,
+ ((off_t)(block) * channel->block_size +
+ data->offset),
+ 0, &errno) == 0)
return 0;
if (errno == EOPNOTSUPP)
goto unimplemented;
@@ -433,13 +430,13 @@ io_zeroout (io_channel channel, unsigned long long block,
data = (struct io_private_data *) channel->private_data;
EXT2_CHECK_MAGIC (data, EXT2_ET_MAGIC_NBDKIT_IO_CHANNEL);
- if (data->next_ops->can_zero (data->nxdata) > NBDKIT_ZERO_NONE) {
+ if (data->next->can_zero (data->next) > NBDKIT_ZERO_NONE) {
/* TODO is 32-bit overflow ever likely to be a problem? */
- if (data->next_ops->zero (data->nxdata,
- (off_t)(count) * channel->block_size,
- ((off_t)(block) * channel->block_size +
- data->offset),
- NBDKIT_FLAG_MAY_TRIM, &errno) == 0)
+ if (data->next->zero (data->next,
+ (off_t)(count) * channel->block_size,
+ ((off_t)(block) * channel->block_size +
+ data->offset),
+ NBDKIT_FLAG_MAY_TRIM, &errno) == 0)
return 0;
if (errno == EOPNOTSUPP)
goto unimplemented;
--
2.30.1