Although it seems to be stable with the current Go versions,
unsafe.Pointers that are created by applying arithmetic on nil
pointers are explicitly not allowed[1], and could potentially lead to
panics by the garbage collector. To be on the safe side, this change
goes back to minimal inline wrappers for the callback registrations,
which should be zero-cost. For the callbacks themselves fortunately
no wrappers are required, because CGo happily converts void* to
uintptr arguments. The potentially problematic VoidPtr helper is
removed again.
[1] https://golang.org/pkg/unsafe/#Pointer
Signed-off-by: Sven Anderson <sven@redhat.com>
Since the index of the registered callbacks is basically only used as
void*/unsafe.Pointer, it makes more sense and code simpler, if
the index type is uintptr instead of a simple int.
Signed-off-by: Sven Anderson <sven@redhat.com>
Previously, the code that set up the callbacks was doing a pretty
direct translation of go-function to c-function. It turns out this
is not needed due to the way we set up the "dynamic" go callbacks
via an integer based callback "registry". Instead, we can stay within
the C layer entirely for the C callback, passing it only the index
value and then return to the go layer through a static C function
that only needs the index value.
Signed-off-by: John Mulligan <jmulligan@redhat.com>
In order to avoid external dependencies on implementation details,
this change replaces RBDError with the unexported rbdError. In case
some application really needs access to the integer value, it can use
the pattern
var errno interface{ Errno() int }
if errors.As(err, errno) { ... errno.Errno() ... }
Signed-off-by: Sven Anderson <sven@redhat.com>
A previous change improved our use of pointers such that go vet no
longer had an issue with these lines but if we ever need to change the
interaction between rbd and rados like that again we can now rely on a
single call site `cephIoctx` that will return our ceph/c type given the
public Go-language level type from the rados pkg.
Signed-off-by: John Mulligan <jmulligan@redhat.com>
The void * is (ab)used in C for passing arbitrary data to the callback,
which in our case is a integer index. However, Go tools can not tell
this is OK and throws an error running go vet. Change the wrapper
function to take a uintptr_t and cast that to void* only in the
(unchecked) C layer.
Signed-off-by: John Mulligan <jmulligan@redhat.com>
The DiffIterate call accepts a data structure argument containing the
parameters of the image to "diff" and a callback function. This callback
is called in the C code, making use of the recently added callbacks
helper.
The callback itself is called with the offset and length of the
differing area in the image as well as a data parameter so that
a common function can distinguish or update different data for
different calls if needed (compare to a void* in C).
Signed-off-by: John Mulligan <jmulligan@redhat.com>