file->deleted = true;
if (file->dirty_seq) {
assert(file->dirty_seq > log_seq_stable);
+ assert(dirty_files.count(file->dirty_seq));
+ auto it = dirty_files[file->dirty_seq].iterator_to(*file);
+ dirty_files[file->dirty_seq].erase(it);
file->dirty_seq = 0;
- dirty_files.erase(dirty_files.iterator_to(*file));
}
}
}
// delete the new log, remove from the dirty files list
_close_writer(new_log_writer);
- dirty_files.erase(dirty_files.iterator_to(*new_log));
+ if (new_log->dirty_seq) {
+ assert(dirty_files.count(new_log->dirty_seq));
+ auto it = dirty_files[new_log->dirty_seq].iterator_to(*new_log);
+ dirty_files[new_log->dirty_seq].erase(it);
+ }
new_log_writer = nullptr;
new_log = nullptr;
log_cond.notify_all();
if (seq > log_seq_stable) {
log_seq_stable = seq;
dout(20) << __func__ << " log_seq_stable " << log_seq_stable << dendl;
- dirty_file_list_t::iterator p = dirty_files.begin();
+
+ auto p = dirty_files.begin();
while (p != dirty_files.end()) {
- File *file = &(*p);
- assert(file->dirty_seq > 0);
- if (file->dirty_seq <= log_seq_stable) {
- dout(20) << __func__ << " cleaned file " << file->fnode << dendl;
- file->dirty_seq = 0;
- dirty_files.erase(p++);
- } else {
- ++p;
+ if (p->first > log_seq_stable) {
+ dout(20) << __func__ << " done cleaning up dirty files" << dendl;
+ break;
+ }
+
+ auto l = p->second.begin();
+ while (l != p->second.end()) {
+ File *file = &*l;
+ assert(file->dirty_seq > 0);
+ assert(file->dirty_seq <= log_seq_stable);
+ dout(20) << __func__ << " cleaned file " << file->fnode << dendl;
+ file->dirty_seq = 0;
+ p->second.erase(l++);
}
+
+ assert(p->second.empty());
+ dirty_files.erase(p++);
}
} else {
dout(20) << __func__ << " log_seq_stable " << log_seq_stable
- << " already > out seq " << seq
+ << " already >= out seq " << seq
<< ", we lost a race against another log flush, done" << dendl;
}
_update_logger_stats();
h->file->fnode.mtime = ceph_clock_now(NULL);
log_t.op_file_update(h->file->fnode);
if (h->file->dirty_seq == 0) {
- dirty_files.push_back(*h->file);
+ h->file->dirty_seq = log_seq + 1;
+ dirty_files[h->file->dirty_seq].push_back(*h->file);
dout(20) << __func__ << " dirty_seq = " << log_seq + 1
<< " (was clean)" << dendl;
} else {
- dout(20) << __func__ << " dirty_seq = " << log_seq + 1
- << " (was " << h->file->dirty_seq << ")" << dendl;
+ if (h->file->dirty_seq != log_seq + 1) {
+ // need re-dirty, erase from list first
+ assert(dirty_files.count(h->file->dirty_seq));
+ auto it = dirty_files[h->file->dirty_seq].iterator_to(*h->file);
+ dirty_files[h->file->dirty_seq].erase(it);
+ h->file->dirty_seq = log_seq + 1;
+ dirty_files[h->file->dirty_seq].push_back(*h->file);
+ dout(20) << __func__ << " dirty_seq = " << log_seq + 1
+ << " (was " << h->file->dirty_seq << ")" << dendl;
+ } else {
+ dout(20) << __func__ << " dirty_seq = " << log_seq + 1
+ << " (unchanged, do nothing) " << dendl;
+ }
}
- h->file->dirty_seq = log_seq + 1;
}
dout(20) << __func__ << " file now " << h->file->fnode << dendl;