go-ceph/rados/striper/xattr.go

151 lines
3.9 KiB
Go

//go:build ceph_preview
package striper
// #cgo LDFLAGS: -lrados -lradosstriper
// #include <stdlib.h>
// #include <radosstriper/libradosstriper.h>
import "C"
import (
"errors"
"unsafe"
)
var errStopIteration = errors.New("stop iteraton")
// GetXattr retrieves an extended attribute (xattr) of the given name from the
// specified striped object.
//
// Implements:
//
// int rados_striper_getxattr(rados_striper_t striper,
// const char *oid,
// const char *name,
// char *buf,
// size_t len);
func (s *Striper) GetXattr(soid string, name string, data []byte) (int, error) {
csoid := C.CString(soid)
cName := C.CString(name)
defer C.free(unsafe.Pointer(csoid))
defer C.free(unsafe.Pointer(cName))
ret := C.rados_striper_getxattr(
s.striper,
csoid,
cName,
(*C.char)(unsafe.Pointer(&data[0])),
(C.size_t)(len(data)))
if ret >= 0 {
return int(ret), nil
}
return 0, getError(ret)
}
// SetXattr sets an extended attribute (xattr) of the given name on the
// specified striped object.
//
// Implements:
//
// int rados_striper_setxattr(rados_striper_t striper,
// const char *oid,
// const char *name,
// const char *buf,
// size_t len);
func (s *Striper) SetXattr(soid string, name string, data []byte) error {
csoid := C.CString(soid)
cName := C.CString(name)
defer C.free(unsafe.Pointer(csoid))
defer C.free(unsafe.Pointer(cName))
ret := C.rados_striper_setxattr(
s.striper,
csoid,
cName,
(*C.char)(unsafe.Pointer(&data[0])),
(C.size_t)(len(data)))
return getError(ret)
}
// RmXattr removes the extended attribute (xattr) of the given name from the
// striped object.
//
// Implements:
//
// int rados_striper_rmxattr(rados_striper_t striper,
// const char *oid,
// const char *name);
func (s *Striper) RmXattr(soid string, name string) error {
csoid := C.CString(soid)
cName := C.CString(name)
defer C.free(unsafe.Pointer(csoid))
defer C.free(unsafe.Pointer(cName))
ret := C.rados_striper_rmxattr(s.striper, csoid, cName)
return getError(ret)
}
// getXattrsNext wraps the function to fetch a xattr name/value pair
// from the iterator. If the iterator is exhausted the error value
// will be errStopIteration.
//
// Implements:
//
// int rados_striper_getxattrs_next(rados_xattrs_iter_t iter,
// const char **name,
// const char **val,
// size_t *len);
func getXattrsNext(it C.rados_xattrs_iter_t) (string, []byte, error) {
var (
cName, cValue *C.char
cLen C.size_t
)
defer C.free(unsafe.Pointer(cName))
defer C.free(unsafe.Pointer(cValue))
ret := C.rados_striper_getxattrs_next(it, &cName, &cValue, &cLen)
if ret < 0 {
return "", nil, getError(ret)
}
if cName == nil && cValue == nil {
return "", nil, errStopIteration
}
return C.GoString(cName), C.GoBytes(unsafe.Pointer(cValue), C.int(cLen)), nil
}
// ListXattrs returns a map containing all of the extended attributes (xattrs)
// for a striped object. The xattr names provide the key strings and the map's
// values are byte slices.
//
// Implements:
//
// int rados_striper_getxattrs(rados_striper_t striper,
// const char *oid,
// rados_xattrs_iter_t *iter);
func (s *Striper) ListXattrs(soid string) (map[string][]byte, error) {
csoid := C.CString(soid)
defer C.free(unsafe.Pointer(csoid))
var it C.rados_xattrs_iter_t
ret := C.rados_striper_getxattrs(s.striper, csoid, &it)
if ret < 0 {
return nil, getError(ret)
}
defer C.rados_striper_getxattrs_end(it)
m := make(map[string][]byte)
for {
xname, xvalue, err := getXattrsNext(it)
if err == errStopIteration {
break
}
if err != nil {
return nil, err
}
m[xname] = xvalue
}
return m, nil
}