From: Yan, Zheng Date: Fri, 5 Sep 2014 14:12:01 +0000 (+0800) Subject: osdc/Journaler: fix try_read_entry()/wait_for_readable() locking X-Git-Tag: v0.86~132^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F2404%2Fhead;p=ceph.git 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 --- 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); + } }