From 0c43de4699aa1863488daeaa3411d1eaba07d0a2 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 4 Oct 2017 10:46:46 -0400 Subject: [PATCH] librbd: list_children should not attempt to refresh image The snap_lock is being held when this method is invoked, which can result in a deadlock. Fixes: http://tracker.ceph.com/issues/21670 Signed-off-by: Jason Dillaman (cherry picked from commit 4c585d826f38ff97d3a484a30eca0588c79396b4) Conflicts: src/librbd/internal.cc: functions re-arranged in later release --- src/librbd/internal.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 52e3dd9192e5c..53483ee3d6fb7 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -885,11 +885,16 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, CephContext *cct = ictx->cct; ldout(cct, 20) << "children list " << ictx->name << dendl; + int r = ictx->state->refresh_if_required(); + if (r < 0) { + return r; + } + RWLock::RLocker l(ictx->snap_lock); parent_spec parent_spec(ictx->md_ctx.get_id(), ictx->id, ictx->snap_id); map< pair, set > image_info; - int r = list_children_info(ictx, parent_spec,image_info); + r = list_children_info(ictx, parent_spec,image_info); if (r < 0) { return r; } @@ -920,12 +925,9 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, } int list_children_info(ImageCtx *ictx, librbd::parent_spec parent_spec, - map< pair, set >& image_info) + map< pair, set >& image_info) { CephContext *cct = ictx->cct; - int r = ictx->state->refresh_if_required(); - if (r < 0) - return r; // no children for non-layered or old format image if (!ictx->test_features(RBD_FEATURE_LAYERING, ictx->snap_lock)) @@ -935,7 +937,7 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force, // search all pools for children depending on this snapshot Rados rados(ictx->md_ctx); std::list > pools; - r = rados.pool_list2(pools); + int r = rados.pool_list2(pools); if (r < 0) { lderr(cct) << "error listing pools: " << cpp_strerror(r) << dendl; return r; -- 2.39.5