From ede177fc9e8bfd8fa99a6bb403138ba49c2ad7f1 Mon Sep 17 00:00:00 2001 From: sageweil Date: Tue, 28 Aug 2007 21:18:17 +0000 Subject: [PATCH] added clean bh merging, removed unnecessary dirty list git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1716 29311d96-e01e-0410-9327-a35deaab8ce9 --- trunk/ceph/ebofs/BufferCache.cc | 85 ++++++++++++++++++++++++++++++++- trunk/ceph/ebofs/BufferCache.h | 25 ++++++---- 2 files changed, 101 insertions(+), 9 deletions(-) diff --git a/trunk/ceph/ebofs/BufferCache.cc b/trunk/ceph/ebofs/BufferCache.cc index 18912aa867e6f..b02f4e0058ac2 100644 --- a/trunk/ceph/ebofs/BufferCache.cc +++ b/trunk/ceph/ebofs/BufferCache.cc @@ -133,7 +133,10 @@ void ObjectCache::tx_finish(ioh_t ioh, block_t start, block_t length, assert(p->first == bh->start()); // past? - if (p->first >= start+length) break; + if (p->first >= start+length) { + bh->oc->try_merge_bh_right(p); + break; + } if (bh->tx_ioh == ioh) bh->tx_ioh = 0; @@ -149,6 +152,7 @@ void ObjectCache::tx_finish(ioh_t ioh, block_t start, block_t length, assert(bh->end() <= start+length); bh->set_last_flushed(version); bc->mark_clean(bh); + bh->oc->try_merge_bh_left(p); } else { dout(10) << "tx_finish leaving tx, " << bh->version << " > " << version << " on " << *bh << dendl; @@ -714,6 +718,83 @@ void ObjectCache::clone_to(Onode *other) +BufferHead *ObjectCache::merge_bh_left(BufferHead *left, BufferHead *right) +{ + dout(-10) << "merge_bh_left " << *left << " " << *right << dendl; + assert(left->end() == right->start()); + assert(left->is_clean()); + assert(right->is_clean()); + assert(right->get_num_ref() == 0); + + // hrm, is this right? + if (right->version > left->version) left->version = right->version; + if (right->last_flushed > left->last_flushed) left->last_flushed = right->last_flushed; + + left->set_length(left->length() + right->length()); + left->data.claim_append(right->data); + + // remove right + remove_bh(right); + bc->lru_rest.lru_remove(right); + delete right; + dout(-10) << "merge_bh_left result " << *left << dendl; + return left; +} + +/* wait until this has a user +void ObjectCache::try_merge_bh(BufferHead *bh) +{ + dout(-10) << "try_merge_bh " << *bh << dendl; + + map::iterator p = data.lower_bound(bh->start()); + assert(p->second == bh); + + try_merge_bh_left(p); + try_merge_bh_right(p); +} +*/ + + +void ObjectCache::try_merge_bh_left(map::iterator& p) +{ + BufferHead *bh = p->second; + dout(10) << "try_merge_bh_left " << *bh << dendl; + + // left? + if (p != data.begin()) { + p--; + if (p->second->end() == bh->start() && + p->second->is_clean() && + bh->is_clean() && + bh->get_num_ref() == 0) + bh = merge_bh_left(p->second, bh); // yay! + else + p++; // nope. + } +} + +void ObjectCache::try_merge_bh_right(map::iterator& p) +{ + BufferHead *bh = p->second; + dout(10) << "try_merge_bh_right " << *bh << dendl; + + // right? + map::iterator o = p; + p++; + if (p != data.end() && + bh->end() == p->second->start() && + p->second->is_clean() && + bh->is_clean() && + p->second->get_num_ref() == 0) { + BufferHead *right = p->second; + p--; + merge_bh_left(bh, right); + } else + p = o; +} + + + /************** BufferCache ***************/ #undef dout @@ -787,6 +868,8 @@ BufferHead *BufferCache::split(BufferHead *orig, block_t after) } + + void BufferCache::bh_read(Onode *on, BufferHead *bh, block_t from) { dout(10) << "bh_read " << *on << " on " << *bh << dendl; diff --git a/trunk/ceph/ebofs/BufferCache.h b/trunk/ceph/ebofs/BufferCache.h index 24aeccc4a200c..346a5cc785618 100644 --- a/trunk/ceph/ebofs/BufferCache.h +++ b/trunk/ceph/ebofs/BufferCache.h @@ -25,6 +25,7 @@ #include "BlockDevice.h" #include "include/interval_set.h" +#include "include/xlist.h" class ObjectCache; class BufferCache; @@ -62,6 +63,7 @@ class BufferHead : public LRUObject { set shadows; // shadow bh's that clone()ed me. BufferHead* shadow_of; + private: int ref; int state; @@ -75,6 +77,7 @@ class BufferHead : public LRUObject { Extent object_loc; // block position _in_object_ utime_t dirty_stamp; + //xlist::item xlist_dirty; bool want_to_expire; // wants to be at bottom of lru @@ -84,6 +87,7 @@ class BufferHead : public LRUObject { rx_ioh(0), tx_ioh(0), tx_block(0), partial_tx_to(0), partial_tx_epoch(0), shadow_of(0), ref(0), state(STATE_MISSING), epoch_modified(0), version(0), last_flushed(0), + //xlist_dirty(this), want_to_expire(false) {} ~BufferHead() { @@ -103,6 +107,7 @@ class BufferHead : public LRUObject { --ref; return ref; } + int get_num_ref() { return ref; } block_t start() { return object_loc.start; } void set_start(block_t s) { object_loc.start = s; } @@ -283,7 +288,7 @@ class BufferHead : public LRUObject { continue; } // overlap tail of i? - if (off > i->first && off < i->first + i->second.length()) { + if (off > i->first && off+len >= i->first + i->second.length()) { // shorten i. bufferlist o; o.claim( i->second ); @@ -293,7 +298,7 @@ class BufferHead : public LRUObject { continue; } // overlap head of i? - if (off < i->first && off+len < i->first + i->second.length()) { + if (off <= i->first && off+len < i->first + i->second.length()) { // move i (make new tail). off_t tailoff = off+len; unsigned trim = tailoff - i->first; @@ -322,7 +327,6 @@ class BufferHead : public LRUObject { partial[off] = p; } - }; inline ostream& operator<<(ostream& out, BufferHead& bh) @@ -413,6 +417,11 @@ class ObjectCache { } bool is_empty() { return data.empty(); } + void try_merge_bh(BufferHead *bh); + void try_merge_bh_left(map::iterator& p); + void try_merge_bh_right(map::iterator& p); + BufferHead* merge_bh_left(BufferHead *left, BufferHead *right); + int find_tx(block_t start, block_t len, list& tx); @@ -459,7 +468,7 @@ class BufferCache { Mutex &ebofs_lock; // hack: this is a ref to global ebofs_lock BlockDevice &dev; - set dirty_bh; + //xlist dirty_bh; LRU lru_dirty, lru_rest; @@ -521,7 +530,7 @@ class BufferCache { bh->get_oc()->add_bh(bh); if (bh->is_dirty()) { lru_dirty.lru_insert_mid(bh); - dirty_bh.insert(bh); + //dirty_bh.push_back(&bh->xlist_dirty); } else lru_rest.lru_insert_mid(bh); stat_add(bh); @@ -544,7 +553,7 @@ class BufferCache { stat_sub(bh); if (bh->is_dirty()) { lru_dirty.lru_remove(bh); - dirty_bh.erase(bh); + //dirty_bh.push_back(&bh->xlist_dirty); } else lru_rest.lru_remove(bh); } @@ -612,7 +621,7 @@ class BufferCache { if (s == BufferHead::STATE_DIRTY && bh->get_state() != BufferHead::STATE_DIRTY) { lru_rest.lru_remove(bh); lru_dirty.lru_insert_top(bh); - dirty_bh.insert(bh); + //dirty_bh.push_back(&bh->xlist_dirty); } if (s != BufferHead::STATE_DIRTY && bh->get_state() == BufferHead::STATE_DIRTY) { lru_dirty.lru_remove(bh); @@ -620,7 +629,7 @@ class BufferCache { lru_rest.lru_insert_bot(bh); else lru_rest.lru_insert_mid(bh); - dirty_bh.erase(bh); + //dirty_bh.remove(&bh->xlist_dirty); } // set state -- 2.39.5