Doing it in the aio thread ensures that there isn't a use-after-free.
Note that this is only bluefs written files.
Signed-off-by: Sage Weil <sage@redhat.com>
size(0), block_size(0),
fs(NULL), aio(false), dio(false),
debug_lock("BlockDevice::debug_lock"),
+ ioc_reap_lock("BlockDevice::ioc_reap_lock"),
aio_queue(g_conf->bdev_aio_max_queue_depth),
aio_callback(cb),
aio_callback_priv(cbpriv),
}
}
}
+ if (ioc_reap_count.read()) {
+ Mutex::Locker l(ioc_reap_lock);
+ for (auto p : ioc_reap_queue) {
+ dout(20) << __func__ << " reap ioc " << p << dendl;
+ delete p;
+ }
+ ioc_reap_queue.clear();
+ ioc_reap_count.dec();
+ }
}
dout(10) << __func__ << " end" << dendl;
}
}
return r;
}
+
+void BlockDevice::queue_reap_ioc(IOContext *ioc)
+{
+ Mutex::Locker l(ioc_reap_lock);
+ if (ioc_reap_count.read() == 0)
+ ioc_reap_count.inc();
+ ioc_reap_queue.push_back(ioc);
+}
Mutex debug_lock;
interval_set<uint64_t> debug_inflight;
+ Mutex ioc_reap_lock;
+ vector<IOContext*> ioc_reap_queue;
+ atomic_t ioc_reap_count;
+
FS::aio_queue_t aio_queue;
aio_callback_t aio_callback;
void *aio_callback_priv;
IOContext *ioc);
int flush();
+ void queue_reap_ioc(IOContext *ioc);
+
// for managing buffered readers/writers
int invalidate_cache(uint64_t off, uint64_t len);
int open(string path);
_close_writer(log_writer);
log_writer = NULL;
- // manually clean up it's iocs
- for (auto p : ioc_reap_queue) {
- delete p;
- }
- ioc_reap_queue.clear();
block_all.clear();
_stop_alloc();
}
dout(10) << __func__ << dendl;
utime_t start = ceph_clock_now(NULL);
- vector<IOContext*> iocv;
- iocv.swap(ioc_reap_queue);
for (auto p : alloc) {
p->commit_start();
}
for (auto p : alloc) {
p->commit_finish();
}
- for (auto p : iocv) {
- delete p;
- }
utime_t end = ceph_clock_now(NULL);
utime_t dur = end - start;
dout(10) << __func__ << " done in " << dur << dendl;
void BlueFS::_close_writer(FileWriter *h)
{
dout(10) << __func__ << " " << h << dendl;
- for (auto i : h->iocv) {
- if (i->has_aios()) {
- ioc_reap_queue.push_back(i);
- } else {
- delete i;
- }
+ for (unsigned i=0; i<bdev.size(); ++i) {
+ bdev[i]->queue_reap_ioc(h->iocv[i]);
}
h->iocv.clear();
delete h;
vector<interval_set<uint64_t> > block_all; ///< extents in bdev we own
vector<Allocator*> alloc; ///< allocators for bdevs
- vector<IOContext*> ioc_reap_queue; ///< iocs from closed writers
-
void _init_alloc();
void _stop_alloc();