Using ‘nbdkit --filter=xz file disk.xz’ and loop mounting eventually
results in this error:
nbdkit: file[1]: debug: xz: pwrite count=4096 offset=1048576 flags=0x0
nbdkit: file[1]: debug: pwrite count=4096 offset=1048576 fua=0
nbdkit: file[1]: error: pwrite: Bad file descriptor
nbdkit: file[1]: debug: sending error reply: Bad file descriptor
Since the filter did not intercept can_write, it was passed through to
the layer below (the file plugin). The filter opens the file plugin
passing readonly=1, but in the case where there are no filters, nbdkit
core would never call can_write() (assuming that because we opened the
server readonly, it would return false). However with the filter,
can_write is called and returns the default (true). This caused
writes to be generated which were also passed through to the plugin
which generates "Bad file descriptor" because:
EBADF fd is not a valid file descriptor or is not open for writing.
This change also disables zero and trim because the server logic
disables those when the top backend->can_write returns false.
---
filters/xz/xz.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/filters/xz/xz.c b/filters/xz/xz.c
index 28a6a81..5ff791e 100644
--- a/filters/xz/xz.c
+++ b/filters/xz/xz.c
@@ -173,6 +173,13 @@ xz_get_size (struct nbdkit_next_ops *next_ops, void *nxdata, void
*handle)
return xzfile_get_size (h->xz);
}
+static int
+xz_can_write (struct nbdkit_next_ops *next_ops, void *nxdata,
+ void *handle)
+{
+ return 0;
+}
+
/* Read data from the file. */
static int
xz_pread (struct nbdkit_next_ops *next_ops, void *nxdata,
@@ -225,6 +232,7 @@ static struct nbdkit_filter filter = {
.close = xz_close,
.prepare = xz_prepare,
.get_size = xz_get_size,
+ .can_write = xz_can_write,
.pread = xz_pread,
};
--
2.20.1