Skip to content

Commit 4762ffa

Browse files
committed
On graceful shutdown we will wait for discard queue to drain before storing the allocator.
ON fast shutdown we will simply copy the discard queue entries to the allocator Signed-off-by: Gabriel BenHanokh <[email protected]>
1 parent 3aa891d commit 4762ffa

File tree

4 files changed

+21
-36
lines changed

4 files changed

+21
-36
lines changed

src/blk/BlockDevice.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,8 @@ class BlockDevice {
285285
int write_hint = WRITE_LIFE_NOT_SET) = 0;
286286
virtual int flush() = 0;
287287
virtual bool try_discard(interval_set<uint64_t> &to_release, bool async=true) { return false; }
288-
virtual int discard_drain(uint32_t timeout_msec = 0) { return 0; }
289-
288+
virtual void discard_drain() { return; }
289+
virtual const interval_set<uint64_t>* get_discard_queued() { return nullptr;}
290290
// for managing buffered readers/writers
291291
virtual int invalidate_cache(uint64_t off, uint64_t len) = 0;
292292
virtual int open(const std::string& path) = 0;

src/blk/kernel/KernelDevice.cc

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -587,35 +587,13 @@ bool KernelDevice::_discard_started()
587587
return !discard_threads.empty();
588588
}
589589

590-
int KernelDevice::discard_drain(uint32_t timeout_msec = 0)
590+
void KernelDevice::discard_drain()
591591
{
592592
dout(10) << __func__ << dendl;
593-
bool check_timeout = false;
594-
utime_t end_time;
595-
if (timeout_msec) {
596-
check_timeout = true;
597-
uint32_t timeout_sec = 0;
598-
if (timeout_msec >= 1000) {
599-
timeout_sec = (timeout_msec / 1000);
600-
timeout_msec = (timeout_msec % 1000);
601-
}
602-
end_time = ceph_clock_now();
603-
// add the timeout after converting from msec to nsec
604-
end_time.tv.tv_nsec += (timeout_msec * (1000*1000));
605-
if (end_time.tv.tv_nsec > (1000*1000*1000)) {
606-
end_time.tv.tv_nsec -= (1000*1000*1000);
607-
end_time.tv.tv_sec += 1;
608-
}
609-
end_time.tv.tv_sec += timeout_sec;
610-
}
611593
std::unique_lock l(discard_lock);
612594
while (!discard_queued.empty() || discard_running) {
613595
discard_cond.wait(l);
614-
if (check_timeout && ceph_clock_now() > end_time) {
615-
return -1;
616-
}
617596
}
618-
return 0;
619597
}
620598

621599
static bool is_expected_ioerr(const int r)

src/blk/kernel/KernelDevice.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ class KernelDevice : public BlockDevice,
123123
~KernelDevice();
124124

125125
void aio_submit(IOContext *ioc) override;
126-
int discard_drain(uint32_t timeout_msec) override;
127-
126+
void discard_drain() override;
127+
const interval_set<uint64_t>* get_discard_queued() override { return &discard_queued;}
128128
int collect_metadata(const std::string& prefix, std::map<std::string,std::string> *pm) const override;
129129
int get_devname(std::string *s) const override {
130130
if (devname.empty()) {

src/os/bluestore/BlueStore.cc

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7762,17 +7762,24 @@ void BlueStore::_close_db()
77627762
db = nullptr;
77637763

77647764
if (do_destage && fm && fm->is_null_manager()) {
7765-
// force all backgrounds discards to be committed before storing allocator
7766-
// set timeout to 500msec
7767-
int ret = bdev->discard_drain(500);
7768-
if (ret == 0) {
7769-
ret = store_allocator(alloc);
7770-
if (unlikely(ret != 0)) {
7771-
derr << __func__ << "::NCB::store_allocator() failed (we will need to rebuild it on startup)" << dendl;
7765+
if (cct->_conf->osd_fast_shutdown == false) {
7766+
// graceful shutdown -> commit backgrounds discards before storing allocator
7767+
bdev->discard_drain();
7768+
}
7769+
7770+
auto discard_queued = bdev->get_discard_queued();
7771+
if (discard_queued && (discard_queued->num_intervals() > 0)) {
7772+
dout(10) << __func__ << "::discard_drain: size=" << discard_queued->size()
7773+
<< " num_intervals=" << discard_queued->num_intervals() << dendl;
7774+
// copy discard_queued to the allocator before storing it
7775+
for (auto p = discard_queued->begin(); p != discard_queued->end(); ++p) {
7776+
dout(20) << __func__ << "::discarded-extent=[" << p.get_start() << ", " << p.get_len() << "]" << dendl;
7777+
alloc->init_add_free(p.get_start(), p.get_len());
77727778
}
77737779
}
7774-
else {
7775-
derr << __func__ << "::NCB::discard_drain() exceeded timeout (abort!)" << dendl;
7780+
int ret = store_allocator(alloc);
7781+
if (unlikely(ret != 0)) {
7782+
derr << __func__ << "::NCB::store_allocator() failed (we will need to rebuild it on startup)" << dendl;
77767783
}
77777784
}
77787785

0 commit comments

Comments
 (0)