From 3016f46f53d4701ead1e30f2a3d67a39ca0050f8 Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Tue, 25 Jun 2013 16:10:02 +0200 Subject: [PATCH] get_xattr() can return more than 4KB Instead of failing if the attribute to be returned is larger than 4KB, double the buffer size each time librados.rados_getxattr returns -errno.ERANGE and try again. http://tracker.ceph.com/issues/4907 fixes #4907 Signed-off-by: Loic Dachary --- src/pybind/rados.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/pybind/rados.py b/src/pybind/rados.py index 6e6d14ea1dd6..13badc997f95 100644 --- a/src/pybind/rados.py +++ b/src/pybind/rados.py @@ -1328,12 +1328,17 @@ written." % (self.name, ret, length)) if not isinstance(xattr_name, str): raise TypeError('xattr_name must be a string') ret_length = 4096 - ret_buf = create_string_buffer(ret_length) - ret = run_in_thread(self.librados.rados_getxattr, - (self.io, c_char_p(key), c_char_p(xattr_name), - ret_buf, c_size_t(ret_length))) - if ret < 0: - raise make_ex(ret, "Failed to get xattr %r" % xattr_name) + while ret_length < 4096 * 1024 * 1024: + ret_buf = create_string_buffer(ret_length) + ret = run_in_thread(self.librados.rados_getxattr, + (self.io, c_char_p(key), c_char_p(xattr_name), + ret_buf, c_size_t(ret_length))) + if (ret == -errno.ERANGE): + ret_length *= 2 + elif ret < 0: + raise make_ex(ret, "Failed to get xattr %r" % xattr_name) + else: + break return ctypes.string_at(ret_buf, ret) def get_xattrs(self, oid): -- 2.47.3