From 2280736c4d6adff73b34263c33a9ce4a220c5414 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Fri, 5 Sep 2014 22:12:01 +0800 Subject: [PATCH] osdc/Journaler: fix try_read_entry()/wait_for_readable() locking These two functions should be protected by the Journal::mutex. Furthermore, wait_for_readable() is racy. The journal may have already become readable when it is called. Signed-off-by: Yan, Zheng --- src/osdc/Journaler.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/osdc/Journaler.cc b/src/osdc/Journaler.cc index 579e49b3ca09..b16809e2f301 100644 --- a/src/osdc/Journaler.cc +++ b/src/osdc/Journaler.cc @@ -994,6 +994,8 @@ bool Journaler::_is_readable() */ bool Journaler::is_readable() { + Mutex::Locker l(lock); + bool r = _is_readable(); _prefetch(); return r; @@ -1048,7 +1050,9 @@ void Journaler::_finish_erase(int data_result, C_OnFinisher *completion) */ bool Journaler::try_read_entry(bufferlist& bl) { - if (!is_readable()) { // this may start a read. + Mutex::Locker l(lock); + + if (!_is_readable()) { // this may start a read. ldout(cct, 10) << "try_read_entry at " << read_pos << " not readable" << dendl; return false; } @@ -1071,10 +1075,16 @@ bool Journaler::try_read_entry(bufferlist& bl) void Journaler::wait_for_readable(Context *onreadable) { - ldout(cct, 10) << "wait_for_readable at " << read_pos << " onreadable " << onreadable << dendl; - assert(!_is_readable()); + Mutex::Locker l(lock); + assert(on_readable == 0); - on_readable = wrap_finisher(onreadable); + if (!_is_readable()) { + ldout(cct, 10) << "wait_for_readable at " << read_pos << " onreadable " << onreadable << dendl; + on_readable = wrap_finisher(onreadable); + } else { + // race with OSD reply + finisher->queue(onreadable, 0); + } } -- 2.47.3