diff options
author | Samuel Just <sam.just@inktank.com> | 2013-05-07 11:12:43 -0700 |
---|---|---|
committer | Samuel Just <sam.just@inktank.com> | 2013-05-09 17:28:15 -0700 |
commit | 90f50c487acea3b0a395fdcc6ea6640c2a8e7d9d (patch) | |
tree | dec6aaddef0198b0be7e13f63ccf5fd9ec04ba8e /src/osd/OSD.h | |
parent | b274c8a0b21ec87a744bbb4c27e6c21277c7d794 (diff) | |
download | ceph-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.h | 78 |
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; |