Skip to content

Commit 92e50c4

Browse files
committed
mds: do not write journal head twice on trim
Add context to wait for MDLog::trim_expired_segments to write the journal head. Signed-off-by: Patrick Donnelly <[email protected]>
1 parent 6828bd0 commit 92e50c4

File tree

3 files changed

+35
-40
lines changed

3 files changed

+35
-40
lines changed

src/mds/MDLog.cc

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ void MDLog::trim()
644644
max_ev = events_per_segment + 1;
645645
}
646646

647-
submit_mutex.lock();
647+
std::unique_lock locker{submit_mutex};
648648

649649
// trim!
650650
dout(10) << "trim "
@@ -655,7 +655,6 @@ void MDLog::trim()
655655
<< dendl;
656656

657657
if (segments.empty()) {
658-
submit_mutex.unlock();
659658
return;
660659
}
661660

@@ -725,22 +724,23 @@ void MDLog::trim()
725724
new_expiring_segments++;
726725
expiring_segments.insert(ls);
727726
expiring_events += ls->num_events;
728-
submit_mutex.unlock();
727+
locker.unlock();
729728

730729
uint64_t last_seq = ls->seq;
731730
try_expire(ls, op_prio);
732731
log_trim_counter.hit();
733732
trim_end = ceph::coarse_mono_clock::now();
734733

735-
submit_mutex.lock();
734+
locker.lock();
736735
p = segments.lower_bound(last_seq + 1);
737736
}
738737
}
739738

739+
ceph_assert(locker.owns_lock());
740+
740741
try_to_commit_open_file_table(get_last_segment_seq());
741742

742-
// discard expired segments and unlock submit_mutex
743-
_trim_expired_segments();
743+
_trim_expired_segments(locker);
744744
}
745745

746746
class C_MaybeExpiredSegment : public MDSInternalContext {
@@ -764,7 +764,7 @@ class C_MaybeExpiredSegment : public MDSInternalContext {
764764
*/
765765
int MDLog::trim_to(SegmentBoundary::seq_t seq)
766766
{
767-
submit_mutex.lock();
767+
std::unique_lock locker(submit_mutex);
768768

769769
dout(10) << __func__ << ": "
770770
<< seq
@@ -788,7 +788,7 @@ int MDLog::trim_to(SegmentBoundary::seq_t seq)
788788
// Caller should have flushed journaler before calling this
789789
if (pending_events.count(ls->seq)) {
790790
dout(5) << __func__ << ": " << *ls << " has pending events" << dendl;
791-
submit_mutex.unlock();
791+
locker.unlock();
792792
return -CEPHFS_EAGAIN;
793793
}
794794

@@ -800,17 +800,17 @@ int MDLog::trim_to(SegmentBoundary::seq_t seq)
800800
ceph_assert(expiring_segments.count(ls) == 0);
801801
expiring_segments.insert(ls);
802802
expiring_events += ls->num_events;
803-
submit_mutex.unlock();
803+
locker.unlock();
804804

805805
uint64_t next_seq = ls->seq + 1;
806806
try_expire(ls, CEPH_MSG_PRIO_DEFAULT);
807807

808-
submit_mutex.lock();
808+
locker.lock();
809809
p = segments.lower_bound(next_seq);
810810
}
811811
}
812812

813-
_trim_expired_segments();
813+
_trim_expired_segments(locker);
814814

815815
return 0;
816816
}
@@ -851,9 +851,10 @@ void MDLog::_maybe_expired(LogSegment *ls, int op_prio)
851851
try_expire(ls, op_prio);
852852
}
853853

854-
void MDLog::_trim_expired_segments()
854+
void MDLog::_trim_expired_segments(auto& locker, MDSContext* ctx)
855855
{
856856
ceph_assert(ceph_mutex_is_locked_by_me(submit_mutex));
857+
ceph_assert(locker.owns_lock());
857858

858859
uint64_t const oft_committed_seq = mds->mdcache->open_file_table.get_committed_log_seq();
859860

@@ -912,16 +913,15 @@ void MDLog::_trim_expired_segments()
912913
dout(10) << __func__ << ": maybe expiring " << *ls << dendl;
913914
}
914915

915-
submit_mutex.unlock();
916+
locker.unlock();
916917

917-
if (trimmed)
918-
journaler->write_head(0);
919-
}
920-
921-
void MDLog::trim_expired_segments()
922-
{
923-
submit_mutex.lock();
924-
_trim_expired_segments();
918+
if (trimmed) {
919+
write_head(ctx);
920+
} else {
921+
if (ctx) {
922+
ctx->complete(0);
923+
}
924+
}
925925
}
926926

927927
void MDLog::_expired(LogSegment *ls)

src/mds/MDLog.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ class MDLog {
146146
return unflushed == 0;
147147
}
148148

149-
void trim_expired_segments();
149+
void trim_expired_segments(MDSContext* ctx=nullptr) {
150+
std::unique_lock locker(submit_mutex);
151+
_trim_expired_segments(locker, ctx);
152+
}
150153
int trim_all() {
151154
return trim_to(0);
152155
}
@@ -288,7 +291,7 @@ class MDLog {
288291
void try_expire(LogSegment *ls, int op_prio);
289292
void _maybe_expired(LogSegment *ls, int op_prio);
290293
void _expired(LogSegment *ls);
291-
void _trim_expired_segments();
294+
void _trim_expired_segments(auto& locker, MDSContext* ctx=nullptr);
292295
void write_head(MDSContext *onfinish);
293296

294297
void trim();

src/mds/MDSRank.cc

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -176,25 +176,14 @@ class C_Flush_Journal : public MDSInternalContext {
176176
<< mdlog->get_journaler()->get_trimmed_pos() << dendl;
177177

178178
// Now everyone I'm interested in is expired
179-
mdlog->trim_expired_segments();
179+
auto* ctx = new MDSInternalContextWrapper(mds, new LambdaContext([this](int r) {
180+
handle_write_head(r);
181+
}));
182+
mdlog->trim_expired_segments(ctx);
180183

181-
dout(5) << __func__ << ": trim complete, expire_pos/trim_pos is now "
184+
dout(5) << __func__ << ": trimming is complete; wait for journal head write. Journal expire_pos/trim_pos is now "
182185
<< std::hex << mdlog->get_journaler()->get_expire_pos() << "/"
183186
<< mdlog->get_journaler()->get_trimmed_pos() << dendl;
184-
185-
write_journal_head();
186-
}
187-
188-
void write_journal_head() {
189-
dout(20) << __func__ << dendl;
190-
191-
Context *ctx = new LambdaContext([this](int r) {
192-
std::lock_guard locker(mds->mds_lock);
193-
handle_write_head(r);
194-
});
195-
// Flush the journal header so that readers will start from after
196-
// the flushed region
197-
mdlog->get_journaler()->write_head(ctx);
198187
}
199188

200189
void handle_write_head(int r) {
@@ -208,7 +197,10 @@ class C_Flush_Journal : public MDSInternalContext {
208197
}
209198

210199
void finish(int r) override {
211-
ceph_assert(!ceph_mutex_is_locked_by_me(mds->mds_lock));
200+
/* We don't need the mds_lock but MDLog::write_head takes an MDSContext so
201+
* we are expected to have it.
202+
*/
203+
ceph_assert(ceph_mutex_is_locked_by_me(mds->mds_lock));
212204
dout(20) << __func__ << ": r=" << r << dendl;
213205
on_finish->complete(r);
214206
}

0 commit comments

Comments
 (0)