From: Kotresh HR Date: Wed, 4 Mar 2020 12:16:24 +0000 (+0530) Subject: libcephfs/pybind: Add rewinddir, telldir, seekdir X-Git-Tag: v16.1.0~2070^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=626febcefb878623195d9d6aa29b9975ed633cdd;p=ceph.git libcephfs/pybind: Add rewinddir, telldir, seekdir Fixes: https://tracker.ceph.com/issues/44171 Signed-off-by: Kotresh HR --- diff --git a/src/pybind/cephfs/cephfs.pyx b/src/pybind/cephfs/cephfs.pyx index 146a195e51a..40ecd565911 100644 --- a/src/pybind/cephfs/cephfs.pyx +++ b/src/pybind/cephfs/cephfs.pyx @@ -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. diff --git a/src/test/pybind/test_cephfs.py b/src/test/pybind/test_cephfs.py index 97e8c5c8ac9..b135d5dfbc3 100644 --- a/src/test/pybind/test_cephfs.py +++ b/src/test/pybind/test_cephfs.py @@ -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)