]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: list_children should not attempt to refresh image
authorJason Dillaman <dillaman@redhat.com>
Wed, 4 Oct 2017 14:46:46 +0000 (10:46 -0400)
committerJason Dillaman <dillaman@redhat.com>
Wed, 4 Oct 2017 14:46:46 +0000 (10:46 -0400)
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 <dillaman@redhat.com>
src/librbd/api/Image.cc
src/librbd/internal.cc

index 27049183b65626f3f5749fa1b0f40f37cecf5aff..43eb592a7b632b811f9d15bea80d96c8d29174ce 100644 (file)
@@ -54,10 +54,6 @@ int Image<I>::list_children(I *ictx, const ParentSpec &parent_spec,
                             PoolImageIds *pool_image_ids)
 {
   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)) {
@@ -68,7 +64,7 @@ int Image<I>::list_children(I *ictx, const ParentSpec &parent_spec,
   // search all pools for children depending on this snapshot
   librados::Rados rados(ictx->md_ctx);
   std::list<std::pair<int64_t, std::string> > 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;
index acbe336629ccd4c52aee6ed94e4e06a533865b30..9b322997014dc7a06943416853be5cdc432389f9 100644 (file)
@@ -568,12 +568,17 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
     CephContext *cct = ictx->cct;
     ldout(cct, 20) << "children flatten " << ictx->name << dendl;
 
+    int r = ictx->state->refresh_if_required();
+    if (r < 0) {
+      return r;
+    }
+
     RWLock::RLocker l(ictx->snap_lock);
     snap_t snap_id = ictx->get_snap_id(cls::rbd::UserSnapshotNamespace(), snap_name);
     ParentSpec parent_spec(ictx->md_ctx.get_id(), ictx->id, snap_id);
     map< pair<int64_t, string>, set<string> > image_info;
 
-    int r = api::Image<>::list_children(ictx, parent_spec, &image_info);
+    r = api::Image<>::list_children(ictx, parent_spec, &image_info);
     if (r < 0) {
       return r;
     }
@@ -645,11 +650,16 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
     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);
     ParentSpec parent_spec(ictx->md_ctx.get_id(), ictx->id, ictx->snap_id);
     map< pair<int64_t, string>, set<string> > image_info;
 
-    int r = api::Image<>::list_children(ictx, parent_spec, &image_info);
+    r = api::Image<>::list_children(ictx, parent_spec, &image_info);
     if (r < 0) {
       return r;
     }