pass
+class OutOfRange(Error):
+ pass
+
cdef errno_to_exception = {
errno.EPERM : PermissionError,
errno.ENOENT : ObjectNotFound,
errno.ENODATA : NoData,
errno.EINVAL : InvalidValue,
errno.EOPNOTSUPP: OperationNotSupported,
+ errno.ERANGE : OutOfRange,
}
raise make_ex(ret, "error in write")
return ret
- def getxattr(self, path, name):
+ def getxattr(self, path, name, size=255):
self.require_state("mounted")
path = cstr(path, 'path')
char* _path = path
char* _name = name
- size_t ret_length = 255
+ size_t ret_length = size
char *ret_buf = NULL
try:
if ret < 0:
raise make_ex(ret, "error in getxattr")
- if ret > ret_length:
- ret_buf = <char *>realloc_chk(ret_buf, ret)
- with nogil:
- ret = ceph_getxattr(self.cluster, _path, _name, ret_buf,
- ret)
- if ret < 0:
- raise make_ex(ret, "error in getxattr")
-
return ret_buf[:ret]
finally:
free(ret_buf)
cephfs.setxattr("/", "user.big", "x" * 300, 0)
- # FIXME: Python bindings expect ceph_getxattr to return the attr size,
- # even if it's longer than the requested size. It actually returns
- # -ERANGE.
- # What *should* happen is that the cephfs pythno bindings should
- # either accept a size field, or they should increase the buffer size
- # until they can accomodate the true size of the buffer.
- # assert_equal(300, len(cephfs.getxattr("/", "user.big")))
+ # Default size is 255, get ERANGE
+ assert_raises(libcephfs.OutOfRange, cephfs.getxattr, "/", "user.big")
+
+ # Pass explicit size, and we'll get the value
+ assert_equal(300, len(cephfs.getxattr("/", "user.big", 300)))
@with_setup(setup_test)