]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: fix race between unprotect and clone
authorJosh Durgin <josh.durgin@inktank.com>
Sun, 30 Dec 2012 04:35:15 +0000 (20:35 -0800)
committerJosh Durgin <josh.durgin@inktank.com>
Sun, 30 Dec 2012 08:06:11 +0000 (00:06 -0800)
Clone needs to actually re-read the header to make sure the image is
still protected before returning. Additionally, it needs to consider
the image protected *only* if the protection status is protected -
unprotecting does not count. I thought I'd already fixed this, but
can't find the commit.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
src/librbd/ImageCtx.cc
src/librbd/internal.cc

index fb9212e187ed134d9f605344b9b64f77602e0337..80f19d2355019645ee13e310c61725e6a2cea83f 100644 (file)
@@ -327,7 +327,7 @@ namespace librbd {
     map<string, SnapInfo>::const_iterator it = snaps_by_name.find(in_snap_name);
     if (it != snaps_by_name.end()) {
       *is_protected =
-       (it->second.protection_status != RBD_PROTECTION_STATUS_UNPROTECTED);
+       (it->second.protection_status == RBD_PROTECTION_STATUS_PROTECTED);
       return 0;
     }
     return -ENOENT;
index 53ce19c65fc6caff1a9cd84c3366208cbf70e099..ee8966cb40e23adf1113a944d906adbde3e99c65 100644 (file)
@@ -963,10 +963,15 @@ reprotect_and_return_err:
       goto err_close_child;
     }
 
-    p_imctx->snap_lock.Lock();
-    r = p_imctx->is_snap_protected(p_imctx->snap_name, &snap_protected);
-    p_imctx->snap_lock.Unlock();
+    p_imctx->md_lock.Lock();
+    r = ictx_refresh(p_imctx);
+    p_imctx->md_lock.Unlock();
 
+    if (r == 0) {
+      p_imctx->snap_lock.Lock();
+      r = p_imctx->is_snap_protected(p_imctx->snap_name, &snap_protected);
+      p_imctx->snap_lock.Unlock();
+    }
     if (r < 0 || !snap_protected) {
       // we lost the race with unprotect
       r = -EINVAL;