Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
backend: Implement next_ops->reopen call.
This is intended for use by the forthcoming retry filter to close and
reopen the backend chain.  It is handled entirely by server/backend.c
as no cooperation is needed with the plugin.

Note the explicit readonly parameter: An alternative would be to store
the previous readonly setting in the b_conn_handle struct.  However
passing it explicitly allows the retry filter to retry as readonly,
which might be useful.  This design does however require any filter
which might call .reopen to save the original readonly parameter from
the .open call.
  • Loading branch information
rwmjones committed Sep 19, 2019
1 parent cfbbe17 commit fb72fcd
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/nbdkit-filter.pod
Expand Up @@ -161,6 +161,10 @@ C<nbdkit_set_error> or setting C<errno>), whereas
C<next_ops-E<gt>pread> exposes this via an explicit parameter,
allowing a filter to learn or modify this error if desired.

There is also a C<next_ops-E<gt>reopen> function which is used by
L<nbdkit-retry-filter(3)> to close and reopen the underlying plugin.
It should be used with caution because it is difficult to use safely.

=head2 Other considerations

You can modify parameters when you call the C<next> function. However
Expand Down
6 changes: 6 additions & 0 deletions include/nbdkit-filter.h
Expand Up @@ -68,6 +68,12 @@ typedef int nbdkit_next_open (void *nxdata,
int readonly);

struct nbdkit_next_ops {
/* Performs close + open on the underlying chain.
* Used by the retry filter.
*/
int (*reopen) (void *nxdata, int readonly);

/* The rest of the next ops are the same as normal plugin operations. */
int64_t (*get_size) (void *nxdata);

int (*can_write) (void *nxdata);
Expand Down
12 changes: 12 additions & 0 deletions server/backend.c
Expand Up @@ -233,6 +233,18 @@ backend_valid_range (struct backend *b, struct connection *conn,

/* Wrappers for all callbacks in a filter's struct nbdkit_next_ops. */

int
backend_reopen (struct backend *b, struct connection *conn, int readonly)
{
struct b_conn_handle *h = &conn->handles[b->i];

debug ("%s: reopen readonly=%d", b->name, readonly);

if (h->handle != NULL)
backend_close (b, conn);
return backend_open (b, conn, readonly);
}

int64_t
backend_get_size (struct backend *b, struct connection *conn)
{
Expand Down
8 changes: 8 additions & 0 deletions server/filters.c
Expand Up @@ -237,6 +237,13 @@ filter_close (struct backend *b, struct connection *conn)
* single ‘void *nxdata’ struct pointer (‘b_conn’).
*/

static int
next_reopen (void *nxdata, int readonly)
{
struct b_conn *b_conn = nxdata;
return backend_reopen (b_conn->b, b_conn->conn, readonly);
}

static int64_t
next_get_size (void *nxdata)
{
Expand Down Expand Up @@ -373,6 +380,7 @@ next_cache (void *nxdata, uint32_t count, uint64_t offset,
}

static struct nbdkit_next_ops next_ops = {
.reopen = next_reopen,
.get_size = next_get_size,
.can_write = next_can_write,
.can_flush = next_can_flush,
Expand Down
3 changes: 3 additions & 0 deletions server/internal.h
Expand Up @@ -360,6 +360,9 @@ extern bool backend_valid_range (struct backend *b, struct connection *conn,
uint64_t offset, uint32_t count)
__attribute__((__nonnull__ (1, 2)));

extern int backend_reopen (struct backend *b, struct connection *conn,
int readonly)
__attribute__((__nonnull__ (1, 2)));
extern int64_t backend_get_size (struct backend *b, struct connection *conn)
__attribute__((__nonnull__ (1, 2)));
extern int backend_can_write (struct backend *b, struct connection *conn)
Expand Down

0 comments on commit fb72fcd

Please sign in to comment.