]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: differentiate between R/O vs R/W RBD features
authorJason Dillaman <dillaman@redhat.com>
Mon, 3 Nov 2014 21:51:06 +0000 (16:51 -0500)
committerJason Dillaman <dillaman@redhat.com>
Tue, 13 Jan 2015 01:02:25 +0000 (20:02 -0500)
The new RBD exclusive lock feature should be treated as a
feature that is only applied when the image is opened in
R/W mode.

Older clients will need to handle the updated
cls_rbd::get_features method in order to properly determine
the incompatible features for an image depending on the
current mode.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/cls/rbd/cls_rbd.cc
src/cls/rbd/cls_rbd_client.cc
src/cls/rbd/cls_rbd_client.h
src/include/rbd/features.h
src/librbd/internal.cc
src/test/cls_rbd/test_cls_rbd.cc

index 68d960627125f47c325f91a0a39cc5d04d5ec331..866823f024ba9cfd310a2e7e250de617cf645d86 100644 (file)
@@ -282,10 +282,14 @@ int create(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
 int get_features(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
 {
   uint64_t features, snap_id;
+  bool read_only = false;
 
   bufferlist::iterator iter = in->begin();
   try {
     ::decode(snap_id, iter);
+    if (!iter.end()) {
+      ::decode(read_only, iter);
+    }
   } catch (const buffer::error &err) {
     return -EINVAL;
   }
@@ -309,7 +313,8 @@ int get_features(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
     features = snap.features;
   }
 
-  uint64_t incompatible = features & RBD_FEATURES_INCOMPATIBLE;
+  uint64_t incompatible = (read_only ? features & RBD_FEATURES_INCOMPATIBLE :
+                                      features & RBD_FEATURES_RW_INCOMPATIBLE);
   ::encode(features, *out);
   ::encode(incompatible, *out);
 
index 7bc596a3ec601e90b0fec773ffc61f565f32080f..8bbb1ccc2c427cad3d4c5f6304c3e872bd1acc02 100644 (file)
@@ -47,7 +47,7 @@ namespace librbd {
     }
 
     int get_mutable_metadata(librados::IoCtx *ioctx, const std::string &oid,
-                            uint64_t *size, uint64_t *features,
+                            bool read_only, uint64_t *size, uint64_t *features,
                             uint64_t *incompatible_features,
                             map<rados::cls::lock::locker_id_t,
                                 rados::cls::lock::locker_info_t> *lockers,
@@ -68,11 +68,15 @@ namespace librbd {
       bufferlist sizebl, featuresbl, parentbl, empty;
       snapid_t snap = CEPH_NOSNAP;
       ::encode(snap, sizebl);
-      ::encode(snap, featuresbl);
-      ::encode(snap, parentbl);
       op.exec("rbd", "get_size", sizebl);
+
+      ::encode(snap, featuresbl);
+      ::encode(read_only, featuresbl);
       op.exec("rbd", "get_features", featuresbl);
+
       op.exec("rbd", "get_snapcontext", empty);
+
+      ::encode(snap, parentbl);
       op.exec("rbd", "get_parent", parentbl);
       rados::cls::lock::get_lock_info_start(&op, RBD_LOCK_NAME);
 
index 34cc45b839099e31155ababb9b251108731ac06d..10073e578c4886d42f0520348d2c9a53a0d3256d 100644 (file)
@@ -19,7 +19,7 @@ namespace librbd {
     int get_immutable_metadata(librados::IoCtx *ioctx, const std::string &oid,
                               std::string *object_prefix, uint8_t *order);
     int get_mutable_metadata(librados::IoCtx *ioctx, const std::string &oid,
-                            uint64_t *size, uint64_t *features,
+                            bool read_only, uint64_t *size, uint64_t *features,
                             uint64_t *incompatible_features,
                             map<rados::cls::lock::locker_id_t,
                                 rados::cls::lock::locker_info_t> *lockers,
index 9b28b5749953693fe22d430030fa67526260bf0d..7e35baac348e85113f8494e97ac5654dfba8f61d 100644 (file)
@@ -5,9 +5,14 @@
 #define RBD_FEATURE_STRIPINGV2         (1<<1)
 #define RBD_FEATURE_EXCLUSIVE_LOCK     (1<<2)
 
-#define RBD_FEATURES_INCOMPATIBLE (RBD_FEATURE_LAYERING|RBD_FEATURE_STRIPINGV2|\
-                                   RBD_FEATURE_EXCLUSIVE_LOCK)
-#define RBD_FEATURES_ALL          (RBD_FEATURE_LAYERING|RBD_FEATURE_STRIPINGV2|\
-                                   RBD_FEATURE_EXCLUSIVE_LOCK)
+#define RBD_FEATURES_INCOMPATIBLE      (RBD_FEATURE_LAYERING |      \
+                                        RBD_FEATURE_STRIPINGV2)
+
+#define RBD_FEATURES_RW_INCOMPATIBLE   (RBD_FEATURES_INCOMPATIBLE | \
+                                        RBD_FEATURE_EXCLUSIVE_LOCK)
+
+#define RBD_FEATURES_ALL               (RBD_FEATURE_LAYERING |      \
+                                        RBD_FEATURE_STRIPINGV2 |    \
+                                        RBD_FEATURE_EXCLUSIVE_LOCK)
 
 #endif
index 7794d986f261cf5094f6e8f21e80485bfb5bfb61..e645fd883189272ad5667fb4f4723b164460f971 100644 (file)
@@ -1849,7 +1849,9 @@ reprotect_and_return_err:
        } else {
          do {
            uint64_t incompatible_features;
+           bool read_only = ictx->read_only || ictx->snap_id != CEPH_NOSNAP;
            r = cls_client::get_mutable_metadata(&ictx->md_ctx, ictx->header_oid,
+                                                read_only,
                                                 &ictx->size, &ictx->features,
                                                 &incompatible_features,
                                                 &ictx->lockers,
index 31d7df0cd8016d3e473e221ac8ab4d231a9c1a4c..bef5fe141b5460720e0f559da8435d6c355e573b 100644 (file)
@@ -48,6 +48,7 @@ using ::librbd::cls_client::set_protection_status;
 using ::librbd::cls_client::get_stripe_unit_count;
 using ::librbd::cls_client::set_stripe_unit_count;
 using ::librbd::cls_client::old_snapshot_add;
+using ::librbd::cls_client::get_mutable_metadata;
 
 static char *random_buf(size_t len)
 {
@@ -887,3 +888,38 @@ TEST_F(TestClsRbd, stripingv2)
 
   ioctx.close();
 }
+
+TEST_F(TestClsRbd, get_mutable_metadata_features)
+{
+  librados::IoCtx ioctx;
+  ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx));
+
+  string oid = get_temp_image_name();
+  ASSERT_EQ(0, create_image(&ioctx, oid, 10, 22, RBD_FEATURE_EXCLUSIVE_LOCK,
+                            oid));
+
+  uint64_t size, features, incompatible_features;
+  std::map<rados::cls::lock::locker_id_t,
+           rados::cls::lock::locker_info_t> lockers;
+  bool exclusive_lock;
+  std::string lock_tag;
+  ::SnapContext snapc;
+  parent_info parent;
+
+  ASSERT_EQ(0, get_mutable_metadata(&ioctx, oid, true, &size, &features,
+                                   &incompatible_features, &lockers,
+                                   &exclusive_lock, &lock_tag, &snapc,
+                                    &parent));
+  ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK), features);
+  ASSERT_EQ(0U, incompatible_features);
+
+  ASSERT_EQ(0, get_mutable_metadata(&ioctx, oid, false, &size, &features,
+                                    &incompatible_features, &lockers,
+                                    &exclusive_lock, &lock_tag, &snapc,
+                                    &parent));
+  ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK), features);
+  ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK),
+           incompatible_features);
+
+  ioctx.close();
+}