]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind/rbd: add new write_zeroes/aio_write_zeroes API methods
authorJason Dillaman <dillaman@redhat.com>
Tue, 30 Jun 2020 15:20:31 +0000 (11:20 -0400)
committerJason Dillaman <dillaman@redhat.com>
Wed, 22 Jul 2020 19:14:49 +0000 (15:14 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit c27d744a339d3644b756ee496445909f63c8903e)
(cherry picked from commit 6a884184b680b89e2b46ad001651e07e58514eb0)

src/pybind/rbd/rbd.pyx
src/test/pybind/test_rbd.py

index 8789c9d48af1cb869694914e4654da1284a2714d..3ce8ed4463b9d659ef7ec391676fa003d3804c40 100644 (file)
@@ -451,6 +451,8 @@ cdef extern from "rbd/librbd.h" nogil:
     ssize_t rbd_write2(rbd_image_t image, uint64_t ofs, size_t len,
                        const char *buf, int op_flags)
     int rbd_discard(rbd_image_t image, uint64_t ofs, uint64_t len)
+    int rbd_write_zeroes(rbd_image_t image, uint64_t ofs, uint64_t len,
+                         int zero_flags, int op_flags)
     int rbd_copy3(rbd_image_t src, rados_ioctx_t dest_io_ctx,
                   const char *destname, rbd_image_options_t dest_opts)
     int rbd_deep_copy(rbd_image_t src, rados_ioctx_t dest_io_ctx,
@@ -552,6 +554,8 @@ cdef extern from "rbd/librbd.h" nogil:
                       char *buf, rbd_completion_t c, int op_flags)
     int rbd_aio_discard(rbd_image_t image, uint64_t off, uint64_t len,
                         rbd_completion_t c)
+    int rbd_aio_write_zeroes(rbd_image_t image, uint64_t off, uint64_t len,
+                             rbd_completion_t c, int zero_flags, int op_flags)
 
     int rbd_aio_create_completion(void *cb_arg, rbd_callback_t complete_cb,
                                   rbd_completion_t *c)
@@ -3915,6 +3919,23 @@ written." % (self.name, ret, length))
             msg = 'error discarding region %d~%d' % (offset, length)
             raise make_ex(ret, msg)
 
+    @requires_not_closed
+    def write_zeroes(self, offset, length, zero_flags = 0):
+        """
+        Zero the range from the image. By default it will attempt to
+        discard/unmap as much space as possible but any unaligned
+        extent segments will still be zeroed.
+        """
+        cdef:
+            uint64_t _offset = offset, _length = length
+            int _zero_flags = zero_flags
+        with nogil:
+            ret = rbd_write_zeroes(self.image, _offset, _length,
+                                   _zero_flags, 0)
+        if ret < 0:
+            msg = 'error zeroing region %d~%d' % (offset, length)
+            raise make_ex(ret, msg)
+
     @requires_not_closed
     def flush(self):
         """
@@ -4536,6 +4557,34 @@ written." % (self.name, ret, length))
 
         return completion
 
+    @requires_not_closed
+    def aio_write_zeroes(self, offset, length, oncomplete, zero_flags = 0):
+        """
+        Asynchronously Zero the range from the image. By default it will attempt
+        to discard/unmap as much space as possible but any unaligned extent
+        segments will still be zeroed.
+        """
+        cdef:
+            uint64_t _offset = offset
+            size_t _length = length
+            int _zero_flags = zero_flags
+            Completion completion
+
+        completion = self.__get_completion(oncomplete)
+        try:
+            completion.__persist()
+            with nogil:
+                ret = rbd_aio_write_zeroes(self.image, _offset, _length,
+                                           completion.rbd_comp, _zero_flags, 0)
+            if ret < 0:
+                raise make_ex(ret, 'error zeroing %s %ld~%ld' %
+                              (self.name, offset, length))
+        except:
+            completion.__unpersist()
+            raise
+
+        return completion
+
     @requires_not_closed
     def aio_flush(self, oncomplete):
         """
index eb07eb7c6c8d4f96e192f3831a6d303171ac7a9a..0fe72e9693f55c1ec785693db6cb5c62beefe554 100644 (file)
@@ -551,6 +551,12 @@ class TestImage(object):
         self.image.write(data, 0, LIBRADOS_OP_FLAG_FADVISE_DONTNEED)
         self.image.write(data, 0, LIBRADOS_OP_FLAG_FADVISE_NOCACHE)
 
+    def test_write_zeroes(self):
+        data = rand_data(256)
+        self.image.write(data, 0)
+        self.image.write_zeroes(0, 256)
+        eq(self.image.read(256, 256), b'\0' * 256)
+
     def test_read(self):
         data = self.image.read(0, 20)
         eq(data, b'\0' * 20)
@@ -1079,6 +1085,20 @@ class TestImage(object):
         eq(sys.getrefcount(comp), 2)
         eq(self.image.read(256, 256), b'\0' * 256)
 
+    def test_aio_write_zeroes(self):
+        retval = [None]
+        def cb(comp):
+            retval[0] = comp.get_return_value()
+
+        data = rand_data(256)
+        self.image.write(data, 0)
+        comp = self.image.aio_write_zeroes(0, 256, cb)
+        comp.wait_for_complete_and_cb()
+        eq(retval[0], 0)
+        eq(comp.get_return_value(), 0)
+        eq(sys.getrefcount(comp), 2)
+        eq(self.image.read(256, 256), b'\0' * 256)
+
     def test_aio_flush(self):
         retval = [None]
         def cb(comp):