From: "Richard W.M. Jones" <rjones(a)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(a)redhat.com>
[eblake: rework for FUA support]
Signed-off-by: Eric Blake <eblake(a)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