From 5246e789606b802f8a0e5bc58eb2ec3ac6e481c3 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 28 Oct 2015 16:54:21 +0800 Subject: [PATCH] objectcacher: make flush_set() only flushes dirty data in ObjectSet Buffer heads in dirty_or_tx_bh are sorted in ObjectSet/Object/offset order. So we can find dirty buffer heads in the given ObjectSet and flush them only. Signed-off-by: Yan, Zheng --- src/osdc/ObjectCacher.cc | 43 +++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index e358ed73989a..85c5a9b4b25a 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -1825,17 +1825,46 @@ bool ObjectCacher::flush_set(ObjectSet *oset, Context *onfinish) C_GatherBuilder gather(cct); set waitfor_commit; - set::iterator next, it; - next = it = dirty_or_tx_bh.begin(); - while (it != dirty_or_tx_bh.end()) { - ++next; - BufferHead *bh = *it; - waitfor_commit.insert(bh->ob); + set::iterator it, p, q; + + // Buffer heads in dirty_or_tx_bh are sorted in ObjectSet/Object/offset + // order. But items in oset->objects are not sorted. So the iterator can + // point to any buffer head in the ObjectSet + BufferHead key(*oset->objects.begin()); + it = dirty_or_tx_bh.lower_bound(&key); + p = q = it; + + bool backwards = true; + if (it != dirty_or_tx_bh.begin()) + --it; + else + backwards = false; + for (; p != dirty_or_tx_bh.end(); p = q) { + ++q; + BufferHead *bh = *p; + if (bh->ob->oset != oset) + break; + waitfor_commit.insert(bh->ob); if (bh->is_dirty()) bh_write(bh); + } - it = next; + if (backwards) { + for(p = q = it; true; p = q) { + if (q != dirty_or_tx_bh.begin()) + --q; + else + backwards = false; + BufferHead *bh = *p; + if (bh->ob->oset != oset) + break; + waitfor_commit.insert(bh->ob); + if (bh->is_dirty()) + bh_write(bh); + if (!backwards) + break; + } } for (set::iterator i = waitfor_commit.begin(); -- 2.47.3