[PATCH nbdkit v2 0/2] Use of attribute(()).
by Richard W.M. Jones
v1 was here:
https://www.redhat.com/archives/libguestfs/2019-January/msg00008.html
In v2 I have provided two patches:
The first patch extends attribute((nonnull)) to most internal
functions, but not to the external API.
The second patch uses a macro so that attribute((format)) is only used
in the public API on GCC or Clang. At least in theory these headers
could be used by a C compiler which only supports the C99 standard.
Note that I don't propose to use attribute((nonnull)) in the public
API until we have a bit more knowledge about: (1) Which version of GCC
fixed this. (2) Whether it really works well with new GCC or if we
find there are unexpected problems.
Rich.
5 years, 10 months
[PATCH nbdkit] server: Use bool for types which are really booleans.
by Richard W.M. Jones
For mainly historical reasons we tended to use int to store boolean
values. However using bool is probably safer in some corner cases
(eg. ‘v == true’ can fail badly if v is an int, but works for bool).
bool was added in C99 so let's use it.
---
server/internal.h | 16 +++++------
server/connections.c | 28 +++++++++---------
server/crypto.c | 4 +--
server/main.c | 67 ++++++++++++++++++++++----------------------
server/plugins.c | 2 +-
5 files changed, 59 insertions(+), 58 deletions(-)
diff --git a/server/internal.h b/server/internal.h
index b13685e..76d3a6d 100644
--- a/server/internal.h
+++ b/server/internal.h
@@ -79,7 +79,7 @@ struct debug_flag {
char *name; /* plugin or filter name */
char *flag; /* flag name */
int value; /* value of flag */
- int used; /* if flag was successfully set */
+ bool used; /* if flag was successfully set */
};
enum log_to {
@@ -94,22 +94,22 @@ extern struct debug_flag *debug_flags;
extern const char *exportname;
extern const char *ipaddr;
extern enum log_to log_to;
-extern int newstyle;
+extern bool newstyle;
extern const char *port;
-extern int readonly;
+extern bool readonly;
extern const char *selinux_label;
+extern int threads;
extern int tls;
extern const char *tls_certificates_dir;
extern const char *tls_psk;
-extern int tls_verify_peer;
+extern bool tls_verify_peer;
extern char *unixsocket;
-extern int verbose;
-extern int threads;
+extern bool verbose;
extern volatile int quit;
extern int quit_fd;
-extern int forked_into_background;
+extern bool forked_into_background;
extern struct backend *backend;
#define for_each_backend(b) for (b = backend; b != NULL; b = b->next)
@@ -140,7 +140,7 @@ extern void connection_set_close (struct connection *, connection_close_function
/* crypto.c */
#define root_tls_certificates_dir sysconfdir "/pki/" PACKAGE_NAME
-extern void crypto_init (int tls_set_on_cli);
+extern void crypto_init (bool tls_set_on_cli);
extern void crypto_free (void);
extern int crypto_negotiate_tls (struct connection *conn, int sockin, int sockout);
diff --git a/server/connections.c b/server/connections.c
index 0d1bd74..0a89315 100644
--- a/server/connections.c
+++ b/server/connections.c
@@ -78,13 +78,13 @@ struct connection {
uint32_t cflags;
uint64_t exportsize;
uint16_t eflags;
- int readonly;
- int can_flush;
- int is_rotational;
- int can_trim;
- int can_zero;
- int can_fua;
- int using_tls;
+ bool readonly;
+ bool can_flush;
+ bool is_rotational;
+ bool can_trim;
+ bool can_zero;
+ bool can_fua;
+ bool using_tls;
int sockin, sockout;
connection_recv_function recv;
@@ -419,7 +419,7 @@ compute_eflags (struct connection *conn, uint16_t *flags)
return -1;
if (readonly || !fl) {
eflags |= NBD_FLAG_READ_ONLY;
- conn->readonly = 1;
+ conn->readonly = true;
}
if (!conn->readonly) {
fl = backend->can_zero (backend, conn);
@@ -427,7 +427,7 @@ compute_eflags (struct connection *conn, uint16_t *flags)
return -1;
if (fl) {
eflags |= NBD_FLAG_SEND_WRITE_ZEROES;
- conn->can_zero = 1;
+ conn->can_zero = true;
}
fl = backend->can_trim (backend, conn);
@@ -435,7 +435,7 @@ compute_eflags (struct connection *conn, uint16_t *flags)
return -1;
if (fl) {
eflags |= NBD_FLAG_SEND_TRIM;
- conn->can_trim = 1;
+ conn->can_trim = true;
}
fl = backend->can_fua (backend, conn);
@@ -443,7 +443,7 @@ compute_eflags (struct connection *conn, uint16_t *flags)
return -1;
if (fl) {
eflags |= NBD_FLAG_SEND_FUA;
- conn->can_fua = 1;
+ conn->can_fua = true;
}
}
@@ -452,7 +452,7 @@ compute_eflags (struct connection *conn, uint16_t *flags)
return -1;
if (fl) {
eflags |= NBD_FLAG_SEND_FLUSH;
- conn->can_flush = 1;
+ conn->can_flush = true;
}
fl = backend->is_rotational (backend, conn);
@@ -460,7 +460,7 @@ compute_eflags (struct connection *conn, uint16_t *flags)
return -1;
if (fl) {
eflags |= NBD_FLAG_ROTATIONAL;
- conn->is_rotational = 1;
+ conn->is_rotational = true;
}
*flags = eflags;
@@ -793,7 +793,7 @@ _negotiate_handshake_newstyle_options (struct connection *conn)
/* Upgrade the connection to TLS. Also performs access control. */
if (crypto_negotiate_tls (conn, conn->sockin, conn->sockout) == -1)
return -1;
- conn->using_tls = 1;
+ conn->using_tls = true;
debug ("using TLS on this connection");
}
break;
diff --git a/server/crypto.c b/server/crypto.c
index 5b01684..4638a69 100644
--- a/server/crypto.c
+++ b/server/crypto.c
@@ -230,7 +230,7 @@ start_psk (void)
* and loading the server certificate.
*/
void
-crypto_init (int tls_set_on_cli)
+crypto_init (bool tls_set_on_cli)
{
int err, r;
const char *what;
@@ -521,7 +521,7 @@ crypto_negotiate_tls (struct connection *conn, int sockin, int sockout)
*/
void
-crypto_init (int tls_set_on_cli)
+crypto_init (bool tls_set_on_cli)
{
if (tls > 0) {
fprintf (stderr,
diff --git a/server/main.c b/server/main.c
index e8a15f7..5e538bf 100644
--- a/server/main.c
+++ b/server/main.c
@@ -35,6 +35,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
@@ -75,26 +76,26 @@ static unsigned int get_socket_activation (void);
static int is_config_key (const char *key, size_t len);
struct debug_flag *debug_flags; /* -D */
-int exit_with_parent; /* --exit-with-parent */
+bool exit_with_parent; /* --exit-with-parent */
const char *exportname; /* -e */
-int foreground; /* -f */
+bool foreground; /* -f */
const char *ipaddr; /* -i */
enum log_to log_to = LOG_TO_DEFAULT; /* --log */
-int newstyle = 1; /* 0 = -o, 1 = -n */
+bool newstyle = true; /* false = -o, true = -n */
char *pidfile; /* -P */
const char *port; /* -p */
-int readonly; /* -r */
+bool readonly; /* -r */
char *run; /* --run */
-int listen_stdin; /* -s */
+bool listen_stdin; /* -s */
const char *selinux_label; /* --selinux-label */
int threads; /* -t */
int tls; /* --tls : 0=off 1=on 2=require */
const char *tls_certificates_dir; /* --tls-certificates */
const char *tls_psk; /* --tls-psk */
-int tls_verify_peer; /* --tls-verify-peer */
+bool tls_verify_peer; /* --tls-verify-peer */
char *unixsocket; /* -U */
const char *user, *group; /* -u & -g */
-int verbose; /* -v */
+bool verbose; /* -v */
unsigned int socket_activation /* $LISTEN_FDS and $LISTEN_PID set */;
/* Detection of request to exit via signal. Most places in the code
@@ -106,7 +107,7 @@ int quit_fd;
static int write_quit_fd;
/* True if we forked into the background (used to control log messages). */
-int forked_into_background;
+bool forked_into_background;
/* The currently loaded plugin. */
struct backend *backend;
@@ -160,8 +161,8 @@ int
main (int argc, char *argv[])
{
int c;
- int help = 0, version = 0, dump_plugin = 0;
- int tls_set_on_cli = 0;
+ bool help = false, version = false, dump_plugin = false;
+ int tls_set_on_cli = false;
int short_name;
const char *filename;
char *p;
@@ -229,7 +230,7 @@ main (int argc, char *argv[])
flag->flag = strndup (p, q-p-1);
if (!flag->flag) goto debug_flag_perror;
if (sscanf (q, "%d", &flag->value) != 1) goto bad_debug_flag;
- flag->used = 0;
+ flag->used = false;
/* Add flag to the linked list. */
flag->next = debug_flags;
@@ -242,13 +243,13 @@ main (int argc, char *argv[])
exit (EXIT_SUCCESS);
case DUMP_PLUGIN_OPTION:
- dump_plugin = 1;
+ dump_plugin = true;
break;
case EXIT_WITH_PARENT_OPTION:
#ifdef HAVE_EXIT_WITH_PARENT
- exit_with_parent = 1;
- foreground = 1;
+ exit_with_parent = true;
+ foreground = true;
break;
#else
fprintf (stderr,
@@ -300,7 +301,7 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
run = optarg;
- foreground = 1;
+ foreground = true;
break;
case SELINUX_LABEL_OPTION:
@@ -315,7 +316,7 @@ main (int argc, char *argv[])
exit (EXIT_SUCCESS);
case TLS_OPTION:
- tls_set_on_cli = 1;
+ tls_set_on_cli = true;
if (strcasecmp (optarg, "require") == 0 ||
strcasecmp (optarg, "required") == 0 ||
strcasecmp (optarg, "force") == 0)
@@ -336,16 +337,16 @@ main (int argc, char *argv[])
break;
case TLS_VERIFY_PEER_OPTION:
- tls_verify_peer = 1;
+ tls_verify_peer = true;
break;
case 'e':
exportname = optarg;
- newstyle = 1;
+ newstyle = true;
break;
case 'f':
- foreground = 1;
+ foreground = true;
break;
case 'g':
@@ -362,11 +363,11 @@ main (int argc, char *argv[])
break;
case 'n':
- newstyle = 1;
+ newstyle = true;
break;
case 'o':
- newstyle = 0;
+ newstyle = false;
break;
case 'P':
@@ -385,7 +386,7 @@ main (int argc, char *argv[])
break;
case 'r':
- readonly = 1;
+ readonly = true;
break;
case 's':
@@ -394,7 +395,7 @@ main (int argc, char *argv[])
program_name);
exit (EXIT_FAILURE);
}
- listen_stdin = 1;
+ listen_stdin = true;
break;
case 't':
@@ -431,15 +432,15 @@ main (int argc, char *argv[])
break;
case 'v':
- verbose = 1;
+ verbose = true;
break;
case 'V':
- version = 1;
+ version = true;
break;
case HELP_OPTION:
- help = 1;
+ help = true;
break;
default:
@@ -477,7 +478,7 @@ main (int argc, char *argv[])
}
/* Oldstyle protocol + exportname not allowed. */
- if (newstyle == 0 && exportname != NULL) {
+ if (!newstyle && exportname != NULL) {
fprintf (stderr,
"%s: cannot use oldstyle protocol (-o) and exportname (-e)\n",
program_name);
@@ -489,7 +490,7 @@ main (int argc, char *argv[])
exportname = "";
/* --tls=require and oldstyle won't work. */
- if (tls == 2 && newstyle == 0) {
+ if (tls == 2 && !newstyle) {
fprintf (stderr,
"%s: cannot use oldstyle protocol (-o) and require TLS\n",
program_name);
@@ -727,7 +728,7 @@ open_plugin_so (size_t i, const char *name, int short_name)
{
struct backend *ret;
char *filename = (char *) name;
- int free_filename = 0;
+ bool free_filename = false;
void *dl;
struct nbdkit_plugin *(*plugin_init) (void);
char *error;
@@ -739,7 +740,7 @@ open_plugin_so (size_t i, const char *name, int short_name)
perror ("asprintf");
exit (EXIT_FAILURE);
}
- free_filename = 1;
+ free_filename = true;
}
dl = dlopen (filename, RTLD_NOW|RTLD_GLOBAL);
@@ -780,7 +781,7 @@ open_filter_so (struct backend *next, size_t i,
{
struct backend *ret;
char *filename = (char *) name;
- int free_filename = 0;
+ bool free_filename = false;
void *dl;
struct nbdkit_filter *(*filter_init) (void);
char *error;
@@ -792,7 +793,7 @@ open_filter_so (struct backend *next, size_t i,
perror ("asprintf");
exit (EXIT_FAILURE);
}
- free_filename = 1;
+ free_filename = true;
}
dl = dlopen (filename, RTLD_NOW|RTLD_GLOBAL);
@@ -1023,7 +1024,7 @@ fork_into_background (void)
if (!verbose)
dup2 (1, 2);
- forked_into_background = 1;
+ forked_into_background = true;
debug ("forked into background (new pid = %d)", getpid ());
}
diff --git a/server/plugins.c b/server/plugins.c
index 52dd3a5..701c18e 100644
--- a/server/plugins.c
+++ b/server/plugins.c
@@ -811,7 +811,7 @@ set_debug_flags (void *dl, const char *name)
*sym = flag->value;
/* Mark this flag as used. */
- flag->used = 1;
+ flag->used = true;
}
}
}
--
2.19.2
5 years, 10 months
[PATCH nbdkit] include: Annotate function parameters with attribute((nonnull)).
by Richard W.M. Jones
Should we use attribute((nonnull)) at all? There's a very interesting
history of this in libvirt -- try looking at commit eefb881 plus the
commits referencing eefb881 -- but it does seem to work for me using
recent GCC and Clang.
I only did a few functions because annotating them gets old quickly...
Rich.
5 years, 10 months
[PATCH nbdkit] plugins, filters: Define and use NBDKIT_HANDLE_NOT_NEEDED.
by Richard W.M. Jones
A common idiom where we don't need a per-connection handle is:
static void *
myplugin_open (int readonly)
{
static int handle;
return &handle;
}
We need to return some non-NULL value, but we don't care what.
This commit defines a macro NBDKIT_HANDLE_NOT_NEEDED which contains a
meaningless non-NULL pointer which can be used instead of the above.
This is more descriptive than the previous code.
---
docs/nbdkit-filter.pod | 3 ++-
docs/nbdkit-plugin.pod | 3 ++-
include/nbdkit-common.h | 5 +++++
filters/cache/cache.c | 7 +------
filters/cow/cow.c | 7 +------
filters/error/error.c | 4 +---
plugins/example1/example1.c | 7 +++----
plugins/floppy/floppy.c | 7 +------
plugins/full/full.c | 4 +---
plugins/iso/iso.c | 7 +------
plugins/memory/memory.c | 5 +----
plugins/null/null.c | 4 +---
plugins/partitioning/partitioning.c | 5 +----
plugins/pattern/pattern.c | 5 +----
plugins/random/random.c | 5 +----
15 files changed, 23 insertions(+), 55 deletions(-)
diff --git a/docs/nbdkit-filter.pod b/docs/nbdkit-filter.pod
index 77ecd7b..dd5c4ed 100644
--- a/docs/nbdkit-filter.pod
+++ b/docs/nbdkit-filter.pod
@@ -281,7 +281,8 @@ to other filter callbacks and could be freed in the C<.close>
callback.
Note that the handle is completely opaque to nbdkit, but it must not
-be NULL.
+be NULL. If you don't need to use a handle, return
+C<NBDKIT_HANDLE_NOT_NEEDED> which is a meaningless non-NULL pointer.
If there is an error, C<.open> should call C<nbdkit_error> with an
error message and return C<NULL>.
diff --git a/docs/nbdkit-plugin.pod b/docs/nbdkit-plugin.pod
index 0f8ef79..e909b0d 100644
--- a/docs/nbdkit-plugin.pod
+++ b/docs/nbdkit-plugin.pod
@@ -453,7 +453,8 @@ is passed back to other callbacks and could be freed in the C<.close>
callback.
Note that the handle is completely opaque to nbdkit, but it must not
-be NULL.
+be NULL. If you don't need to use a handle, return
+C<NBDKIT_HANDLE_NOT_NEEDED> which is a meaningless non-NULL pointer.
The C<readonly> flag informs the plugin that the user requested a
read-only connection using the I<-r> flag on the command line. Note
diff --git a/include/nbdkit-common.h b/include/nbdkit-common.h
index 9295b8a..bc3c438 100644
--- a/include/nbdkit-common.h
+++ b/include/nbdkit-common.h
@@ -70,6 +70,11 @@ extern int nbdkit_parse_bool (const char *str);
extern int nbdkit_read_password (const char *value, char **password);
extern char *nbdkit_realpath (const char *path);
+/* A meaningless non-NULL pointer which can be used when you don't
+ * need a per-connection handle.
+ */
+#define NBDKIT_HANDLE_NOT_NEEDED ((void *) &nbdkit_error)
+
#ifdef __cplusplus
}
#endif
diff --git a/filters/cache/cache.c b/filters/cache/cache.c
index 67dde23..dc7ceab 100644
--- a/filters/cache/cache.c
+++ b/filters/cache/cache.c
@@ -177,15 +177,10 @@ cache_config_complete (nbdkit_next_config_complete *next, void *nxdata)
static void *
cache_open (nbdkit_next_open *next, void *nxdata, int readonly)
{
- /* We don't use the handle, so this just provides a non-NULL
- * pointer that we can return.
- */
- static int handle;
-
if (next (nxdata, readonly) == -1)
return NULL;
- return &handle;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
/* Get the file size and ensure the cache is the correct size. */
diff --git a/filters/cow/cow.c b/filters/cow/cow.c
index fe5b00e..b8f08c4 100644
--- a/filters/cow/cow.c
+++ b/filters/cow/cow.c
@@ -70,16 +70,11 @@ cow_unload (void)
static void *
cow_open (nbdkit_next_open *next, void *nxdata, int readonly)
{
- /* We don't use the handle, so this just provides a non-NULL
- * pointer that we can return.
- */
- static int handle;
-
/* Always pass readonly=1 to the underlying plugin. */
if (next (nxdata, 1) == -1)
return NULL;
- return &handle;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
/* Get the file size and ensure the overlay is the correct size. */
diff --git a/filters/error/error.c b/filters/error/error.c
index c897c76..598bd1f 100644
--- a/filters/error/error.c
+++ b/filters/error/error.c
@@ -240,12 +240,10 @@ error_config (nbdkit_next_config *next, void *nxdata,
static void *
error_open (nbdkit_next_open *next, void *nxdata, int readonly)
{
- static int handle;
-
if (next (nxdata, readonly) == -1)
return NULL;
- return &handle;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
/* This function injects a random error. */
diff --git a/plugins/example1/example1.c b/plugins/example1/example1.c
index 871efb7..ddafc60 100644
--- a/plugins/example1/example1.c
+++ b/plugins/example1/example1.c
@@ -131,11 +131,10 @@ static void *
example1_open (int readonly)
{
/* In this trivial example we don't care about per-connection
- * handles (every connection serves up the same content and there is
- * no connection state), so we just have to return something that is
- * non-NULL and doesn't need to be freed.
+ * handles because every connection serves up the same content and
+ * there is no connection state.
*/
- return data;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
/* Size of the data we are going to serve. */
diff --git a/plugins/floppy/floppy.c b/plugins/floppy/floppy.c
index 769448c..5e23c88 100644
--- a/plugins/floppy/floppy.c
+++ b/plugins/floppy/floppy.c
@@ -110,12 +110,7 @@ floppy_config_complete (void)
static void *
floppy_open (int readonly)
{
- /* We don't need a per-connection handle, so this just acts as a
- * pointer to return.
- */
- static int h;
-
- return &h;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
diff --git a/plugins/full/full.c b/plugins/full/full.c
index 3f5159f..cb18a48 100644
--- a/plugins/full/full.c
+++ b/plugins/full/full.c
@@ -83,9 +83,7 @@ full_config_complete (void)
static void *
full_open (int readonly)
{
- static int handle;
-
- return &handle;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
diff --git a/plugins/iso/iso.c b/plugins/iso/iso.c
index bed8486..7ed5e7a 100644
--- a/plugins/iso/iso.c
+++ b/plugins/iso/iso.c
@@ -239,12 +239,7 @@ iso_config_complete (void)
static void *
iso_open (int readonly)
{
- /* We don't need a per-connection handle, so this just acts as a
- * pointer to return.
- */
- static int h;
-
- return &h;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
diff --git a/plugins/memory/memory.c b/plugins/memory/memory.c
index 8e5c084..4013087 100644
--- a/plugins/memory/memory.c
+++ b/plugins/memory/memory.c
@@ -103,10 +103,7 @@ memory_config_complete (void)
static void *
memory_open (int readonly)
{
- /* Used only as a handle pointer. */
- static int mh;
-
- return &mh;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
#define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS
diff --git a/plugins/null/null.c b/plugins/null/null.c
index cee22f5..20d333e 100644
--- a/plugins/null/null.c
+++ b/plugins/null/null.c
@@ -72,9 +72,7 @@ null_config (const char *key, const char *value)
static void *
null_open (int readonly)
{
- static int handle;
-
- return &handle;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
diff --git a/plugins/partitioning/partitioning.c b/plugins/partitioning/partitioning.c
index 2889e67..43bdd7c 100644
--- a/plugins/partitioning/partitioning.c
+++ b/plugins/partitioning/partitioning.c
@@ -276,10 +276,7 @@ partitioning_config_complete (void)
static void *
partitioning_open (int readonly)
{
- /* We don't need a handle. This is a non-NULL pointer we can return. */
- static int h;
-
- return &h;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
diff --git a/plugins/pattern/pattern.c b/plugins/pattern/pattern.c
index 46b5abd..1d1b234 100644
--- a/plugins/pattern/pattern.c
+++ b/plugins/pattern/pattern.c
@@ -73,14 +73,11 @@ pattern_config (const char *key, const char *value)
#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-/* No meaning, just used as the address for the handle. */
-static int ph;
-
/* Create the per-connection handle. */
static void *
pattern_open (int readonly)
{
- return &ph;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
/* Get the disk size. */
diff --git a/plugins/random/random.c b/plugins/random/random.c
index 72caaed..9c805ab 100644
--- a/plugins/random/random.c
+++ b/plugins/random/random.c
@@ -93,14 +93,11 @@ random_config (const char *key, const char *value)
#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
-/* No meaning, just used as the address for the handle. */
-static int rndh;
-
/* Create the per-connection handle. */
static void *
random_open (int readonly)
{
- return &rndh;
+ return NBDKIT_HANDLE_NOT_NEEDED;
}
/* Get the disk size. */
--
2.19.2
5 years, 10 months
[PATCH nbdkit 0/9] cache: Implement cache-max-size and method of reclaiming space from the cache.
by Richard W.M. Jones
This patch series enhances the cache filter in a few ways, primarily
adding a "cache-on-read" feature (similar to qemu's copyonread); and
adding the ability to limit the cache size and the antecedent of that
which is having a method to reclaim cache blocks.
As the cache is stored as a sparse temporary file, reclaiming cache
blocks simply means punching holes in the temporary file. The tricky
bit is working out where to punch the holes to avoid reclaiming
recently/frequently used blocks.
I believe the status of the patch series is:
[1/9] cache: Rename blk_writeback function.
[2/9] cache: Add cache-on-read mode.
[3/9] common/bitmap: Include <nbdkit-plugin.h>.
[4/9] cache: Split out the block/bitmap code into
- All of the above patches are pretty uncontroversial and ready for
review and upstreaming.
[5/9] cache: Allow this filter to serve requests in
- Probably needs more testing, but should be OK too.
[6/9] common/bitmap: Add bitmap_next function and tests.
[7/9] common/bitmap: Add bitmap_clear function.
[8/9] cache: Implement LRU structure.
[9/9] cache: Implement cache-max-size and method of
- Needs much better testing, and maybe even review of the design.
Rich.
5 years, 10 months