]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
libcephfs/pybind: Add rewinddir, telldir, seekdir
authorKotresh HR <khiremat@redhat.com>
Wed, 4 Mar 2020 12:16:24 +0000 (17:46 +0530)
committerKotresh HR <khiremat@redhat.com>
Thu, 21 May 2020 11:31:24 +0000 (17:01 +0530)
Fixes: https://tracker.ceph.com/issues/44171
Signed-off-by: Kotresh HR <khiremat@redhat.com>
src/pybind/cephfs/cephfs.pyx
src/test/pybind/test_cephfs.py

index 146a195e51a3702ca0039ad9785ffca46cb44cd3..40ecd565911859474877a60cb1d118c9a5cbc8d2 100644 (file)
@@ -198,6 +198,8 @@ cdef extern from "cephfs/libcephfs.h" nogil:
     int ceph_closedir(ceph_mount_info *cmount, ceph_dir_result *dirp)
     int ceph_opendir(ceph_mount_info *cmount, const char *name, ceph_dir_result **dirpp)
     void ceph_rewinddir(ceph_mount_info *cmount, ceph_dir_result *dirp)
+    int64_t ceph_telldir(ceph_mount_info *cmount, ceph_dir_result *dirp)
+    void ceph_seekdir(ceph_mount_info *cmount, ceph_dir_result *dirp, int64_t offset)
     int ceph_chdir(ceph_mount_info *cmount, const char *path)
     dirent * ceph_readdir(ceph_mount_info *cmount, ceph_dir_result *dirp)
     int ceph_rmdir(ceph_mount_info *cmount, const char *path)
@@ -426,6 +428,34 @@ cdef class DirResult(object):
                 raise make_ex(ret, "closedir failed")
             self.handle = NULL
 
+    def rewinddir(self):
+        if not self.handle:
+            raise make_ex(errno.EBADF, "dir is not open")
+        self.lib.require_state("mounted")
+        with nogil:
+            ceph_rewinddir(self.lib.cluster, self.handle)
+
+    def telldir(self):
+        if not self.handle:
+            raise make_ex(errno.EBADF, "dir is not open")
+        self.lib.require_state("mounted")
+        with nogil:
+            ret = ceph_telldir(self.lib.cluster, self.handle)
+        if ret < 0:
+            raise make_ex(ret, "telldir failed")
+        return ret
+
+    def seekdir(self, offset):
+        if not self.handle:
+            raise make_ex(errno.EBADF, "dir is not open")
+        if not isinstance(offset, int):
+            raise TypeError('offset must be an int')
+        self.lib.require_state("mounted")
+        cdef int64_t _offset = offset
+        with nogil:
+            ceph_seekdir(self.lib.cluster, self.handle, _offset)
+
+
 def cstr(val, name, encoding="utf-8", opt=False):
     """
     Create a byte string from a Python string
@@ -1034,6 +1064,37 @@ cdef class LibCephFS(object):
 
         return handle.close()
 
+    def rewinddir(self, DirResult handle):
+        """
+        Rewind the directory stream to the beginning of the directory.
+
+        :param handle: the open directory stream handle
+        """
+        return handle.rewinddir()
+
+    def telldir(self, DirResult handle):
+        """
+        Get the current position of a directory stream.
+
+        :param handle: the open directory stream handle
+        :return value: The position of the directory stream. Note that the offsets
+                       returned by ceph_telldir do not have a particular order (cannot
+                       be compared with inequality).
+        """
+        return handle.telldir()
+
+    def seekdir(self, DirResult handle, offset):
+        """
+        Move the directory stream to a position specified by the given offset.
+
+        :param handle: the open directory stream handle
+        :param offset: the position to move the directory stream to. This offset should be
+                       a value returned by telldir. Note that this value does not refer to
+                       the nth entry in a directory, and can not be manipulated with plus
+                       or minus.
+        """
+        return handle.seekdir(offset)
+
     def mkdir(self, path, mode):
         """
         Create a directory.
index 97e8c5c8ac9caacddc29dd1ed48f9e19185dae39..b135d5dfbc338623df35900f2b1c294aae958048 100644 (file)
@@ -598,3 +598,34 @@ def test_setuuid():
 def test_session_timeout():
     assert_raises(TypeError, cephfs.set_session_timeout, "300")
     cephfs.set_session_timeout(300)
+
+@with_setup(setup_test)
+def test_readdirops():
+    cephfs.chdir(b"/")
+    dirs = [b"dir-1", b"dir-2", b"dir-3"]
+    for i in dirs:
+        cephfs.mkdir(i, 0o755)
+    handler = cephfs.opendir(b"/")
+    d1 = cephfs.readdir(handler)
+    d2 = cephfs.readdir(handler)
+    d3 = cephfs.readdir(handler)
+    offset_d4 = cephfs.telldir(handler)
+    d4 = cephfs.readdir(handler)
+    cephfs.rewinddir(handler)
+    d = cephfs.readdir(handler)
+    assert_equal(d.d_name, d1.d_name)
+    cephfs.seekdir(handler, offset_d4)
+    d = cephfs.readdir(handler)
+    assert_equal(d.d_name, d4.d_name)
+    dirs += [b".", b".."]
+    cephfs.rewinddir(handler)
+    d = cephfs.readdir(handler)
+    while d:
+        assert(d.d_name in dirs)
+        dirs.remove(d.d_name)
+        d = cephfs.readdir(handler)
+    assert(len(dirs) == 0)
+    dirs = [b"/dir-1", b"/dir-2", b"/dir-3"]
+    for i in dirs:
+        cephfs.rmdir(i)
+    cephfs.closedir(handler)