]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: snap protect/unprotect now connected to watch/notify
authorJason Dillaman <dillaman@redhat.com>
Tue, 25 Aug 2015 15:17:57 +0000 (11:17 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 19 Nov 2015 01:34:38 +0000 (20:34 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/ImageWatcher.cc
src/librbd/internal.cc
src/librbd/internal.h

index 87aebf0d9084fd4658390c628af01e62b94484f8..6cbab0022173a6da43c5cd60d5e3ee3e9689d978 100644 (file)
@@ -1091,9 +1091,12 @@ void ImageWatcher::handle_payload(const SnapProtectPayload& payload,
   if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) {
     ldout(m_image_ctx.cct, 10) << this << " remote snap_protect request: "
                                << payload.snap_name << dendl;
+    C_SaferCond cond_ctx;
+    librbd::snap_protect_helper(&m_image_ctx, &cond_ctx,
+                                payload.snap_name.c_str());
 
-    // TODO
-    ::encode(ResponseMessage(-EOPNOTSUPP), *out);
+    int r = cond_ctx.wait();
+    ::encode(ResponseMessage(r), *out);
   }
 }
 
@@ -1103,9 +1106,12 @@ void ImageWatcher::handle_payload(const SnapUnprotectPayload& payload,
   if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) {
     ldout(m_image_ctx.cct, 10) << this << " remote snap_unprotect request: "
                                << payload.snap_name << dendl;
+    C_SaferCond cond_ctx;
+    librbd::snap_unprotect_helper(&m_image_ctx, &cond_ctx,
+                                  payload.snap_name.c_str());
 
-    // TODO
-    ::encode(ResponseMessage(-EOPNOTSUPP), *out);
+    int r = cond_ctx.wait();
+    ::encode(ResponseMessage(r), *out);
   }
 }
 
@@ -1125,7 +1131,7 @@ void ImageWatcher::handle_payload(const RebuildObjectMapPayload& payload,
       librbd::async_rebuild_object_map(&m_image_ctx, ctx, *prog_ctx);
     }
 
-    ::encode(ResponseMessage(0), *out);
+    ::encode(ResponseMessage(r), *out);
   }
 }
 
index accf5e0fdfa80ace40f23fd5439cb474b4f8e381..8efec10d2f5cf379f4270675898b471db9633113 100644 (file)
@@ -903,57 +903,149 @@ int invoke_async_request(ImageCtx *ictx, const std::string& request_type,
     ldout(ictx->cct, 20) << "snap_protect " << ictx << " " << snap_name
                         << dendl;
 
-    if (ictx->read_only)
+    if (ictx->read_only) {
       return -EROFS;
+    }
 
     int r = ictx_check(ictx);
-    if (r < 0)
+    if (r < 0) {
       return r;
+    }
 
-    // TODO integrate w/ watch/notify
-    RWLock::RLocker owner_locker(ictx->owner_lock);
+    {
+      RWLock::RLocker snap_locker(ictx->snap_lock);
+      bool is_protected;
+      r = ictx->is_snap_protected(ictx->get_snap_id(snap_name), &is_protected);
+      if (r < 0) {
+        return r;
+      }
 
-    C_SaferCond cond_ctx;
-    operation::SnapshotProtectRequest *request =
-      new operation::SnapshotProtectRequest(*ictx, &cond_ctx, snap_name);
-    request->send();
-    r = cond_ctx.wait();
-    if (r < 0) {
-      return r;
+      if (is_protected) {
+        return -EBUSY;
+      }
+    }
+
+    if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
+      r = invoke_async_request(ictx, "snap_protect", true,
+                               boost::bind(&snap_protect_helper, ictx, _1,
+                                           snap_name),
+                               boost::bind(&ImageWatcher::notify_snap_protect,
+                                           ictx->image_watcher, snap_name));
+      if (r < 0 && r != -EBUSY) {
+        return r;
+      }
+    } else {
+      RWLock::RLocker owner_lock(ictx->owner_lock);
+      C_SaferCond cond_ctx;
+      snap_protect_helper(ictx, &cond_ctx, snap_name);
+
+      r = cond_ctx.wait();
+      if (r < 0) {
+        return r;
+      }
     }
 
     notify_change(ictx->md_ctx, ictx->header_oid, ictx);
     return 0;
   }
 
