rbd feature enable ${IMAGE_NAME} exclusive-lock || break
rbd feature enable ${IMAGE_NAME} journaling || break
rbd feature enable ${IMAGE_NAME} object-map || break
- rbd feature enable ${IMAGE_NAME} fast-diff || break
if is_qemu_running ; then
sleep 60
fi
/// features that will be implicitly enabled
#define RBD_FEATURES_IMPLICIT_ENABLE (RBD_FEATURE_STRIPINGV2 | \
RBD_FEATURE_DATA_POOL | \
+ RBD_FEATURE_FAST_DIFF | \
RBD_FEATURE_OPERATIONS)
/// features that cannot be controlled by the user
lderr(cct) << "cannot update immutable features" << dendl;
return -EINVAL;
}
+
+ bool set_object_map = (features & RBD_FEATURE_OBJECT_MAP) == RBD_FEATURE_OBJECT_MAP;
+ bool set_fast_diff = (features & RBD_FEATURE_FAST_DIFF) == RBD_FEATURE_FAST_DIFF;
+ bool exist_fast_diff = (m_image_ctx.features & RBD_FEATURE_FAST_DIFF) != 0;
+ bool exist_object_map = (m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) != 0;
+
+ if ((enabled && ((set_object_map && !exist_fast_diff) || (set_fast_diff && !exist_object_map)))
+ || (!enabled && (set_object_map && exist_fast_diff))) {
+ features |= (RBD_FEATURE_OBJECT_MAP | RBD_FEATURE_FAST_DIFF);
+ }
+
if (features == 0) {
lderr(cct) << "update requires at least one feature" << dendl;
return -EINVAL;
m_features |= features_set;
m_features &= ~features_clear;
+ if ((m_features & RBD_FEATURE_OBJECT_MAP) == RBD_FEATURE_OBJECT_MAP) {
+ m_features |= RBD_FEATURE_FAST_DIFF;
+ }
+
if (image_options.get(RBD_IMAGE_OPTION_STRIPE_UNIT, &m_stripe_unit) != 0 ||
m_stripe_unit == 0) {
m_stripe_unit = m_cct->_conf->get_val<uint64_t>("rbd_default_stripe_unit");
m_disable_flags |= RBD_FLAG_FAST_DIFF_INVALID;
}
if ((m_features & RBD_FEATURE_OBJECT_MAP) != 0) {
- if ((m_new_features & RBD_FEATURE_FAST_DIFF) != 0) {
- lderr(cct) << "cannot disable object-map. fast-diff must be "
- "disabled before disabling object-map." << dendl;
- *result = -EINVAL;
- break;
- }
m_disable_flags |= RBD_FLAG_OBJECT_MAP_INVALID;
}
} while (false);
m_features_mask |= RBD_FEATURE_EXCLUSIVE_LOCK;
}
if ((m_features & RBD_FEATURE_FAST_DIFF) != 0) {
- if ((m_new_features & RBD_FEATURE_OBJECT_MAP) == 0) {
- lderr(cct) << "cannot enable fast-diff. object-map must be "
- "enabled before enabling fast-diff." << dendl;
- *result = -EINVAL;
- break;
- }
m_enable_flags |= RBD_FLAG_FAST_DIFF_INVALID;
m_features_mask |= (RBD_FEATURE_OBJECT_MAP | RBD_FEATURE_EXCLUSIVE_LOCK);
}
--object-size arg object size in B/K/M [4K <= object size <= 32M]
--image-feature arg image features
[layering(+), exclusive-lock(+*), object-map(+*),
- fast-diff(+*), deep-flatten(+-), journaling(*)]
+ deep-flatten(+-), journaling(*)]
--image-shared shared image
--stripe-unit arg stripe unit in B/K/M
--stripe-count arg stripe count
--object-size arg object size in B/K/M [4K <= object size <= 32M]
--image-feature arg image features
[layering(+), exclusive-lock(+*),
- object-map(+*), fast-diff(+*), deep-flatten(+-),
- journaling(*)]
+ object-map(+*), deep-flatten(+-), journaling(*)]
--image-shared shared image
--stripe-unit arg stripe unit in B/K/M
--stripe-count arg stripe count
--object-size arg object size in B/K/M [4K <= object size <= 32M]
--image-feature arg image features
[layering(+), exclusive-lock(+*), object-map(+*),
- fast-diff(+*), deep-flatten(+-), journaling(*)]
+ deep-flatten(+-), journaling(*)]
--image-shared shared image
--stripe-unit arg stripe unit in B/K/M
--stripe-count arg stripe count
--object-size arg object size in B/K/M [4K <= object size <= 32M]
--image-feature arg image features
[layering(+), exclusive-lock(+*),
- object-map(+*), fast-diff(+*), deep-flatten(+-),
- journaling(*)]
+ object-map(+*), deep-flatten(+-), journaling(*)]
--image-shared shared image
--stripe-unit arg stripe unit in B/K/M
--stripe-count arg stripe count
<image-spec> image specification
(example: [<pool-name>/]<image-name>)
<features> image features
- [exclusive-lock, object-map, fast-diff, journaling]
+ [exclusive-lock, object-map, journaling]
Optional arguments
-p [ --pool ] arg pool name
<image-spec> image specification
(example: [<pool-name>/]<image-name>)
<features> image features
- [exclusive-lock, object-map, fast-diff, journaling]
+ [exclusive-lock, object-map, journaling]
Optional arguments
-p [ --pool ] arg pool name
--object-size arg object size in B/K/M [4K <= object size <= 32M]
--image-feature arg image features
[layering(+), exclusive-lock(+*), object-map(+*),
- fast-diff(+*), deep-flatten(+-), journaling(*)]
+ deep-flatten(+-), journaling(*)]
--image-shared shared image
--stripe-unit arg stripe unit in B/K/M
--stripe-count arg stripe count
ASSERT_EQ(0, image.features(&features));
ASSERT_NE(0U, features & RBD_FEATURE_EXCLUSIVE_LOCK);
- // cannot enable fast diff w/o object map
- ASSERT_EQ(-EINVAL, image.update_features(RBD_FEATURE_FAST_DIFF, true));
- ASSERT_EQ(0, image.update_features(RBD_FEATURE_OBJECT_MAP, true));
+ // can enable fast diff w/o object map
+ ASSERT_EQ(0, image.update_features(RBD_FEATURE_FAST_DIFF, true));
+ ASSERT_EQ(-EINVAL, image.update_features(RBD_FEATURE_OBJECT_MAP, true));
ASSERT_EQ(0, image.features(&features));
ASSERT_NE(0U, features & RBD_FEATURE_OBJECT_MAP);
- uint64_t expected_flags = RBD_FLAG_OBJECT_MAP_INVALID;
+ uint64_t expected_flags = RBD_FLAG_OBJECT_MAP_INVALID |
+ RBD_FLAG_FAST_DIFF_INVALID;
uint64_t flags;
ASSERT_EQ(0, image.get_flags(&flags));
ASSERT_EQ(expected_flags, flags);
ASSERT_EQ(0, image.features(&features));
ASSERT_EQ(0U, features & RBD_FEATURE_OBJECT_MAP);
- ASSERT_EQ(0, image.update_features(RBD_FEATURE_OBJECT_MAP |
- RBD_FEATURE_FAST_DIFF |
- RBD_FEATURE_JOURNALING, true));
-
- expected_flags = RBD_FLAG_OBJECT_MAP_INVALID | RBD_FLAG_FAST_DIFF_INVALID;
- ASSERT_EQ(0, image.get_flags(&flags));
- ASSERT_EQ(expected_flags, flags);
-
- // cannot disable object map w/ fast diff
- ASSERT_EQ(-EINVAL, image.update_features(RBD_FEATURE_OBJECT_MAP, false));
- ASSERT_EQ(0, image.update_features(RBD_FEATURE_FAST_DIFF, false));
+ // can disable object map w/ fast diff
+ ASSERT_EQ(0, image.update_features(RBD_FEATURE_OBJECT_MAP, true));
+ ASSERT_EQ(0, image.update_features(RBD_FEATURE_OBJECT_MAP, false));
+ ASSERT_EQ(-EINVAL, image.update_features(RBD_FEATURE_FAST_DIFF, false));
ASSERT_EQ(0, image.features(&features));
ASSERT_EQ(0U, features & RBD_FEATURE_FAST_DIFF);
- expected_flags = RBD_FLAG_OBJECT_MAP_INVALID;
ASSERT_EQ(0, image.get_flags(&flags));
- ASSERT_EQ(expected_flags, flags);
+ ASSERT_EQ(0U, flags);
// cannot disable exclusive lock w/ object map
+ ASSERT_EQ(0, image.update_features(RBD_FEATURE_OBJECT_MAP, true));
ASSERT_EQ(-EINVAL, image.update_features(RBD_FEATURE_EXCLUSIVE_LOCK, false));
ASSERT_EQ(0, image.update_features(RBD_FEATURE_OBJECT_MAP, false));
// cannot disable exclusive lock w/ journaling
+ ASSERT_EQ(0, image.update_features(RBD_FEATURE_JOURNALING, true));
ASSERT_EQ(-EINVAL, image.update_features(RBD_FEATURE_EXCLUSIVE_LOCK, false));
ASSERT_EQ(0, image.update_features(RBD_FEATURE_JOURNALING, false));