From a8e041f0656573ecc26e1625bfb46e43d1ee08ff Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Sun, 25 Jan 2015 21:15:41 -0800 Subject: [PATCH] osd_types: add excl obc lock Signed-off-by: Samuel Just --- src/osd/osd_types.h | 67 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index f75fb3ddead..4e7a2da0ef5 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -2996,13 +2996,15 @@ public: enum State { RWNONE, RWREAD, - RWWRITE + RWWRITE, + RWEXCL, }; static const char *get_state_name(State s) { switch (s) { case RWNONE: return "none"; case RWREAD: return "read"; case RWWRITE: return "write"; + case RWEXCL: return "excl"; default: return "???"; } } @@ -3049,6 +3051,8 @@ public: return true; case RWWRITE: return false; + case RWEXCL: + return false; default: assert(0 == "unhandled case"); return false; @@ -3081,11 +3085,39 @@ public: return true; case RWREAD: return false; + case RWEXCL: + return false; default: assert(0 == "unhandled case"); return false; } } + bool get_excl_lock() { + switch (state) { + case RWNONE: + assert(count == 0); + state = RWEXCL; + count = 1; + return true; + case RWWRITE: + return false; + case RWREAD: + return false; + case RWEXCL: + return false; + default: + assert(0 == "unhandled case"); + return false; + } + } + bool get_excl(OpRequestRef op) { + if (get_excl_lock()) { + return true; + } // else + if (op) + waiters.push_back(op); + return false; + } /// same as get_write_lock, but ignore starvation bool take_write_lock() { if (state == RWWRITE) { @@ -3111,6 +3143,10 @@ public: assert(state == RWWRITE); dec(requeue); } + void put_excl(list *requeue) { + assert(state == RWEXCL); + dec(requeue); + } bool empty() const { return state == RWNONE; } } rwstate; @@ -3120,6 +3156,22 @@ public: bool get_write(OpRequestRef op) { return rwstate.get_write(op, false); } + bool get_excl(OpRequestRef op) { + return rwstate.get_excl(op); + } + bool get_lock_type(OpRequestRef op, RWState::State type) { + switch (type) { + case RWState::RWWRITE: + return get_write(op); + case RWState::RWREAD: + return get_read(op); + case RWState::RWEXCL: + return get_excl(op); + default: + assert(0 == "invalid lock type"); + return true; + } + } bool get_write_greedy(OpRequestRef op) { return rwstate.get_write(op, true); } @@ -3146,6 +3198,19 @@ public: void put_read(list *to_wake) { rwstate.put_read(to_wake); } + void put_excl(list *to_wake, + bool *requeue_recovery, + bool *requeue_snaptrimmer) { + rwstate.put_excl(to_wake); + if (rwstate.empty() && rwstate.recovery_read_marker) { + rwstate.recovery_read_marker = false; + *requeue_recovery = true; + } + if (rwstate.empty() && rwstate.snaptrimmer_write_marker) { + rwstate.snaptrimmer_write_marker = false; + *requeue_snaptrimmer = true; + } + } void put_write(list *to_wake, bool *requeue_recovery, bool *requeue_snaptrimmer) {