Although our plugin interface has to support older users that
didn't take a flag parameter, we want to allow newer plugins
that can honor flags, as well as insist that all filters take a
flag argument. This will allow future expansion to conditionally
honor any flags passed over the NBD protocol; with immediate
plans to support NBD_CMD_FLAG_FUA. So, make the backend
interface always pass flags for actions corresponding to NBD
wire commands. The .zero interface is currently the only user
of a flag; note that our NBDKIT_FLAG_MAY_TRIM preserves our old
internal sense, which is intentionally opposite of the NBD
protocol NBD_CMD_FLAG_NO_HOLE, and that our flag values are not
the same as the on-the-wire flag values.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
src/connections.c | 18 ++++++++++--------
src/internal.h | 14 ++++++++------
src/plugins.c | 18 ++++++++++++------
3 files changed, 30 insertions(+), 20 deletions(-)
diff --git a/src/connections.c b/src/connections.c
index aac1d05..8446691 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -1,5 +1,5 @@
/* nbdkit
- * Copyright (C) 2013-2017 Red Hat Inc.
+ * Copyright (C) 2013-2018 Red Hat Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -871,6 +871,7 @@ handle_request (struct connection *conn,
void *buf)
{
bool flush_after_command;
+ uint32_t f = 0;
/* Flush after command performed? */
flush_after_command = (flags & NBD_CMD_FLAG_FUA) != 0;
@@ -883,28 +884,29 @@ handle_request (struct connection *conn,
switch (cmd) {
case NBD_CMD_READ:
- if (backend->pread (backend, conn, buf, count, offset) == -1)
+ if (backend->pread (backend, conn, buf, count, offset, 0) == -1)
return get_error (conn);
break;
case NBD_CMD_WRITE:
- if (backend->pwrite (backend, conn, buf, count, offset) == -1)
+ if (backend->pwrite (backend, conn, buf, count, offset, 0) == -1)
return get_error (conn);
break;
case NBD_CMD_FLUSH:
- if (backend->flush (backend, conn) == -1)
+ if (backend->flush (backend, conn, 0) == -1)
return get_error (conn);
break;
case NBD_CMD_TRIM:
- if (backend->trim (backend, conn, count, offset) == -1)
+ if (backend->trim (backend, conn, count, offset, 0) == -1)
return get_error (conn);
break;
case NBD_CMD_WRITE_ZEROES:
- if (backend->zero (backend, conn, count, offset,
- !(flags & NBD_CMD_FLAG_NO_HOLE)) == -1)
+ if (!(flags & NBD_CMD_FLAG_NO_HOLE))
+ f |= NBDKIT_FLAG_MAY_TRIM;
+ if (backend->zero (backend, conn, count, offset, f) == -1)
return get_error (conn);
break;
@@ -912,7 +914,7 @@ handle_request (struct connection *conn,
abort ();
}
- if (flush_after_command && backend->flush (backend, conn) == -1)
+ if (flush_after_command && backend->flush (backend, conn, 0) == -1)
return get_error (conn);
return 0;
diff --git a/src/internal.h b/src/internal.h
index c4ee51b..be1a0ca 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -1,5 +1,5 @@
/* nbdkit
- * Copyright (C) 2013-2017 Red Hat Inc.
+ * Copyright (C) 2013-2018 Red Hat Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -97,6 +97,8 @@
(type *) ((char *) __mptr - offsetof(type, member)); \
})
+#define NBDKIT_FLAG_MAY_TRIM (1<<0) /* Maps to !NBD_CMD_FLAG_NO_HOLE */
+
/* main.c */
extern const char *exportname;
extern const char *ipaddr;
@@ -167,11 +169,11 @@ struct backend {
int (*can_flush) (struct backend *, struct connection *conn);
int (*is_rotational) (struct backend *, struct connection *conn);
int (*can_trim) (struct backend *, struct connection *conn);
- int (*pread) (struct backend *, struct connection *conn, void *buf, uint32_t count,
uint64_t offset);
- int (*pwrite) (struct backend *, struct connection *conn, const void *buf, uint32_t
count, uint64_t offset);
- int (*flush) (struct backend *, struct connection *conn);
- int (*trim) (struct backend *, struct connection *conn, uint32_t count, uint64_t
offset);
- int (*zero) (struct backend *, struct connection *conn, uint32_t count, uint64_t
offset, int may_trim);
+ int (*pread) (struct backend *, struct connection *conn, void *buf, uint32_t count,
uint64_t offset, uint32_t flags);
+ int (*pwrite) (struct backend *, struct connection *conn, const void *buf, uint32_t
count, uint64_t offset, uint32_t flags);
+ int (*flush) (struct backend *, struct connection *conn, uint32_t flags);
+ int (*trim) (struct backend *, struct connection *conn, uint32_t count, uint64_t
offset, uint32_t flags);
+ int (*zero) (struct backend *, struct connection *conn, uint32_t count, uint64_t
offset, uint32_t flags);
};
extern struct backend *plugin_register (const char *_filename, void *_dl, struct
nbdkit_plugin *(*plugin_init) (void));
diff --git a/src/plugins.c b/src/plugins.c
index 6a2ef66..4c6c3a5 100644
--- a/src/plugins.c
+++ b/src/plugins.c
@@ -1,5 +1,5 @@
/* nbdkit
- * Copyright (C) 2013 Red Hat Inc.
+ * Copyright (C) 2013-2018 Red Hat Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -341,12 +341,13 @@ plugin_can_trim (struct backend *b, struct connection *conn)
static int
plugin_pread (struct backend *b, struct connection *conn,
- void *buf, uint32_t count, uint64_t offset)
+ void *buf, uint32_t count, uint64_t offset, uint32_t flags)
{
struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
assert (connection_get_handle (conn));
assert (p->plugin.pread != NULL);
+ assert (!flags);
debug ("pread count=%" PRIu32 " offset=%" PRIu64, count, offset);
@@ -355,11 +356,12 @@ plugin_pread (struct backend *b, struct connection *conn,
static int
plugin_pwrite (struct backend *b, struct connection *conn,
- const void *buf, uint32_t count, uint64_t offset)
+ const void *buf, uint32_t count, uint64_t offset, uint32_t flags)
{
struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
assert (connection_get_handle (conn));
+ assert (!flags);
debug ("pwrite count=%" PRIu32 " offset=%" PRIu64, count, offset);
@@ -372,11 +374,12 @@ plugin_pwrite (struct backend *b, struct connection *conn,
}
static int
-plugin_flush (struct backend *b, struct connection *conn)
+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 (!flags);
debug ("flush");
@@ -390,11 +393,12 @@ plugin_flush (struct backend *b, struct connection *conn)
static int
plugin_trim (struct backend *b, struct connection *conn,
- uint32_t count, uint64_t offset)
+ uint32_t count, uint64_t offset, uint32_t flags)
{
struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
assert (connection_get_handle (conn));
+ assert (!flags);
debug ("trim count=%" PRIu32 " offset=%" PRIu64, count, offset);
@@ -408,15 +412,17 @@ plugin_trim (struct backend *b, struct connection *conn,
static int
plugin_zero (struct backend *b, struct connection *conn,
- uint32_t count, uint64_t offset, int may_trim)
+ uint32_t count, uint64_t offset, uint32_t flags)
{
struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
char *buf;
uint32_t limit;
int result;
int err = 0;
+ int may_trim = (flags & NBDKIT_FLAG_MAY_TRIM) != 0;
assert (connection_get_handle (conn));
+ assert (!(flags & ~NBDKIT_FLAG_MAY_TRIM));
debug ("zero count=%" PRIu32 " offset=%" PRIu64 "
may_trim=%d",
count, offset, may_trim);
--
2.14.3