mirror of
https://github.com/ceph/ceph
synced 2025-01-03 01:22:53 +00:00
mds: call wait_for_safe twice in command_flush_journal
...so that we wait until everyone who was waiting for the first wait_for_safe has run their completion before we proceed, thus avoiding the possibility that those completions will execute during our trimming and cause problems. Fixes: #10368 Signed-off-by: John Spray <john.spray@redhat.com>
This commit is contained in:
parent
b94189f9c0
commit
035ab3c0e3
@ -438,6 +438,7 @@ int MDS::_command_flush_journal(std::stringstream *ss)
|
||||
|
||||
// Flush initially so that all the segments older than our new one
|
||||
// will be elegible for expiry
|
||||
{
|
||||
C_SaferCond mdlog_flushed;
|
||||
mdlog->flush();
|
||||
mdlog->wait_for_safe(new MDSInternalContextWrapper(this, &mdlog_flushed));
|
||||
@ -448,6 +449,24 @@ int MDS::_command_flush_journal(std::stringstream *ss)
|
||||
*ss << "Error " << r << " (" << cpp_strerror(r) << ") while flushing journal";
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
// Because we may not be the last wait_for_safe context on MDLog, and
|
||||
// subsequent contexts might wake up in the middle of our later trim_all
|
||||
// and interfere with expiry (by e.g. marking dirs/dentries dirty
|
||||
// on previous log segments), we run a second wait_for_safe here.
|
||||
// See #10368
|
||||
{
|
||||
C_SaferCond mdlog_cleared;
|
||||
mdlog->wait_for_safe(new MDSInternalContextWrapper(this, &mdlog_cleared));
|
||||
mds_lock.Unlock();
|
||||
r = mdlog_cleared.wait();
|
||||
mds_lock.Lock();
|
||||
if (r != 0) {
|
||||
*ss << "Error " << r << " (" << cpp_strerror(r) << ") while flushing journal";
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
// Put all the old log segments into expiring or expired state
|
||||
dout(5) << __func__ << ": beginning segment expiry" << dendl;
|
||||
|
Loading…
Reference in New Issue
Block a user