From 5a7abb0b39fcc3aa9601aa81f4440d6efa3f4f02 Mon Sep 17 00:00:00 2001 From: sage Date: Sat, 31 Dec 2005 09:36:49 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@557 29311d96-e01e-0410-9327-a35deaab8ce9 --- ceph/ebofs/BufferCache.cc | 29 ++++++++++++++++++++++------- ceph/ebofs/BufferCache.h | 5 +++-- ceph/ebofs/Ebofs.cc | 10 +++++----- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/ceph/ebofs/BufferCache.cc b/ceph/ebofs/BufferCache.cc index f2c1352c3d6fc..1b38380981965 100644 --- a/ceph/ebofs/BufferCache.cc +++ b/ceph/ebofs/BufferCache.cc @@ -32,15 +32,18 @@ void BufferHead::finish_partials() assert(is_tx()); oc->bc->bh_cancel_write(this); } - - if (p->second.epoch == epoch_modified) { // FIXME: this'll break when we add journaling! ick. - // current epoch! make like a bh_write. + + vector exv; + oc->on->map_extents(object_loc.start, 1, exv); + assert(exv.size() == 1); + if (exv[0].start == p->first) { + // current block! make like a bh_write. assert(cur_block == 0); cur_block = p->first; - dout(1) << "finish_partials same epoch, doing a bh_write on " << p->first << " on " << *this << endl; + dout(10) << "finish_partials same block, doing a bh_write on " << p->first << " on " << *this << endl; } else { // past epoch. just write. - dout(1) << "finish_partials prior epoch, writing to " << p->first << " on " << *this << endl; + dout(10) << "finish_partials different block, writing to " << p->first << " on " << *this << endl; oc->bc->dev.write( p->second.block, 1, bl, new C_OC_PartialTxFinish( oc->bc, p->second.epoch ), "finish_partials"); @@ -54,8 +57,10 @@ void BufferHead::finish_partials() // same as epoch_modified, so do a normal bh_write. // assert: this should match the current onode's block oc->bc->mark_dirty(this); + if (tx_ioh) + oc->bc->bh_cancel_write(this); oc->bc->bh_write(oc->on, this, cur_block); - oc->bc->dec_unflushed(epoch_modified); // undo the queued partial inc + oc->bc->dec_unflushed(epoch_modified); // undo the queued partial inc. (bh_write just inced it) } else oc->bc->mark_clean(this); } @@ -553,7 +558,10 @@ BufferHead *BufferCache::split(BufferHead *orig, block_t after) // split off right BufferHead *right = new BufferHead(orig->get_oc()); right->set_version(orig->get_version()); + right->epoch_modified = orig->epoch_modified; + right->last_flushed = orig->last_flushed; right->set_state(orig->get_state()); + block_t newleftlen = after - orig->start(); right->set_start( after ); right->set_length( orig->length() - newleftlen ); @@ -678,6 +686,13 @@ void BufferCache::bh_write(Onode *on, BufferHead *bh, block_t shouldbe) on->oc->get(); inc_unflushed( bh->epoch_modified ); + + // 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 << endl; + dec_unflushed( bh->partial_write[ex.start].epoch ); + bh->partial_write.erase(ex.start); + } } @@ -763,7 +778,7 @@ void BufferCache::bh_queue_partial_write(Onode *on, BufferHead *bh) block_t b = exv[0].start; assert(exv[0].length == 1); - dout(1) << "bh_queue_partial_write " << *on << " on " << *bh << " block " << b << endl; + dout(10) << "bh_queue_partial_write " << *on << " on " << *bh << " block " << b << " epoch " << bh->epoch_modified << endl; // copy map state, queue for this block diff --git a/ceph/ebofs/BufferCache.h b/ceph/ebofs/BufferCache.h index 037bd1066cd9f..910ca017a0cf4 100644 --- a/ceph/ebofs/BufferCache.h +++ b/ceph/ebofs/BufferCache.h @@ -50,8 +50,9 @@ class BufferHead : public LRUObject { private: map partial; // partial dirty content overlayed onto incoming data - + public: map partial_write; // queued writes w/ partial content + private: int ref; int state; @@ -272,7 +273,7 @@ class BufferHead : public LRUObject { inline ostream& operator<<(ostream& out, BufferHead& bh) { out << "bufferhead(" << bh.start() << "~" << bh.length(); - //out << " v" << bh.get_version() << "/" << bh.get_last_flushed(); + out << " v" << bh.get_version() << "/" << bh.get_last_flushed(); if (bh.is_missing()) out << " missing"; if (bh.is_dirty()) out << " dirty"; if (bh.is_clean()) out << " clean"; diff --git a/ceph/ebofs/Ebofs.cc b/ceph/ebofs/Ebofs.cc index c2f544f26eaa8..89d4485a487ab 100644 --- a/ceph/ebofs/Ebofs.cc +++ b/ceph/ebofs/Ebofs.cc @@ -1202,6 +1202,7 @@ void Ebofs::apply_write(Onode *on, size_t len, off_t off, bufferlist& bl) // map into blocks off_t opos = off; // byte pos in object size_t zleft = 0; // zeros left to write + size_t left = len; // bytes left block_t bstart = off / EBOFS_BLOCK_SIZE; @@ -1210,16 +1211,16 @@ void Ebofs::apply_write(Onode *on, size_t len, off_t off, bufferlist& bl) opos = on->object_size; bstart = on->object_size / EBOFS_BLOCK_SIZE; } - if (bl.length() == 0) { - zleft += len; - len = 0; - } if (off+len > on->object_size) { dout(10) << "apply_write extending size on " << *on << ": " << on->object_size << " -> " << off+len << endl; on->object_size = off+len; dirty_onode(on); } + if (bl.length() == 0) { + zleft += len; + left = 0; + } if (zleft) dout(10) << "apply_write zeroing first " << zleft << " bytes of " << *on << endl; @@ -1243,7 +1244,6 @@ void Ebofs::apply_write(Onode *on, size_t len, off_t off, bufferlist& bl) // copy from bl into buffer cache unsigned blpos = 0; // byte pos in input buffer - size_t left = len; // bytes left // write data into buffers for (map::iterator i = hits.begin(); -- 2.39.5