]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: acquire cache_lock before refreshing parent 4206/head
authorJason Dillaman <dillaman@redhat.com>
Mon, 16 Mar 2015 15:04:22 +0000 (11:04 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 27 Mar 2015 18:13:37 +0000 (14:13 -0400)
cache_lock needs to be acquired before snap_lock to avoid
the potential for deadlock.

Fixes: #5488
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/ImageCtx.cc
src/librbd/internal.cc

index 8fb8e37129c91b7e7e56e1cb7f3747619fe81283..1295d421c23533965062f9d60b93dc6a4efe1d55 100644 (file)
@@ -603,9 +603,7 @@ namespace librbd {
   void ImageCtx::clear_nonexistence_cache() {
     if (!object_cacher)
       return;
-    cache_lock.Lock();
     object_cacher->clear_nonexistence(object_set);
-    cache_lock.Unlock();
   }
 
   int ImageCtx::register_watch() {
index 598d515cde4a409462d00f49da984c42b2b1ba64..6ca8941214ac6ab258cab108fac971162f09f47b 100644 (file)
@@ -1286,11 +1286,13 @@ reprotect_and_return_err:
       return r;
     }
 
+    ictx->parent->cache_lock.Lock();
     ictx->parent->snap_lock.get_write();
     r = ictx->parent->get_snap_name(parent_snap_id, &ictx->parent->snap_name);
     if (r < 0) {
       lderr(ictx->cct) << "parent snapshot does not exist" << dendl;
       ictx->parent->snap_lock.put_write();
+      ictx->parent->cache_lock.Unlock();
       close_image(ictx->parent);
       ictx->parent = NULL;
       return r;
@@ -1304,12 +1306,14 @@ reprotect_and_return_err:
                       << ictx->parent->snap_name << dendl;
       ictx->parent->parent_lock.put_write();
       ictx->parent->snap_lock.put_write();
+      ictx->parent->cache_lock.Unlock();
       close_image(ictx->parent);
       ictx->parent = NULL;
       return r;
     }
     ictx->parent->parent_lock.put_write();
     ictx->parent->snap_lock.put_write();
+    ictx->parent->cache_lock.Unlock();
 
     return 0;
   }
@@ -1707,10 +1711,11 @@ reprotect_and_return_err:
     vector<parent_info> snap_parents;
     vector<uint8_t> snap_protection;
     {
-      RWLock::WLocker l(ictx->snap_lock);
+      Mutex::Locker cache_locker(ictx->cache_lock);
+      RWLock::WLocker snap_locker(ictx->snap_lock);
       {
-        int r;
-       RWLock::WLocker l2(ictx->parent_lock);
+       int r;
+       RWLock::WLocker parent_locker(ictx->parent_lock);
        ictx->lockers.clear();
        if (ictx->old_format) {
          r = read_header(ictx->md_ctx, ictx->header_oid, &ictx->header, NULL);
@@ -1836,7 +1841,7 @@ reprotect_and_return_err:
       }
 
       ictx->data_ctx.selfmanaged_snap_set_write_ctx(ictx->snapc.seq, ictx->snaps);
-    } // release snap_lock
+    } // release snap_lock and cache_lock
 
     if (new_snap) {
       _flush(ictx);
@@ -2068,8 +2073,9 @@ reprotect_and_return_err:
 
   int _snap_set(ImageCtx *ictx, const char *snap_name)
   {
-    RWLock::WLocker l1(ictx->snap_lock);
-    RWLock::WLocker l2(ictx->parent_lock);
+    Mutex::Locker cache_locker(ictx->cache_lock);
+    RWLock::WLocker snap_locker(ictx->snap_lock);
+    RWLock::WLocker parent_locker(ictx->parent_lock);
     int r;
     if ((snap_name != NULL) && (strlen(snap_name) != 0)) {
       r = ictx->snap_set(snap_name);