librbd/cache/pwl/ssd: avoid dispatch_deferred_writes() vs ~AbstractWriteLog() race
In append_op_log_entries(), dispatch_deferred_writes() is called after
append_ops() returns. This can result in a race between AbstractWriteLog
destructor and dispatch_deferred_writes() because all I/Os may complete
and append_ctx callback may run allowing AbstractWriteLog::shut_down()
to indicate completion before dispatch_deferred_writes() is called.
This race is problematic even if there aren't any deferred writes
(i.e. m_deferred_ios list is empty): a deadlock may pop up because
m_thread_pool is stopped by the destructor under the same lock that
dispatch_deferred_writes() needs to perform the initial check on
m_deferred_ios.
Call dispatch_deferred_writes() from append_ops() before the I/O batch
is submitted, similar to what was done previously in commit d83a0f6db8ff
("librbd/cache/pwl/ssd: avoid corrupting m_first_free_entry"). Since
dispatch_deferred_writes() appears to be called to act on a decremented
m_bytes_allocated, this doesn't change anything for it. The ops.size()
condition has always been redundant as append_op_log_entries() asserts
on it and ops list remains constant.
Fixes: https://tracker.ceph.com/issues/77894
Signed-off-by: Ilya Dryomov <idryomov@gmail.com> I
Ilya Dryomov committed
229ed45778621556c24d0a7770518f0551f7c1ad
Parent: 0358275