]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: add an interface to invalidate cached data
authorJosh Durgin <josh.durgin@inktank.com>
Thu, 24 Apr 2014 21:47:24 +0000 (14:47 -0700)
committerJosh Durgin <josh.durgin@inktank.com>
Sat, 9 Aug 2014 23:34:00 +0000 (16:34 -0700)
This is useful for qemu to guarantee live migration with caching is
safe, by invalidating the cache on the destination before starting it.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
(cherry picked from commit 5d340d26dd70192eb0e4f3f240e3433fb9a24154)

src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/internal.cc
src/librbd/internal.h
src/librbd/librbd.cc
src/pybind/rbd.py
src/test/pybind/test_rbd.py

index 5be82033390e81f335a01c962c765a1708bfb904..1e87af9d1944f997d34329fb5629baa8bba06457 100644 (file)
@@ -39,6 +39,7 @@ extern "C" {
 
 #define LIBRBD_SUPPORTS_WATCH 0
 #define LIBRBD_SUPPORTS_AIO_FLUSH 1
+#define LIBRBD_SUPPORTS_INVALIDATE 1
 
 typedef void *rbd_snap_t;
 typedef void *rbd_image_t;
@@ -376,6 +377,14 @@ int rbd_flush(rbd_image_t image);
  */
 int rbd_aio_flush(rbd_image_t image, rbd_completion_t c);
 
+/**
+ * Drop any cached data for an image
+ *
+ * @param image the image to invalidate cached data for
+ * @returns 0 on success, negative error code on failure
+ */
+int rbd_invalidate_cache(rbd_image_t image);
+
 #ifdef __cplusplus
 }
 #endif
index 697fc6ccc41e9ce1c3fe3bccbfd2b9847c613420..caf61a65f706918baa17040985141f6c05023de8 100644 (file)
@@ -216,6 +216,14 @@ public:
    */
   int aio_flush(RBD::AioCompletion *c);
 
+  /**
+   * Drop any cached data for an image
+   *
+   * @param image the image to invalidate cached data for
+   * @returns 0 on success, negative error code on failure
+   */
+  int invalidate_cache();
+
 private:
   friend class RBD;
 
index b13ff97cd9aeb095f14b0624deee18968ce49564..e56ef0897f48c3ddf5e7766f01f95a7592a3a588 100644 (file)
@@ -2881,6 +2881,19 @@ reprotect_and_return_err:
     return r;
   }
 
+  int invalidate_cache(ImageCtx *ictx)
+  {
+    CephContext *cct = ictx->cct;
+    ldout(cct, 20) << "invalidate_cache " << ictx << dendl;
+
+    int r = ictx_check(ictx);
+    if (r < 0)
+      return r;
+
+    RWLock::WLocker l(ictx->md_lock);
+    return ictx->invalidate_cache();
+  }
+
   int aio_write(ImageCtx *ictx, uint64_t off, size_t len, const char *buf,
                AioCompletion *c)
   {
index 43458886b430b3f423d4b22a4db890d1f5410c5a..6fb1af4617573566e9cec061125c85ca7fd34263 100644 (file)
@@ -188,6 +188,7 @@ namespace librbd {
   int aio_flush(ImageCtx *ictx, AioCompletion *c);
   int flush(ImageCtx *ictx);
   int _flush(ImageCtx *ictx);
+  int invalidate_cache(ImageCtx *ictx);
 
   ssize_t handle_sparse_read(CephContext *cct,
                             ceph::bufferlist data_bl,
index cad0c5eb17294400d9972736774090c9a8c260e3..658f24b85ca794a11e7c2d4a3f98044c2f95805d 100644 (file)
@@ -514,6 +514,12 @@ namespace librbd {
     return librbd::aio_flush(ictx, (librbd::AioCompletion *)c->pc);
   }
 
+  int Image::invalidate_cache()
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::invalidate_cache(ictx);
+  }
+
 } // namespace librbd
 
 extern "C" void rbd_version(int *major, int *minor, int *extra)
@@ -1130,6 +1136,12 @@ extern "C" int rbd_aio_flush(rbd_image_t image, rbd_completion_t c)
   return librbd::aio_flush(ictx, (librbd::AioCompletion *)comp->pc);
 }
 
+extern "C" int rbd_invalidate_cache(rbd_image_t image)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  return librbd::invalidate_cache(ictx);
+}
+
 extern "C" int rbd_aio_is_complete(rbd_completion_t c)
 {
   librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
index bf075769d8be07d54ae2f1ae624e0b9bb0ad1928..ab093ce30abd764ee4250764e6515d103d8a18c3 100644 (file)
@@ -750,6 +750,14 @@ written." % (self.name, ret, length))
         if ret < 0:
             raise make_ex(ret, 'error flushing image')
 
+    def invalidate_cache(self):
+        """
+        Drop any cached data for the image.
+        """
+        ret = self.librbd.rbd_invalidate_cache(self.image)
+        if ret < 0:
+            raise make_ex(ret, 'error invalidating cache')
+
     def stripe_unit(self):
         """
         Returns the stripe unit used for the image.
index f45391835183d764200d4dfef513015ebab4c711..11591820641d5c3e5ec4903760c8b28a43aeddde 100644 (file)
@@ -229,6 +229,12 @@ class TestImage(object):
         self.image.close()
         remove_image()
 
+    def test_invalidate_cache(self):
+        self.image.write('abc', 0)
+        eq('abc', self.image.read(0, 3))
+        self.image.invalidate_cache()
+        eq('abc', self.image.read(0, 3))
+
     def test_stat(self):
         info = self.image.stat()
         check_stat(info, IMG_SIZE, IMG_ORDER)