From: Jason Dillaman Date: Thu, 12 Mar 2015 02:37:46 +0000 (-0400) Subject: librbd: add update_features to librbd API X-Git-Tag: v9.0.0~37^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7cff359188443ecd40bacb5406c1a5278f411f56;p=ceph.git librbd: add update_features to librbd API Allow mutable features to be enabled / disabled. Signed-off-by: Jason Dillaman --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 506be7876613..9e54b318a07f 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -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); diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index a5a7bae045d4..52c713b58bc6 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -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); diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index bf2401019e2f..ce70350480a9 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -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); diff --git a/src/librbd/internal.h b/src/librbd/internal.h index 9d583fe94326..aa472a98af3e 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -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); diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index cdba2cc3655d..1143a1f62101 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -322,6 +322,15 @@ namespace librbd { return r; } + int Image::update_features(uint64_t features, bool enabled) + { + ImageCtx *ictx = reinterpret_cast(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(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; diff --git a/src/tracing/librbd.tp b/src/tracing/librbd.tp index bf2c6f4f0dbd..b7d104591ce9 100644 --- a/src/tracing/librbd.tp +++ b/src/tracing/librbd.tp @@ -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,