From d0272a474d18a5dc3375be37fc733564520458b5 Mon Sep 17 00:00:00 2001 From: sageweil Date: Tue, 18 Dec 2007 23:23:45 +0000 Subject: [PATCH] minor bug fixes, cleanup git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2225 29311d96-e01e-0410-9327-a35deaab8ce9 --- branches/ebofs/ebofs/BufferCache.cc | 36 +++++------------- branches/ebofs/ebofs/BufferCache.h | 21 +++++++---- branches/ebofs/ebofs/Ebofs.cc | 57 ++++++++++++++++++----------- branches/ebofs/ebofs/Onode.h | 4 +- branches/ebofs/ebofs/test.ebofs.cc | 4 +- 5 files changed, 62 insertions(+), 60 deletions(-) diff --git a/branches/ebofs/ebofs/BufferCache.cc b/branches/ebofs/ebofs/BufferCache.cc index 493dafe3023e4..cd0b980e5fb00 100644 --- a/branches/ebofs/ebofs/BufferCache.cc +++ b/branches/ebofs/ebofs/BufferCache.cc @@ -115,15 +115,15 @@ void BufferHead::apply_partial() { assert(!partial.empty()); dout(10) << "apply_partial on " << partial.size() << " substrings" << dendl; + csum_t *expect = oc->on->get_extent_csum_ptr(start(), 1); csum_t oldc = calc_csum(data.c_str(), EBOFS_BLOCK_SIZE); do_apply_partial(data, partial); csum_t newc = calc_csum(data.c_str(), EBOFS_BLOCK_SIZE); - csum_t *p = oc->on->get_extent_csum_ptr(start(), 1); - dout(10) << "apply_partial onode had " << hex << *p + dout(10) << "apply_partial onode expected " << hex << *expect << " bl was " << oldc << " now " << newc << dec << dendl; - assert(*p == oldc); - *p = newc; + assert(*expect == oldc); + *expect = newc; oc->on->data_csum += newc - oldc; } @@ -165,13 +165,7 @@ void ObjectCache::rx_finish(ioh_t ioh, block_t start, block_t length, bufferlist bh->rx_ioh = 0; // trigger waiters - for (map >::iterator p = bh->waitfor_read.begin(); - p != bh->waitfor_read.end(); - p++) { - assert(p->first >= bh->start() && p->first < bh->end()); - waiters.splice(waiters.begin(), p->second); - } - bh->waitfor_read.clear(); + bh->take_read_waiters(waiters); if (bh->is_rx()) { assert(bh->get_version() == 0); @@ -805,11 +799,11 @@ void ObjectCache::discard_bh(BufferHead *bh, version_t super_epoch) bh->shadow_of->remove_shadow(bh); } - for (map >::iterator p = bh->waitfor_read.begin(); - p != bh->waitfor_read.end(); - p++) - finish_contexts(p->second, -1); - + // kick read waiters + list finished; + bh->take_read_waiters(finished); + finish_contexts(finished, -1); + bc->remove_bh(bh); } @@ -1156,16 +1150,6 @@ void BufferCache::bh_write(Onode *on, BufferHead *bh, block_t shouldbe) on->oc->get(); inc_unflushed( EBOFS_BC_FLUSH_BHWRITE, bh->epoch_modified ); - - /* - // assert: no partials on the same block - // hose any partial on the same block - if (bh->partial_write.count(ex.start)) { - dout(10) << "bh_write hosing parital write on same block " << ex.start << " " << *bh << dendl; - dec_unflushed( bh->partial_write[ex.start].epoch ); - bh->partial_write.erase(ex.start); - } - */ } diff --git a/branches/ebofs/ebofs/BufferCache.h b/branches/ebofs/ebofs/BufferCache.h index af3073c907e90..c42bbc0fccbd8 100644 --- a/branches/ebofs/ebofs/BufferCache.h +++ b/branches/ebofs/ebofs/BufferCache.h @@ -57,7 +57,7 @@ class BufferHead : public LRUObject { map partial; // partial dirty content overlayed onto incoming data - map< block_t, list > waitfor_read; + map > waitfor_read; set shadows; // shadow bh's that clone()ed me. BufferHead* shadow_of; @@ -243,6 +243,14 @@ class BufferHead : public LRUObject { void apply_partial(); void add_partial(off_t off, bufferlist& p); + void take_read_waiters(list& finished) { + for (map >::iterator p = waitfor_read.begin(); + p != waitfor_read.end(); + p++) + finished.splice(finished.begin(), p->second); + waitfor_read.clear(); + } + }; inline ostream& operator<<(ostream& out, BufferHead& bh) @@ -566,11 +574,11 @@ class BufferCache { } void inc_unflushed(int what, version_t epoch) { epoch_unflushed[what][epoch]++; - //cout << "inc_unflushed " << epoch << " now " << epoch_unflushed[epoch] << std::endl; + //cout << "inc_unflushed " << epoch << " now " << epoch_unflushed[what][epoch] << std::endl; } void dec_unflushed(int what, version_t epoch) { epoch_unflushed[what][epoch]--; - //cout << "dec_unflushed " << epoch << " now " << epoch_unflushed[epoch] << std::endl; + //cout << "dec_unflushed " << epoch << " now " << epoch_unflushed[what][epoch] << std::endl; if (epoch_unflushed[what][epoch] == 0) flush_cond.Signal(); } @@ -593,14 +601,11 @@ class BufferCache { stat_waiter--; } void waitfor_partials() { - cout << "wait start " << partial_reads << std::endl; stat_waiter++; - while (partial_reads > 0) { - cout << "wait " << partial_reads << std::endl; + while (partial_reads > 0) stat_cond.Wait(ebofs_lock); - } stat_waiter--; - cout << "wait finish " << partial_reads << std::endl; + } void waitfor_flush() { flush_cond.Wait(ebofs_lock); diff --git a/branches/ebofs/ebofs/Ebofs.cc b/branches/ebofs/ebofs/Ebofs.cc index 5bb84a3520f9f..8f20f278319cf 100644 --- a/branches/ebofs/ebofs/Ebofs.cc +++ b/branches/ebofs/ebofs/Ebofs.cc @@ -1623,20 +1623,24 @@ int Ebofs::check_partial_edges(Onode *on, off_t off, off_t len, { // partial block overwrite at head or tail? off_t last_block_byte = on->last_block * EBOFS_BLOCK_SIZE; - partial_head = off < last_block_byte && (off & EBOFS_BLOCK_MASK); - partial_tail = (off+len) < on->object_size && ((off+len) & EBOFS_BLOCK_MASK); + partial_head = (off < last_block_byte) && (off & EBOFS_BLOCK_MASK); + partial_tail = ((off+len) < on->object_size) && ((off+len) & EBOFS_BLOCK_MASK); + dout(0) << "check_partial_edges on " << *on << " " << off << "~" << len + << " " << partial_head << "/" << partial_tail << dendl; if ((partial_head || partial_tail) && commit_starting) { + ObjectCache *oc = on->get_oc(&bc); + // verify that partials don't depend on unread data! if (partial_head) { block_t bstart = off / EBOFS_BLOCK_SIZE; - BufferHead *bh = on->oc->find_bh_containing(bstart); + BufferHead *bh = oc->find_bh_containing(bstart); if (!bh) { - dout(0) << "check_partial_edges missing data for partial head, deferring" << dendl; + dout(10) << "check_partial_edges missing data for partial head, deferring" << dendl; return -1; } if (bh->is_missing() || bh->is_rx()) { - dout(0) << "check_partial_edges missing data for partial head " << *bh << ", deferring" << dendl; + dout(10) << "check_partial_edges missing data for partial head " << *bh << ", deferring" << dendl; return -1; } if (bh->is_partial()) { @@ -1644,20 +1648,20 @@ int Ebofs::check_partial_edges(Onode *on, off_t off, off_t len, int end_in_bh = MAX(EBOFS_BLOCK_SIZE, off_in_bh+len); if (!(off_in_bh == 0 || bh->have_partial_range(0, off_in_bh)) || !(end_in_bh == EBOFS_BLOCK_SIZE || bh->have_partial_range(end_in_bh, EBOFS_BLOCK_SIZE-end_in_bh))) { - dout(0) << "check_partial_edges can't complete partial head " << *bh << ", deferring" << dendl; + dout(10) << "check_partial_edges can't complete partial head " << *bh << ", deferring" << dendl; return -1; } } } if (partial_tail) { block_t blast = (len+off-1) / EBOFS_BLOCK_SIZE; - BufferHead *bh = on->oc->find_bh_containing(blast); + BufferHead *bh = oc->find_bh_containing(blast); if (!bh) { - dout(0) << "check_partial_edges missing data for partial tail, deferring" << dendl; + dout(10) << "check_partial_edges missing data for partial tail, deferring" << dendl; return -1; } if (bh->is_missing() || bh->is_rx()) { - dout(0) << "check_partial_edges missing data for partial tail " << *bh << ", deferring" << dendl; + dout(10) << "check_partial_edges missing data for partial tail " << *bh << ", deferring" << dendl; return -1; } if (bh->is_partial()) { @@ -1668,7 +1672,7 @@ int Ebofs::check_partial_edges(Onode *on, off_t off, off_t len, end = last_block_byte & EBOFS_BLOCK_MASK; if (!(off_in_bh == 0 || bh->have_partial_range(0, off_in_bh)) || !(end_in_bh >= end || bh->have_partial_range(end_in_bh, end-end_in_bh))) { - dout(0) << "check_partial_edges can't complete partial tail " << *bh << ", deferring" << dendl; + dout(10) << "check_partial_edges can't complete partial tail " << *bh << ", deferring" << dendl; return -1; } } @@ -1731,6 +1735,7 @@ int Ebofs::apply_write(Onode *on, off_t off, off_t len, const bufferlist& bl) version_t highv = ++oc->write_count; // copy from bl into buffer cache + list finished; unsigned blpos = 0; // byte pos in input buffer for (map::iterator i = hits.begin(); i != hits.end(); @@ -1763,6 +1768,9 @@ int Ebofs::apply_write(Onode *on, off_t off, off_t len, const bufferlist& bl) } } + // take read waiters + bh->take_read_waiters(finished); // this is a bit aggressive, since we kick waiters on partials + // need to split off partial? (partials can only be ONE block) if ((bh->is_missing() || bh->is_rx()) && bh->length() > 1) { if (bh->start() == bstart && partial_head) { @@ -1846,11 +1854,13 @@ int Ebofs::apply_write(Onode *on, off_t off, off_t len, const bufferlist& bl) dout(10) << "apply_write rx -> partial " << *bh << dendl; assert(bh->length() == 1); bc.mark_partial(bh); + assert(!commit_starting); // otherwise, but in check_partial_edges } else if (bh->is_missing() || bh->is_corrupt()) { dout(10) << "apply_write missing -> partial " << *bh << dendl; assert(bh->length() == 1); bc.mark_partial(bh); + assert(!commit_starting); // otherwise, but in check_partial_edges // take care to read from _old_ disk block locations! if (bh->start() == bstart) @@ -2010,13 +2020,14 @@ int Ebofs::apply_write(Onode *on, off_t off, off_t len, const bufferlist& bl) oc->scrub_csums(); dirty_onode(on); + finish_contexts(finished); return 0; } int Ebofs::apply_zero(Onode *on, off_t off, size_t len) { - ObjectCache *oc = on->get_oc(&bc); + dout(10) << "apply_zero " << off << "~" << len << " on " << *on << dendl; bool partial_head, partial_tail; if (check_partial_edges(on, off, len, partial_head, partial_tail) < 0) @@ -2024,15 +2035,17 @@ int Ebofs::apply_zero(Onode *on, off_t off, size_t len) // zero edges // head? - if (partial_head) { - assert(off & EBOFS_BLOCK_MASK); + if (off & EBOFS_BLOCK_MASK) { size_t l = EBOFS_BLOCK_SIZE - (off & EBOFS_BLOCK_MASK); if (l > len) l = len; - bufferptr bp(l); - bp.zero(); - bufferlist bl; - bl.push_back(bp); - apply_write(on, off, bl.length(), bl); + if (partial_head) { + bufferptr bp(l); + bp.zero(); + bufferlist bl; + bl.push_back(bp); + int r = apply_write(on, off, bl.length(), bl); + assert(r == 0); + } off += l; len -= l; } @@ -2045,7 +2058,8 @@ int Ebofs::apply_zero(Onode *on, off_t off, size_t len) bp.zero(); bufferlist bl; bl.push_back(bp); - apply_write(on, off+len-bl.length(), bp.length(), bl); + int r = apply_write(on, off+len-bl.length(), bp.length(), bl); + assert(r == 0); len -= l; } if (len == 0) return 0; // done! @@ -2059,9 +2073,9 @@ int Ebofs::apply_zero(Onode *on, off_t off, size_t len) assert(blen > 0); map hits; + ObjectCache *oc = on->get_oc(&bc); oc->map_write(bstart, blen, hits, super_epoch); - list finished; map::iterator p = hits.begin(); while (p != hits.end()) { map::iterator next = p; @@ -2090,7 +2104,7 @@ int Ebofs::apply_zero(Onode *on, off_t off, size_t len) on->uncommitted.subtract(olduncom); dout(10) << "_zeroed new uncom " << on->uncommitted << dendl; - finish_contexts(finished, -1); + dirty_onode(on); return 0; } @@ -2773,7 +2787,6 @@ int Ebofs::_write(pobject_t oid, off_t offset, size_t length, const bufferlist& // apply write to buffer cache if (length > 0) { int r = apply_write(on, offset, length, bl); - dout(1) << "apply_write returned " << r << dendl; if (r == 0) break; // yay! assert(r < 0); diff --git a/branches/ebofs/ebofs/Onode.h b/branches/ebofs/ebofs/Onode.h index 85bd658d05ba1..a8ef3cbb13d26 100644 --- a/branches/ebofs/ebofs/Onode.h +++ b/branches/ebofs/ebofs/Onode.h @@ -180,7 +180,7 @@ public: for (map::iterator p = extent_map.begin(); p != extent_map.end(); p++) { - cout << " verify_extents " << p->first << ": " << p->second << std::endl; + //cout << " verify_extents " << p->first << ": " << p->second << std::endl; assert(pos == p->first); pos += p->second.ex.length; if (p->second.ex.start) { @@ -192,7 +192,7 @@ public: } } } - cout << " verify_extents got csum " << hex << csum << " want " << data_csum << dec << std::endl; + //cout << " verify_extents got csum " << hex << csum << " want " << data_csum << dec << std::endl; assert(s.size() == count); assert(count == alloc_blocks); diff --git a/branches/ebofs/ebofs/test.ebofs.cc b/branches/ebofs/ebofs/test.ebofs.cc index 8dcc4961e2666..dd78b8ff9a11e 100644 --- a/branches/ebofs/ebofs/test.ebofs.cc +++ b/branches/ebofs/ebofs/test.ebofs.cc @@ -217,13 +217,13 @@ int main(int argc, char **argv) } utime_t now = g_clock.now(); - utime_t dur(seconds,0); + utime_t dur(seconds, 0); utime_t end = now + dur; cout << "stop at " << end << std::endl; while (now < end) { sleep(1); now = g_clock.now(); - cout << now << std::endl; + //cout << now << std::endl; } cout << "stopping" << std::endl; -- 2.39.5