]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: establish watch before reading header
authorJosh Durgin <josh.durgin@inktank.com>
Wed, 2 Jan 2013 22:15:24 +0000 (14:15 -0800)
committerJosh Durgin <josh.durgin@inktank.com>
Wed, 2 Jan 2013 22:15:34 +0000 (14:15 -0800)
This eliminates a window in which a race could occur when we have an
image open but no watch established. The previous fix (using
assert_version) did not work well with resend operations.

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

index b69e40bbbdbb2279c1c7d5ffa93d4051a01060c0..0b788136b0d1dfaba5535100c803c36875a65717 100644 (file)
@@ -1913,25 +1913,29 @@ reprotect_and_return_err:
     if (r < 0)
       return r;
 
-    ictx->md_lock.Lock();
-    r = ictx_refresh(ictx);
-    ictx->md_lock.Unlock();
-    if (r < 0)
-      return r;
-
-    _snap_set(ictx, ictx->snap_name.c_str());
-
     if (!ictx->read_only) {
       r = ictx->register_watch();
       if (r < 0) {
        lderr(ictx->cct) << "error registering a watch: " << cpp_strerror(r)
                         << dendl;
-       close_image(ictx);
-       return r;
+       goto err_close;
       }
     }
 
+    ictx->md_lock.Lock();
+    r = ictx_refresh(ictx);
+    ictx->md_lock.Unlock();
+    if (r < 0)
+      goto err_close;
+
+    if ((r = _snap_set(ictx, ictx->snap_name.c_str())) < 0)
+      goto err_close;
+
     return 0;
+
+  err_close:
+    close_image(ictx);
+    return r;
   }
 
   void close_image(ImageCtx *ictx)