]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: add update_features to librbd API
authorJason Dillaman <dillaman@redhat.com>
Thu, 12 Mar 2015 02:37:46 +0000 (22:37 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 6 Apr 2015 17:14:34 +0000 (13:14 -0400)
Allow mutable features to be enabled / disabled.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/internal.cc
src/librbd/internal.h
src/librbd/librbd.cc
src/tracing/librbd.tp

index 506be78766130adf50c22253f36dae49937665cb..9e54b318a07fabb7b945580d55990470699e5d7a 100644 (file)
@@ -31,7 +31,7 @@ extern "C" {
 
 #define LIBRBD_VER_MAJOR 0
 #define LIBRBD_VER_MINOR 1
-#define LIBRBD_VER_EXTRA 9
+#define LIBRBD_VER_EXTRA 10
 
 #define LIBRBD_VERSION(maj, min, extra) ((maj << 16) + (min << 8) + extra)
 
@@ -148,6 +148,8 @@ CEPH_RBD_API int rbd_stat(rbd_image_t image, rbd_image_info_t *info,
 CEPH_RBD_API int rbd_get_old_format(rbd_image_t image, uint8_t *old);
 CEPH_RBD_API int rbd_get_size(rbd_image_t image, uint64_t *size);
 CEPH_RBD_API int rbd_get_features(rbd_image_t image, uint64_t *features);
+CEPH_RBD_API int rbd_update_features(rbd_image_t image, uint64_t features,
+                                     uint8_t enabled);
 CEPH_RBD_API int rbd_get_stripe_unit(rbd_image_t image, uint64_t *stripe_unit);
 CEPH_RBD_API int rbd_get_stripe_count(rbd_image_t image,
                                       uint64_t *stripe_count);
index a5a7bae045d4b89d18d506fc96be342218380b49..52c713b58bc69702f034b916439d66ef7a336c2f 100644 (file)
@@ -116,6 +116,7 @@ public:
   int old_format(uint8_t *old);
   int size(uint64_t *size);
   int features(uint64_t *features);
+  int update_features(uint64_t features, bool enabled);
   int overlap(uint64_t *overlap);
   int get_flags(uint64_t *flags);
 
index bf2401019e2ff7ee34943bb4b9f624b4a9a3cee5..ce70350480a9afec52c737cd8f3bb1a1746b7045 100644 (file)
@@ -14,6 +14,7 @@
 #include "include/stringify.h"
 
 #include "cls/rbd/cls_rbd.h"
+#include "cls/rbd/cls_rbd_client.h"
 
 #include "librbd/AioCompletion.h"
 #include "librbd/AioRequest.h"
@@ -1346,6 +1347,67 @@ reprotect_and_return_err:
     return 0;
   }
 
+  int update_features(ImageCtx *ictx, uint64_t features, bool enabled)
+  {
+    int r = ictx_check(ictx);
+    if (r < 0) {
+      return r;
+    }
+
+    CephContext *cct = ictx->cct;
+    if (ictx->read_only) {
+      return -EROFS;
+    } else if (ictx->old_format) {
+      lderr(cct) << "old-format images do not support features" << dendl;
+      return -EINVAL;
+    }
+
+    if ((features & RBD_FEATURES_MUTABLE) != features) {
+      lderr(cct) << "cannot update immutable features" << dendl;
+      return -EINVAL;
+    } else if (features == 0) {
+      lderr(cct) << "update requires at least one feature" << dendl;
+      return -EINVAL;
+    }
+
+    RWLock::RLocker l(ictx->snap_lock);
+    uint64_t new_features = ictx->features | features;
+    if (!enabled) {
+      new_features = ictx->features & ~features;
+    }
+
+    if (ictx->features == new_features) {
+      return 0;
+    }
+
+    uint64_t mask = features;
+    if ((features & RBD_FEATURE_EXCLUSIVE_LOCK) != 0 && !enabled) {
+      if ((new_features & RBD_FEATURE_OBJECT_MAP) != 0) {
+        lderr(cct) << "cannot disable exclusive lock" << dendl;
+        return -EINVAL;
+      }
+      mask |= RBD_FEATURE_OBJECT_MAP;
+    } else if ((features & RBD_FEATURE_OBJECT_MAP) != 0 && enabled) {
+      if ((new_features & RBD_FEATURE_EXCLUSIVE_LOCK) == 0) {
+        lderr(cct) << "cannot enable object map" << dendl;
+        return -EINVAL;
+      }
+      mask |= RBD_FEATURE_EXCLUSIVE_LOCK;
+    }
+
+    ldout(cct, 10) << "update_features: features=" << new_features << ", mask="
+                   << mask << dendl;
+    r = librbd::cls_client::set_features(&ictx->md_ctx, ictx->header_oid,
+                                         new_features, mask);
+    if (r < 0) {
+      lderr(cct) << "failed to update features: " << cpp_strerror(r)
+                 << dendl;
+    }
+
+    notify_change(ictx->md_ctx, ictx->header_oid, ictx);
+    return 0;
+  }
+
   int get_overlap(ImageCtx *ictx, uint64_t *overlap)
   {
     int r = ictx_check(ictx);
index 9d583fe943265dc0c5b215db0c9a0417644f8119..aa472a98af3ecf40c6375603525ba4d6989e921b 100644 (file)
@@ -100,6 +100,7 @@ namespace librbd {
   int get_old_format(ImageCtx *ictx, uint8_t *old);
   int get_size(ImageCtx *ictx, uint64_t *size);
   int get_features(ImageCtx *ictx, uint64_t *features);
+  int update_features(ImageCtx *ictx, uint64_t features, bool enabled);
   int get_overlap(ImageCtx *ictx, uint64_t *overlap);
   int get_parent_info(ImageCtx *ictx, std::string *parent_pool_name,
                      std::string *parent_name, std::string *parent_snap_name);
index cdba2cc3655d4860ee5017167032122fc6d25bfd..1143a1f6210142a08ecd5f1d0af253e19e67bd43 100644 (file)
@@ -322,6 +322,15 @@ namespace librbd {
     return r;
   }
 
+  int Image::update_features(uint64_t features, bool enabled)
+  {
+    ImageCtx *ictx = reinterpret_cast<ImageCtx *>(ctx);
+    tracepoint(librbd, update_features_enter, ictx, features, enabled);
+    int r = librbd::update_features(ictx, features, enabled);
+    tracepoint(librbd, update_features_exit, r);
+    return r;
+  }
+
   uint64_t Image::get_stripe_unit() const
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
@@ -1159,6 +1168,17 @@ extern "C" int rbd_get_features(rbd_image_t image, uint64_t *features)
   return r;
 }
 
+extern "C" int rbd_update_features(rbd_image_t image, uint64_t features,
+                                  uint8_t enabled)
+{
+  librbd::ImageCtx *ictx = reinterpret_cast<librbd::ImageCtx *>(image);
+  bool features_enabled = enabled != 0;
+  tracepoint(librbd, update_features_enter, ictx, features, features_enabled);
+  int r = librbd::update_features(ictx, features, features_enabled);
+  tracepoint(librbd, update_features_exit, r);
+  return r;
+}
+
 extern "C" int rbd_get_stripe_unit(rbd_image_t image, uint64_t *stripe_unit)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
index bf2c6f4f0dbd8b9724df65746e44a8fa54635a7a..b7d104591ce986f0c086bdb72a779b3f22f1c059 100644 (file)
@@ -1431,6 +1431,26 @@ TRACEPOINT_EVENT(librbd, get_features_exit,
     )
 )
 
+TRACEPOINT_EVENT(librbd, update_features_enter,
+    TP_ARGS(
+        void*, imagectx,
+        uint64_t, features,
+        char, enabled),
+    TP_FIELDS(
+        ctf_integer_hex(void*, imagectx, imagectx)
+        ctf_integer(uint64_t, features, features)
+       ctf_integer(char, enabled, enabled)
+    )
+)
+
+TRACEPOINT_EVENT(librbd, update_features_exit,
+    TP_ARGS(
+        int, retval),
+    TP_FIELDS(
+        ctf_integer(int, retval, retval)
+    )
+)
+
 TRACEPOINT_EVENT(librbd, get_size_enter,
     TP_ARGS(
         void*, imagectx,