Fairly straightforward, as the code in plugins.c already takes
care of necessary .pwrite fallbacks.
Simplify similar can_FOO callbacks that were copy-and-pasted while
implementing py_can_zero.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
plugins/python/nbdkit-python-plugin.pod | 7 +++++
plugins/python/python.c | 51 +++++++++++++++++++--------------
tests/test.py | 4 +++
3 files changed, 41 insertions(+), 21 deletions(-)
diff --git a/plugins/python/nbdkit-python-plugin.pod
b/plugins/python/nbdkit-python-plugin.pod
index 19f9eff..29250ce 100644
--- a/plugins/python/nbdkit-python-plugin.pod
+++ b/plugins/python/nbdkit-python-plugin.pod
@@ -183,6 +183,13 @@ contents will be garbage collected.
def can_trim(h):
# return a boolean
+=item C<can_zero>
+
+(Optional)
+
+ def can_zero(h):
+ # return a boolean
+
=item C<pread>
(Required)
diff --git a/plugins/python/python.c b/plugins/python/python.c
index 07559a5..d75b36a 100644
--- a/plugins/python/python.c
+++ b/plugins/python/python.c
@@ -629,13 +629,8 @@ py_can_write (void *handle)
Py_DECREF (r);
return ret;
}
- /* No Python can_write callback, but there's a Python pwrite callback
- * defined, so return 1. (In C modules, nbdkit would do this).
- */
- else if (callback_defined ("pwrite", NULL))
- return 1;
- else
- return 0;
+ /* No Python can_write callback, so check for Python pwrite callback. */
+ return callback_defined ("pwrite", NULL);
}
static int
@@ -657,13 +652,8 @@ py_can_flush (void *handle)
Py_DECREF (r);
return ret;
}
- /* No Python can_flush callback, but there's a Python flush callback
- * defined, so return 1. (In C modules, nbdkit would do this).
- */
- else if (callback_defined ("flush", NULL))
- return 1;
- else
- return 0;
+ /* No Python can_flush callback, so check for Python flush callback. */
+ return callback_defined ("flush", NULL);
}
static int
@@ -708,13 +698,31 @@ py_can_trim (void *handle)
Py_DECREF (r);
return ret;
}
- /* No Python can_trim callback, but there's a Python trim callback
- * defined, so return 1. (In C modules, nbdkit would do this).
- */
- else if (callback_defined ("trim", NULL))
- return 1;
- else
- return 0;
+ /* No Python can_trim callback, so check for Python trim callback. */
+ return callback_defined ("trim", NULL);
+}
+
+static int
+py_can_zero (void *handle)
+{
+ PyObject *obj = handle;
+ PyObject *fn;
+ PyObject *r;
+ int ret;
+
+ if (callback_defined ("can_zero", &fn)) {
+ PyErr_Clear ();
+
+ r = PyObject_CallFunctionObjArgs (fn, obj, NULL);
+ Py_DECREF (fn);
+ if (check_python_failure ("can_zero") == -1)
+ return -1;
+ ret = r == Py_True;
+ Py_DECREF (r);
+ return ret;
+ }
+ /* No Python can_zero callback, so check for Python zero callback. */
+ return callback_defined ("zero", NULL);
}
#define py_config_help \
@@ -743,6 +751,7 @@ static struct nbdkit_plugin plugin = {
.can_flush = py_can_flush,
.is_rotational = py_is_rotational,
.can_trim = py_can_trim,
+ .can_zero = py_can_zero,
.pread = py_pread,
.pwrite = py_pwrite,
diff --git a/tests/test.py b/tests/test.py
index 518cdd4..852af55 100644
--- a/tests/test.py
+++ b/tests/test.py
@@ -30,6 +30,10 @@ def can_trim(h):
return True
+def can_zero(h):
+ return True
+
+
def pread(h, count, offset):
global disk
return disk[offset:offset+count]
--
2.14.3