From: Jason Dillaman Date: Mon, 10 Nov 2014 15:08:26 +0000 (-0500) Subject: librbd: Use RBD image flags for invalid object maps X-Git-Tag: v0.93~143^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=719515a8da94974c8312eb71672ca5687e7a84ab;p=ceph.git librbd: Use RBD image flags for invalid object maps If the RBD object map state is corrupted, flag the object map as invalid so that it won't be used for IO operations. Signed-off-by: Jason Dillaman --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 8d7f23ff2c9..b94faff149f 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -47,6 +47,8 @@ extern "C" { #define CEPH_RBD_API #endif +#define RBD_FLAG_OBJECT_MAP_INVALID (1<<0) + typedef void *rbd_snap_t; typedef void *rbd_image_t; diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index d17e6fd357e..9f1150828cc 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -55,7 +55,7 @@ namespace librbd { order(0), size(0), features(0), format_string(NULL), id(image_id), parent(NULL), - stripe_unit(0), stripe_count(0), + stripe_unit(0), stripe_count(0), flags(0), object_cacher(NULL), writeback_handler(NULL), object_set(NULL), readahead(), total_bytes_read(0), copyup_finisher(NULL), @@ -687,8 +687,9 @@ namespace librbd { bool ImageCtx::object_may_exist(uint64_t object_no) const { - // Fall back to default logic if object map is disabled - if ((features & RBD_FEATURE_OBJECT_MAP) == 0 /* || invalid map */) { + // Fall back to default logic if object map is disabled or invalid + if ((features & RBD_FEATURE_OBJECT_MAP) == 0 || + ((flags & RBD_FLAG_OBJECT_MAP_INVALID) != 0)) { return true; } @@ -710,7 +711,7 @@ namespace librbd { if (r < 0) { lderr(cct) << "error refreshing object map: " << cpp_strerror(r) << dendl; - // TODO: flag object map as invalid + invalidate_object_map(); object_map.clear(); return r; } @@ -723,7 +724,7 @@ namespace librbd { // resize op might have been interrupted lderr(cct) << "incorrect object map size: " << object_map.size() << " != " << num_objs << dendl; - // TODO: flag object map as invalid + invalidate_object_map(); return -EINVAL; } return 0; @@ -745,7 +746,7 @@ namespace librbd { lderr(cct) << "error resizing object map: size=" << num_objs << ", " << "state=" << default_object_state << ", " << "error=" << cpp_strerror(r) << dendl; - // TODO: flag object map as invalid + invalidate_object_map(); return 0; } @@ -773,7 +774,8 @@ namespace librbd { RWLock::WLocker l(object_map_lock); assert(start_object_no <= end_object_no); - assert(/* flagged as invalid || */ end_object_no <= object_map.size()); + assert(end_object_no <= object_map.size() || + (flags & RBD_FLAG_OBJECT_MAP_INVALID) != 0); if (end_object_no > object_map.size()) { ldout(cct, 20) << "skipping update of invalid object map" << dendl; return 0; @@ -803,7 +805,7 @@ namespace librbd { int r = data_ctx.operate(object_map_name(id), &op); if (r < 0) { lderr(cct) << "object map update failed: " << cpp_strerror(r) << dendl; - // TODO: remove RBD_FEATURE_EXCLUSIVE_LOCK feature on image + invalidate_object_map(); } else { for (uint64_t object_no = start_object_no; object_no < end_object_no; ++object_no) { @@ -814,4 +816,15 @@ namespace librbd { } return r; } + + void ImageCtx::invalidate_object_map() + { + flags |= RBD_FLAG_OBJECT_MAP_INVALID; + int r = cls_client::set_flags(&md_ctx, header_oid, flags, + RBD_FLAG_OBJECT_MAP_INVALID); + if (r < 0) { + lderr(cct) << "Failed to invalidate object map: " << cpp_strerror(r) + << dendl; + } + } } diff --git a/src/librbd/ImageCtx.h b/src/librbd/ImageCtx.h index 1c148d5e90c..6c0977ee964 100644 --- a/src/librbd/ImageCtx.h +++ b/src/librbd/ImageCtx.h @@ -96,6 +96,7 @@ namespace librbd { parent_info parent_md; ImageCtx *parent; uint64_t stripe_unit, stripe_count; + uint64_t flags; ceph_file_layout layout; @@ -189,6 +190,7 @@ namespace librbd { int update_object_map(uint64_t start_object_no, uint64_t end_object_no, uint8_t new_state, const boost::optional ¤t_state); + void invalidate_object_map(); }; } diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 9feaa18f520..db13d68e0fc 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -2217,6 +2217,26 @@ reprotect_and_return_err: return -ENOSYS; } + r = cls_client::get_flags(&ictx->md_ctx, ictx->header_oid, + ictx->snap_id, &ictx->flags); + if (r == -EOPNOTSUPP || r == -EIO) { + // Older OSD doesn't support RBD flags, need to assume the worst + ldout(ictx->cct, 10) << "OSD does not support RBD flags" << dendl; + } else if (r == -ENOENT) { + ldout(ictx->cct, 10) << "Image at invalid snapshot" << dendl; + } else if (r < 0 && r != -ENOENT) { + lderr(cct) << "Error reading flags: " << cpp_strerror(r) << dendl; + return r; + } + if (r < 0) { + ictx->flags = 0; + if ((ictx->features & RBD_FEATURE_OBJECT_MAP) != 0) { + ldout(ictx->cct, 10) << "disabling object map optimizations" + << dendl; + ictx->flags |= RBD_FLAG_OBJECT_MAP_INVALID; + } + } + r = cls_client::snapshot_list(&(ictx->md_ctx), ictx->header_oid, new_snapc.snaps, &snap_names, &snap_sizes, &snap_features,