From: Samuel Just Date: Thu, 13 Jun 2024 00:41:55 +0000 (+0000) Subject: crimson: fix ObjectContext::_with_lock to only unlock if lock is taken X-Git-Tag: v20.0.0~1686^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F58099%2Fhead;p=ceph.git crimson: fix ObjectContext::_with_lock to only unlock if lock is taken Fixes: https://tracker.ceph.com/issues/66461 Signed-off-by: Samuel Just --- diff --git a/src/crimson/osd/object_context.h b/src/crimson/osd/object_context.h index 466f22b8372..b1a1e893827 100644 --- a/src/crimson/osd/object_context.h +++ b/src/crimson/osd/object_context.h @@ -137,22 +137,34 @@ public: private: template auto _with_lock(Lock& lock, Func&& func) { - Ref obc = this; auto maybe_fut = lock.lock(); return seastar::futurize_invoke([ maybe_fut=std::move(maybe_fut), - func=std::forward(func)]() mutable { + func=std::forward(func), + obc=Ref(this), + &lock]() mutable { if (maybe_fut) { return std::move(*maybe_fut - ).then([func=std::forward(func)]() mutable { - return seastar::futurize_invoke(func); + ).then([func=std::forward(func), obc, &lock]() mutable { + return seastar::futurize_invoke( + func + ).finally([&lock, obc] { + /* We chain the finally block here because it's possible for + * *maybe_fut from lock.lock() above to fail due to a call to + * ObjectContext::interrupt, which calls tri_mutex::abort. + * In the event of such an error, the lock isn't actually taken + * and calling unlock() would be incorrect. */ + lock.unlock(); + }); }); } else { // atomically calling func upon locking - return seastar::futurize_invoke(func); + return seastar::futurize_invoke( + func + ).finally([&lock, obc] { + lock.unlock(); + }); } - }).finally([&lock, obc] { - lock.unlock(); }); }