}
// drop lock while we wait for io
+ list<FS::aio_t> completed_ios;
+ _claim_completed_aios(log_writer, &completed_ios);
l.unlock();
wait_for_aio(log_writer);
+ completed_ios.clear();
flush_bdev();
l.lock();
for (unsigned i = 0; i < MAX_BDEV; ++i) {
if (bdev[i]) {
assert(h->iocv[i]);
- if (h->iocv[i]->has_aios())
+ if (h->iocv[i]->has_aios()) {
bdev[i]->aio_submit(h->iocv[i]);
+ }
}
}
dout(20) << __func__ << " h " << h << " pos now 0x"
return 0;
}
+// we need to retire old completed aios so they don't stick around in
+// memory indefinitely (along with their bufferlist refs).
+void BlueFS::_claim_completed_aios(FileWriter *h, list<FS::aio_t> *ls)
+{
+ for (auto p : h->iocv) {
+ if (p) {
+ ls->splice(ls->end(), p->running_aios);
+ }
+ }
+ dout(10) << __func__ << " got " << ls->size() << " aios" << dendl;
+}
+
void BlueFS::wait_for_aio(FileWriter *h)
{
// NOTE: this is safe to call without a lock, as long as our reference is
if (r < 0)
return r;
uint64_t old_dirty_seq = h->file->dirty_seq;
+ list<FS::aio_t> completed_ios;
+ _claim_completed_aios(h, &completed_ios);
lock.unlock();
wait_for_aio(h);
+ completed_ios.clear();
lock.lock();
if (old_dirty_seq) {
uint64_t s = log_seq;
int _allocate(uint8_t bdev, uint64_t len, vector<bluefs_extent_t> *ev);
int _flush_range(FileWriter *h, uint64_t offset, uint64_t length);
int _flush(FileWriter *h, bool force);
- void wait_for_aio(FileWriter *h); // safe to call without a lock
int _fsync(FileWriter *h, std::unique_lock<std::mutex>& l);
+ void _claim_completed_aios(FileWriter *h, list<FS::aio_t> *ls);
+ void wait_for_aio(FileWriter *h); // safe to call without a lock
+
int _flush_and_sync_log(std::unique_lock<std::mutex>& l,
uint64_t want_seq = 0,
uint64_t jump_to = 0);