From 6978f76b750078c28e650d09706af1418edbefba Mon Sep 17 00:00:00 2001 From: sageweil Date: Wed, 21 Nov 2007 18:34:47 +0000 Subject: [PATCH] basic read/write support for holes. with bugs. git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2102 29311d96-e01e-0410-9327-a35deaab8ce9 --- branches/ebofs/ebofs/BufferCache.cc | 6 ++-- branches/ebofs/ebofs/BufferCache.h | 6 +++- branches/ebofs/ebofs/Ebofs.cc | 53 +++++++++++++++++++++-------- branches/ebofs/ebofs/Onode.h | 9 ++--- branches/ebofs/include/buffer.h | 6 ++++ 5 files changed, 56 insertions(+), 24 deletions(-) diff --git a/branches/ebofs/ebofs/BufferCache.cc b/branches/ebofs/ebofs/BufferCache.cc index a51b25c40c715..c7b102c8f5925 100644 --- a/branches/ebofs/ebofs/BufferCache.cc +++ b/branches/ebofs/ebofs/BufferCache.cc @@ -343,7 +343,6 @@ int ObjectCache::map_read(block_t start, block_t len, BufferHead *n = new BufferHead(this); n->set_start( cur ); n->set_length( exv[i].length ); - bc->add_bh(n); if (exv[i].start) { missing[cur] = n; dout(20) << "map_read miss " << left << " left, " << *n << dendl; @@ -352,6 +351,7 @@ int ObjectCache::map_read(block_t start, block_t len, n->set_state(BufferHead::STATE_CLEAN); dout(20) << "map_read hole " << left << " left, " << *n << dendl; } + bc->add_bh(n); cur += MIN(left,exv[i].length); left -= MIN(left,exv[i].length); } @@ -403,7 +403,6 @@ int ObjectCache::map_read(block_t start, block_t len, BufferHead *n = new BufferHead(this); n->set_start( cur ); n->set_length( exv[i].length ); - bc->add_bh(n); if (exv[i].start) { missing[cur] = n; dout(20) << "map_read gap " << *n << dendl; @@ -412,6 +411,7 @@ int ObjectCache::map_read(block_t start, block_t len, hits[cur] = n; dout(20) << "map_read hole " << *n << dendl; } + bc->add_bh(n); cur += MIN(left, n->length()); left -= MIN(left, n->length()); } @@ -582,6 +582,8 @@ int ObjectCache::map_write(block_t start, block_t len, BufferHead *n = new BufferHead(this); n->set_start( cur ); n->set_length( glen ); + if (exv[0].start == 0) + n->set_state(BufferHead::STATE_CLEAN); // hole bc->add_bh(n); hits[cur] = n; diff --git a/branches/ebofs/ebofs/BufferCache.h b/branches/ebofs/ebofs/BufferCache.h index 094f444364204..dda4926ea1f09 100644 --- a/branches/ebofs/ebofs/BufferCache.h +++ b/branches/ebofs/ebofs/BufferCache.h @@ -335,7 +335,11 @@ inline ostream& operator<<(ostream& out, BufferHead& bh) 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"; + if (bh.is_clean()) { + out << " clean"; + if (bh.data.length() == 0) + out << " HOLE"; + } if (bh.is_rx()) out << " rx"; if (bh.is_tx()) out << " tx"; if (bh.is_partial()) out << " partial"; diff --git a/branches/ebofs/ebofs/Ebofs.cc b/branches/ebofs/ebofs/Ebofs.cc index f17e3dc299e0b..87b830a1c793a 100644 --- a/branches/ebofs/ebofs/Ebofs.cc +++ b/branches/ebofs/ebofs/Ebofs.cc @@ -1729,7 +1729,10 @@ void Ebofs::apply_write(Onode *on, off_t off, size_t len, const bufferlist& bl) temp.claim(bh->data); //bc.bufferpool.alloc(EBOFS_BLOCK_SIZE*bh->length(), bh->data); bh->data.push_back( buffer::create_page_aligned(EBOFS_BLOCK_SIZE*bh->length()) ); - bh->data.copy_in(0, bh->length()*EBOFS_BLOCK_SIZE, temp); + if (temp.length()) + bh->data.copy_in(0, bh->length()*EBOFS_BLOCK_SIZE, temp); + else + bh->data.zero(); // was a hole bufferlist sub; sub.substr_of(bl, blpos, len_in_bh); @@ -1785,8 +1788,10 @@ void Ebofs::apply_write(Onode *on, off_t off, size_t len, const bufferlist& bl) // old partial? if (bh->is_partial() && - bh->partial_tx_epoch == super_epoch) + bh->partial_tx_epoch == super_epoch) { bc.bh_cancel_partial_write(bh); + bc.bh_cancel_read(bh); // cancel rx (if any) too. + } // mark dirty if (!bh->is_dirty()) @@ -1852,8 +1857,8 @@ void Ebofs::apply_zero(Onode *on, off_t off, size_t len) p = next; } - // free old blocks? if (blen) { + // free old blocks vector old; on->map_extents(bstart, blen, old, 0); for (unsigned i=0; iset_extent(bstart, hole); + + // adjust uncom + interval_set zeroed; + zeroed.insert(bstart, blen); + interval_set olduncom; + olduncom.intersection_of(zeroed, on->uncommitted); + dout(10) << "_zeroed old uncom " << on->uncommitted << " zeroed " << zeroed + << " subtracting " << olduncom << dendl; + on->uncommitted.subtract(olduncom); + dout(10) << "_zeroed new uncom " << on->uncommitted << dendl; } finish_contexts(finished, -1); @@ -1966,23 +1981,31 @@ bool Ebofs::attempt_read(Onode *on, off_t off, size_t len, bufferlist& bl, } else { // copy from a full block. if (bhstart == start && bhend == end) { - bl.append( bh->data ); - pos += bh->data.length(); + if (bh->data.length()) { + dout(10) << "aligned " << (start-bhstart) << "~" << (end-start) << " of " << bh->data.length() << " in " << *bh << dendl; + bl.append( bh->data ); + pos += bh->data.length(); + } else { + dout(10) << "aligned " << (start-bhstart) << "~" << (end-start) << " of hole in " << *bh << dendl; + bl.append_zero(end-start); + pos += end-start; + } } else { - bufferlist frag; - dout(10) << "substr " << (start-bhstart) << "~" << (end-start) << " of " << bh->data.length() << " in " << *bh << dendl; - frag.substr_of(bh->data, start-bhstart, end-start); - pos += frag.length(); - bl.claim_append( frag ); + if (bh->data.length()) { + dout(10) << "substr " << (start-bhstart) << "~" << (end-start) << " of " << bh->data.length() << " in " << *bh << dendl; + bufferlist frag; + frag.substr_of(bh->data, start-bhstart, end-start); + pos += frag.length(); + bl.claim_append( frag ); + } else { + dout(10) << "substr " << (start-bhstart) << "~" << (end-start) << " of hole in " << *bh << dendl; + bl.append_zero(end-start); + pos += end-start; + } } } curblock = bh->end(); - /* this assert is more trouble than it's worth - assert((off_t)(curblock*EBOFS_BLOCK_SIZE) == pos || // should be aligned with next block - end != bhend || // or we ended midway through bh - (bh->last() == blast && end == bhend)); // ended last block ** FIXME WRONG??? - */ } assert(bl.length() == len); diff --git a/branches/ebofs/ebofs/Onode.h b/branches/ebofs/ebofs/Onode.h index 5d6734dfc0d78..dc136c8b01b23 100644 --- a/branches/ebofs/ebofs/Onode.h +++ b/branches/ebofs/ebofs/Onode.h @@ -224,18 +224,15 @@ public: // past the end? if (offset > last_block) { if (ex.start) { - block_t skip = offset - last_block; - - // hole extent_map[last_block].ex.start = 0; - extent_map[last_block].ex.length = skip; - + extent_map[last_block].ex.length = offset - last_block; extent_map[offset].ex = ex; extent_map[offset].resize_tail(); last_block = offset+ex.length; alloc_blocks += ex.length; + } else { + // ignore attempt to set a trailing "hole" } - // else ignore trailing "hole" return; } diff --git a/branches/ebofs/include/buffer.h b/branches/ebofs/include/buffer.h index 5e48b6ce91bf6..ded9fe28741ab 100644 --- a/branches/ebofs/include/buffer.h +++ b/branches/ebofs/include/buffer.h @@ -755,6 +755,12 @@ public: _buffers.push_back(*p); } + void append_zero(unsigned len) { + ptr bp(len); + bp.zero(); + append(bp); + } + /* * get a char -- 2.39.5