From: Jason Dillaman Date: Wed, 25 Mar 2015 14:08:14 +0000 (-0400) Subject: cls_rbd: added object_map_snap_add and object_map_snap_remove methods X-Git-Tag: v9.0.1~55^2~19 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=11fd7a9a2ba8d44f445f5a76b52a30ff593e8cff;p=ceph.git cls_rbd: added object_map_snap_add and object_map_snap_remove methods object_map_snap_add is invoked after creating a new snapshot to flag all in-use HEAD objects within as clean. object_map_snap_remove is invoked after a snapshot is removed in order to clear the clean flag on all in-use objects. Signed-off-by: Jason Dillaman --- diff --git a/src/cls/rbd/cls_rbd.cc b/src/cls/rbd/cls_rbd.cc index c8748651d5b..0cd693993ac 100644 --- a/src/cls/rbd/cls_rbd.cc +++ b/src/cls/rbd/cls_rbd.cc @@ -41,6 +41,7 @@ #include "common/errno.h" #include "objclass/objclass.h" #include "include/rbd_types.h" +#include "include/rbd/object_map_types.h" #include "cls/rbd/cls_rbd.h" @@ -98,6 +99,8 @@ cls_method_handle_t h_object_map_load; cls_method_handle_t h_object_map_save; cls_method_handle_t h_object_map_resize; cls_method_handle_t h_object_map_update; +cls_method_handle_t h_object_map_snap_add; +cls_method_handle_t h_object_map_snap_remove; cls_method_handle_t h_metadata_set; cls_method_handle_t h_metadata_remove; cls_method_handle_t h_metadata_list; @@ -2219,6 +2222,84 @@ int object_map_update(cls_method_context_t hctx, bufferlist *in, bufferlist *out return r; } +/** + * Mark all _EXISTS objects as _EXISTS_CLEAN so future writes to the + * image HEAD can be tracked. + * + * Input: + * none + * + * Output: + * @returns 0 on success, negative error code on failure + */ +int object_map_snap_add(cls_method_context_t hctx, bufferlist *in, + bufferlist *out) +{ + BitVector<2> object_map; + int r = object_map_read(hctx, object_map); + if (r < 0) { + return r; + } + + bool updated = false; + for (uint64_t i = 0; i < object_map.size(); ++i) { + if (object_map[i] == OBJECT_EXISTS) { + object_map[i] = OBJECT_EXISTS_CLEAN; + updated = true; + } + } + + if (updated) { + bufferlist bl; + ::encode(object_map, bl); + r = cls_cxx_write_full(hctx, &bl); + } + return r; +} + +/** + * Mark all _EXISTS_CLEAN objects as _EXISTS in the current object map + * if the provided snapshot object map object is marked as _EXISTS. + * + * Input: + * @param snapshot object map bit vector + * + * Output: + * @returns 0 on success, negative error code on failure + */ +int object_map_snap_remove(cls_method_context_t hctx, bufferlist *in, + bufferlist *out) +{ + BitVector<2> src_object_map; + try { + bufferlist::iterator iter = in->begin(); + ::decode(src_object_map, iter); + } catch (const buffer::error &err) { + return -EINVAL; + } + + BitVector<2> dst_object_map; + int r = object_map_read(hctx, dst_object_map); + if (r < 0) { + return r; + } + + bool updated = false; + for (uint64_t i = 0; i < dst_object_map.size(); ++i) { + if (dst_object_map[i] == OBJECT_EXISTS_CLEAN && + (i >= src_object_map.size() || src_object_map[i] == OBJECT_EXISTS)) { + dst_object_map[i] = OBJECT_EXISTS; + updated = true; + } + } + + if (updated) { + bufferlist bl; + ::encode(dst_object_map, bl); + r = cls_cxx_write_full(hctx, &bl); + } + return r; +} static const string metadata_key_for_name(const string &name) { @@ -2708,6 +2789,12 @@ void __cls_init() cls_register_cxx_method(h_class, "object_map_update", CLS_METHOD_RD | CLS_METHOD_WR, object_map_update, &h_object_map_update); + cls_register_cxx_method(h_class, "object_map_snap_add", + CLS_METHOD_RD | CLS_METHOD_WR, + object_map_snap_add, &h_object_map_snap_add); + cls_register_cxx_method(h_class, "object_map_snap_remove", + CLS_METHOD_RD | CLS_METHOD_WR, + object_map_snap_remove, &h_object_map_snap_remove); /* methods for the old format */ cls_register_cxx_method(h_class, "snap_list",