go-ceph/rbd/resize.go

79 lines
2.3 KiB
Go

package rbd
/*
#cgo LDFLAGS: -lrbd
#ifndef _POSIX_C_SOURCE
// possibly defined in /usr/include/features.h already
#define _POSIX_C_SOURCE 200112L
#endif
#undef _GNU_SOURCE
#include <errno.h>
#include <stdlib.h>
#include <rados/librados.h>
#include <rbd/librbd.h>
extern int resize2Callback(uint64_t, uint64_t, uintptr_t);
// inline wrapper to cast uintptr_t to void*
static inline int wrap_rbd_resize2(
rbd_image_t image, uint64_t size, bool allow_shrink, uintptr_t arg) {
return rbd_resize2(
image, size, allow_shrink, (librbd_progress_fn_t)resize2Callback, (void*)arg);
};
*/
import "C"
import (
"github.com/ceph/go-ceph/internal/callbacks"
)
// Resize2ProgressCallback is the callback function type for Image.Resize2.
type Resize2ProgressCallback func(progress uint64, total uint64, data interface{}) int
var resizeCallbacks = callbacks.New()
type resizeProgressCallbackCtx struct {
callback Resize2ProgressCallback
data interface{}
}
//export resize2Callback
func resize2Callback(
offset, total C.uint64_t, index uintptr,
) C.int {
v := resizeCallbacks.Lookup(index)
ctx := v.(resizeProgressCallbackCtx)
return C.int(ctx.callback(uint64(offset), uint64(total), ctx.data))
}
// Resize2 resizes an rbd image and allows configuration of allow_shrink and a callback function. The callback
// function will be called with the first argument as the progress, the second argument as the total, and the third
// argument as an opaque value that is passed to the Resize2 function's data argument in each callback execution.
// The resize operation will be aborted if the progress callback returns a non-zero value.
//
// Implements:
//
// int rbd_resize2(rbd_image_t image, uint64_t size, allow_shrink bool, librbd_progress_fn_t cb, void *cbdata);
func (image *Image) Resize2(size uint64, allowShrink bool, cb Resize2ProgressCallback, data interface{}) error {
// the provided callback must be a real function
if cb == nil {
return rbdError(C.EINVAL)
}
if err := image.validate(imageIsOpen); err != nil {
return err
}
ctx := resizeProgressCallbackCtx{
callback: cb,
data: data,
}
cbIndex := resizeCallbacks.Add(ctx)
defer resizeCallbacks.Remove(cbIndex)
ret := C.wrap_rbd_resize2(image.image, C.uint64_t(size), C.bool(allowShrink), C.uintptr_t(cbIndex))
return getError(ret)
}