]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
get_xattr() can return more than 4KB 380/head
authorLoic Dachary <loic@dachary.org>
Tue, 25 Jun 2013 14:10:02 +0000 (16:10 +0200)
committerLoic Dachary <loic@dachary.org>
Tue, 25 Jun 2013 14:10:22 +0000 (16:10 +0200)
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 <loic@dachary.org>
src/pybind/rados.py

index 6e6d14ea1dd621c6466fb61631d597bb8984d416..13badc997f95c56d25862f5785c4609b069b5d3e 100644 (file)
@@ -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):