]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind: fix libcephfs getxattr 7901/head
authorJohn Spray <john.spray@redhat.com>
Thu, 3 Mar 2016 13:20:49 +0000 (13:20 +0000)
committerJohn Spray <john.spray@redhat.com>
Mon, 14 Mar 2016 12:32:56 +0000 (12:32 +0000)
The python bindings were expecting a different behaviour
than libcephfs actually has.  On overflow, it doesn't return
the data size, it just gives you -ERANGE.  The python bindings
need to cope with that, and also let you pass in a size param
so that you can handle it.

Signed-off-by: John Spray <john.spray@redhat.com>
src/pybind/cephfs/cephfs.pyx
src/test/pybind/test_cephfs.py

index 712163671b98d0ea5bc5c717bc9aa219960c631b..4f2334b1adb27c1b0a05cd41977b50ed61bbea6c 100644 (file)
@@ -183,6 +183,9 @@ class LibCephFSStateError(Error):
     pass
 
 
+class OutOfRange(Error):
+    pass
+
 cdef errno_to_exception =  {
     errno.EPERM     : PermissionError,
     errno.ENOENT    : ObjectNotFound,
@@ -192,6 +195,7 @@ cdef errno_to_exception =  {
     errno.ENODATA   : NoData,
     errno.EINVAL    : InvalidValue,
     errno.EOPNOTSUPP: OperationNotSupported,
+    errno.ERANGE    : OutOfRange,
 }
 
 
@@ -689,7 +693,7 @@ cdef class LibCephFS(object):
             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')
@@ -699,7 +703,7 @@ cdef class LibCephFS(object):
             char* _path = path
             char* _name = name
 
-            size_t ret_length = 255
+            size_t ret_length = size
             char *ret_buf = NULL
 
         try:
@@ -711,14 +715,6 @@ cdef class LibCephFS(object):
             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)
index 77cd31bf994675aa4ed956d57079dd428f631ee6..6ed18108b61f289616621ee5142ac0b08f31e529 100644 (file)
@@ -86,13 +86,11 @@ def test_xattr():
 
     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)