+  void snap_protect_helper(ImageCtx *ictx, Context* ctx, const char *snap_name)
+  {
+    assert(ictx->owner_lock.is_locked());
+    if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
+      assert(!ictx->image_watcher->is_lock_supported() ||
+             ictx->image_watcher->is_lock_owner());
+    }
+
+    ldout(ictx->cct, 20) << "snap_protect_helper " << ictx << " " << snap_name
+                         << dendl;
+
+    int r = ictx_check(ictx, ictx->owner_lock);
+    if (r < 0) {
+      ctx->complete(r);
+      return;
+    }
+
+    operation::SnapshotProtectRequest *request =
+      new operation::SnapshotProtectRequest(*ictx, ctx, snap_name);
+    request->send();
+  }
+
   int snap_unprotect(ImageCtx *ictx, const char *snap_name)
   {
     ldout(ictx->cct, 20) << "snap_unprotect " << ictx << " " << snap_name
                         << dendl;
 
-    if (ictx->read_only)
+    if (ictx->read_only) {
       return -EROFS;
+    }
 
     int r = ictx_check(ictx);
-    if (r < 0)
+    if (r < 0) {
       return r;
+    }
 
-    // TODO integrate w/ watch/notify
-    RWLock::RLocker owner_locker(ictx->owner_lock);
+    {
+      RWLock::RLocker snap_locker(ictx->snap_lock);
+      bool is_unprotected;
+      r = ictx->is_snap_unprotected(ictx->get_snap_id(snap_name),
+                                    &is_unprotected);
+      if (r < 0) {
+        return r;
+      }
 
-    C_SaferCond cond_ctx;
-    operation::SnapshotUnprotectRequest *request
-      = new operation::SnapshotUnprotectRequest(*ictx, &cond_ctx, snap_name);
-    request->send();
-    r = cond_ctx.wait();
-    if (r < 0) {
-      return r;
+      if (is_unprotected) {
+        return -EINVAL;
+      }
+    }
+
+    if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
+      r = invoke_async_request(ictx, "snap_unprotect", true,
+                               boost::bind(&snap_unprotect_helper, ictx, _1,
+                                           snap_name),
+                               boost::bind(&ImageWatcher::notify_snap_unprotect,
+                                           ictx->image_watcher, snap_name));
+      if (r < 0 && r != -EINVAL) {
+        return r;
+      }
+    } else {
+      RWLock::RLocker owner_lock(ictx->owner_lock);
+      C_SaferCond cond_ctx;
+      snap_unprotect_helper(ictx, &cond_ctx, snap_name);
+
+      r = cond_ctx.wait();
+      if (r < 0) {
+        return r;
+      }
     }
 
     notify_change(ictx->md_ctx, ictx->header_oid, ictx);
     return 0;
   }
 
+  void snap_unprotect_helper(ImageCtx *ictx, Context* ctx,
+                             const char *snap_name)
+  {
+    assert(ictx->owner_lock.is_locked());
+    if (ictx->test_features(RBD_FEATURE_JOURNALING)) {
+      assert(!ictx->image_watcher->is_lock_supported() ||
+             ictx->image_watcher->is_lock_owner());
+    }
+
+    ldout(ictx->cct, 20) << "snap_unprotect_helper " << ictx << " " << snap_name
+                         << dendl;
+
+    int r = ictx_check(ictx, ictx->owner_lock);
+    if (r < 0) {
+      ctx->complete(r);
+      return;
+    }
+
+    operation::SnapshotUnprotectRequest *request =
+      new operation::SnapshotUnprotectRequest(*ictx, ctx, snap_name);
+    request->send();
+  }
+
   int snap_is_protected(ImageCtx *ictx, const char *snap_name,
                        bool *is_protected)
   {
index 2300fcc998cbee07e254e101addd72ca65d28a8d..964dde68d21bf653edd81a535b0dbe70b3c0d5bc 100644 (file)
@@ -137,7 +137,10 @@ namespace librbd {
   void snap_rename_helper(ImageCtx *ictx, Context* ctx,
                           const uint64_t src_snap_id, const char *dst_name);
   int snap_protect(ImageCtx *ictx, const char *snap_name);
+  void snap_protect_helper(ImageCtx *ictx, Context* ctx, const char *snap_name);
   int snap_unprotect(ImageCtx *ictx, const char *snap_name);
+  void snap_unprotect_helper(ImageCtx *ictx, Context* ctx,
+                             const char *snap_name);
   int snap_is_protected(ImageCtx *ictx, const char *snap_name,
                        bool *is_protected);
   int refresh_parent(ImageCtx *ictx);