summaryrefslogtreecommitdiff
path: root/src/osd/OSD.h
diff options
context:
space:
mode:
authorSamuel Just <sam.just@inktank.com>2013-05-07 11:12:43 -0700
committerSamuel Just <sam.just@inktank.com>2013-05-09 17:28:15 -0700
commit90f50c487acea3b0a395fdcc6ea6640c2a8e7d9d (patch)
treedec6aaddef0198b0be7e13f63ccf5fd9ec04ba8e /src/osd/OSD.h
parentb274c8a0b21ec87a744bbb4c27e6c21277c7d794 (diff)
downloadceph-90f50c487acea3b0a395fdcc6ea6640c2a8e7d9d.tar.gz
OSD: add pg deletion cancelation
DeletingState now allows _create_lock_pg() to attempt to cancel pg deletion. PG::init() must mark the PG as backfill iff we stopped a deletion. Signed-off-by: Samuel Just <sam.just@inktank.com>
Diffstat (limited to 'src/osd/OSD.h')
-rw-r--r--src/osd/OSD.h78
1 files changed, 77 insertions, 1 deletions
diff --git a/src/osd/OSD.h b/src/osd/OSD.h
index e5886d959af..2a9f2827488 100644
--- a/src/osd/OSD.h
+++ b/src/osd/OSD.h
@@ -142,9 +142,19 @@ typedef std::tr1::shared_ptr<ObjectStore::Sequencer> SequencerRef;
class DeletingState {
Mutex lock;
+ Cond cond;
list<Context *> on_deletion_complete;
+ enum {
+ QUEUED,
+ CLEARING_DIR,
+ DELETING_DIR,
+ DELETED_DIR,
+ CANCELED,
+ } status;
+ bool stop_deleting;
public:
- DeletingState() : lock("DeletingState::lock") {}
+ DeletingState() :
+ lock("DeletingState::lock"), status(QUEUED), stop_deleting(false) {}
void register_on_delete(Context *completion) {
Mutex::Locker l(lock);
on_deletion_complete.push_front(completion);
@@ -156,6 +166,72 @@ public:
(*i)->complete(0);
}
}
+
+ /// check whether removal was canceled
+ bool check_canceled() {
+ Mutex::Locker l(lock);
+ assert(status == CLEARING_DIR);
+ if (stop_deleting) {
+ status = CANCELED;
+ cond.Signal();
+ return false;
+ }
+ return true;
+ } ///< @return false if canceled, true if we should continue
+
+ /// transition status to clearing
+ bool start_clearing() {
+ Mutex::Locker l(lock);
+ assert(
+ status == QUEUED ||
+ status == DELETED_DIR);
+ if (stop_deleting) {
+ status = CANCELED;
+ cond.Signal();
+ return false;
+ }
+ status = CLEARING_DIR;
+ return true;
+ } ///< @return false if we should cancel deletion
+
+ /// transition status to deleting
+ bool start_deleting() {
+ Mutex::Locker l(lock);
+ assert(status == CLEARING_DIR);
+ if (stop_deleting) {
+ status = CANCELED;
+ cond.Signal();
+ return false;
+ }
+ status = DELETING_DIR;
+ return true;
+ } ///< @return false if we should cancel deletion
+
+ /// signal collection removal queued
+ void finish_deleting() {
+ Mutex::Locker l(lock);
+ assert(status == DELETING_DIR);
+ status = DELETED_DIR;
+ cond.Signal();
+ }
+
+ /// try to halt the deletion
+ bool try_stop_deletion() {
+ Mutex::Locker l(lock);
+ stop_deleting = true;
+ /**
+ * If we are in DELETING_DIR or DELETED_DIR, there are in progress
+ * operations we have to wait for before continuing on. States
+ * DELETED_DIR, QUEUED, and CANCELED either check for stop_deleting
+ * prior to performing any operations or signify the end of the
+ * deleting process. We don't want to wait to leave the QUEUED
+ * state, because this might block the caller behind entire pg
+ * removals.
+ */
+ while (status == DELETING_DIR || status == DELETING_DIR)
+ cond.Wait(lock);
+ return status != DELETED_DIR;
+ } ///< @return true if we don't need to recreate the collection
};
typedef std::tr1::shared_ptr<DeletingState> DeletingStateRef;