From a21f6ec7030ab8d1cdd970523b48a0610b5a60a8 Mon Sep 17 00:00:00 2001 From: carlosm Date: Thu, 21 Jul 2005 09:15:56 +0000 Subject: [PATCH] Modified Files: client/Buffercache.cc client/Client.cc Successfully finishes openssh trace - except dirty shutdown: fakemessenger: last shutdown unsetting messenger kicker thread finish (i woke up but no messages, bye) fakesyn: client/Buffercache.cc:27: Bufferhead::~Bufferhead(): Assertion `state == 1' failed. git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@467 29311d96-e01e-0410-9327-a35deaab8ce9 --- ceph/client/Buffercache.cc | 47 +++++++++++++++++++++++++++----------- ceph/client/Client.cc | 16 +++++++++---- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/ceph/client/Buffercache.cc b/ceph/client/Buffercache.cc index 85c97722d1003..e07c166495cc0 100644 --- a/ceph/client/Buffercache.cc +++ b/ceph/client/Buffercache.cc @@ -69,7 +69,8 @@ void Bufferhead::alloc_buffers(size_t size) size -= g_conf.client_bcache_alloc_maxsize; bc->increase_size(g_conf.client_bcache_alloc_maxsize); } - dout(7) << "bc: allocated " << bl.buffers().size() << " buffers (" << bl.length() << " bytes) " << endl; + dout(6) << "bc: allocated " << bl.buffers().size() << " buffers (" << bl.length() << " bytes) " << endl; + assert(bl.length() == size); } void Bufferhead::miss_start(size_t miss_len) @@ -87,6 +88,7 @@ void Bufferhead::miss_finish() if (bl.length() == 0) { alloc_buffers(miss_len); bl.zero(); + dout(6) << "bc: miss_finish: allocated zeroed buffer len: " << bl.length() << endl; } else { bc->increase_size(bl.length()); } @@ -245,24 +247,39 @@ map::iterator Filecache::overlap(size_t len, off_t off) { // returns iterator to buffer overlapping specified extent or end() if no overlap exists dout(7) << "bc: overlap " << len << " " << off << endl; + + if (buffer_map.empty()) return buffer_map.end(); + + // find first buffer with offset >= off map::iterator it = buffer_map.lower_bound(off); - if (it == buffer_map.end() || it->first < off + len) { - dout(10) << "bc: overlap -- either no lower bound or overlap found" << endl; + + // Found buffer with exact offset + if (it != buffer_map.end() && it->first == off) { + dout(6) << "bc: overlap -- found buffer with exact offset" << endl; return it; - } else if (it == buffer_map.begin()) { - dout(10) << "bc: overlap -- extent is below where buffer_map begins" << endl; - return buffer_map.end(); - } else { - dout(10) << "bc: overlap -- examining previous buffer" << endl; + } + + // examine previous buffer (< off) first in case of two overlaps + if (it != buffer_map.begin()) { it--; if (it->first + it->second->length() > off) { - dout(10) << "bc: overlap -- found overlap with previous buffer" << endl; + dout(6) << "bc: overlap -- found overlap with previous buffer" << endl; return it; } else { - dout(10) << "bc: overlap -- no overlap with previous buffer" << endl; - return buffer_map.end(); + dout(6) << "bc: overlap -- no overlap with previous buffer" << endl; + it++; } } + + // then examine current buffer (> off) + if (it != buffer_map.end() && it->first < off + len) { + dout(6) << "bc: overlap -- overlap found" << endl; + return it; + } + + // give up + dout(6) << "bc: overlap -- no overlap found" << endl; + return buffer_map.end(); } map::iterator @@ -378,7 +395,7 @@ int Filecache::copy_out(size_t size, off_t offset, char *dst) //assert(offset + size <= length()); doesn't hold after trim_bcache int rvalue = size; - map::iterator curbuf = overlap(size, offset); + map::iterator curbuf = buffer_map.lower_bound(offset); if (curbuf == buffer_map.end() || curbuf->first > offset) { return -1; } @@ -421,7 +438,11 @@ void Buffercache::dirty(inodeno_t ino, size_t size, off_t offset, const char *sr Filecache *fc = get_fc(ino); assert(offset >= 0); - map::iterator curbuf = fc->overlap(size, offset); + map::iterator curbuf = fc->buffer_map.lower_bound(offset); + if (curbuf == fc->buffer_map.end() || curbuf->first > offset) { + assert(curbuf != fc->buffer_map.begin()); + curbuf--; + } offset -= curbuf->first; assert(offset >= 0); diff --git a/ceph/client/Client.cc b/ceph/client/Client.cc index 39cb47d5041e8..7593c451e7e61 100644 --- a/ceph/client/Client.cc +++ b/ceph/client/Client.cc @@ -1457,7 +1457,7 @@ int Client::read(fh_t fh, char *buf, size_t size, off_t offset) if (hits.count(offset)) { // sweet -- we can return stuff immediately: find out how much - dout(7) << "read bc hit" << endl; + dout(6) << "read bc hit" << endl; rvalue = (int)bc.touch_continuous(hits, size, offset); assert(rvalue > 0); rvalue = fc->copy_out((size_t)rvalue, offset, buf); @@ -1469,7 +1469,7 @@ int Client::read(fh_t fh, char *buf, size_t size, off_t offset) // issue reads for holes int hole_rvalue = 0; //FIXME: don't really need to track rvalue in MissFinish context for (hole = holes.begin(); hole != holes.end(); hole++) { - dout(7) << "read bc miss" << endl; + dout(6) << "read bc miss" << endl; off_t hole_offset = hole->first; size_t hole_size = hole->second; assert(fc->buffer_map.count(hole_offset) == 0); @@ -1482,13 +1482,19 @@ int Client::read(fh_t fh, char *buf, size_t size, off_t offset) bh->miss_start(hole_size); C_Client_MissFinish *onfinish = new C_Client_MissFinish(bh, &client_lock, &hole_rvalue); filer->read(in->inode.ino, g_OSD_FileLayout, hole_size, hole_offset, &(bh->bl), onfinish); - dout(7) << "read bc miss: issued osd read len: " << hole_size << " off: " << hole_offset << endl; + dout(6) << "read bc miss: issued osd read len: " << hole_size << " off: " << hole_offset << endl; } if (rvalue == 0) { // we need to wait for the first buffer dout(7) << "read bc miss: waiting for first buffer" << endl; - Bufferhead *bh = fc->buffer_map[offset]; + map::iterator it = fc->buffer_map.lower_bound(offset); + if (it == fc->buffer_map.end() || it->first > offset) { + assert(it != fc->buffer_map.begin()); + it--; + } + Bufferhead *bh = it->second; + assert(bh->offset + bh->length() > offset); #if 0 Bufferhead *bh; if (curbuf == fc->buffer_map.end() && fc->buffer_map.count(offset)) { @@ -1507,7 +1513,7 @@ int Client::read(fh_t fh, char *buf, size_t size, off_t offset) // buffer is filled -- see how much we can return hits.clear(); rx.clear(); tx.clear(); holes.clear(); fc->map_existing(size, offset, hits, rx, tx, holes); // FIXME: overkill - assert(hits.count(offset)); + //assert(hits.count(offset)); rvalue = (int)bc.touch_continuous(hits, size, offset); fc->copy_out(rvalue, offset, buf); dout(7) << "read bc no hit: returned first " << rvalue << " bytes" << endl; -- 2.39.5