From 0b76b3d0e98d7d2ef73d5e368b98a5348940779f Mon Sep 17 00:00:00 2001 From: sage Date: Tue, 6 Dec 2005 01:11:02 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@518 29311d96-e01e-0410-9327-a35deaab8ce9 --- ceph/ebofs/AlignedBufferPool.h | 101 +++++++-------------------------- ceph/ebofs/Ebofs.cc | 16 +++--- ceph/ebofs/Ebofs.h | 4 +- ceph/ebofs/Onode.h | 38 ++++--------- ceph/ebofs/nodes.h | 6 +- ceph/ebofs/types.h | 34 ++++++++++- ceph/include/buffer.h | 4 +- 7 files changed, 81 insertions(+), 122 deletions(-) diff --git a/ceph/ebofs/AlignedBufferPool.h b/ceph/ebofs/AlignedBufferPool.h index 1ada70c3722d7..3347bd7abe879 100644 --- a/ceph/ebofs/AlignedBufferPool.h +++ b/ceph/ebofs/AlignedBufferPool.h @@ -6,110 +6,53 @@ #include using namespace std; +#include + #include "include/buffer.h" #include "include/bufferlist.h" -//#undef dout -//#define dout(x) if (x <= g_conf.debug) cout << "bufferpool " - class AlignedBufferPool { - int buffer_size; - int num_buffers; - int num_free; - - static const int MIN_ALLOC = 1024*1024; - - list allocated; // my pools - list freelist; // my freelist - - + int alignment; // err, this isn't actually enforced! we just use mmap. public: - AlignedBufferPool(int size) : buffer_size(size), num_buffers(0), num_free(0) {} + AlignedBufferPool(int a) : alignment(a) {} ~AlignedBufferPool() { - if (num_free != num_buffers) { - dout(1) << "WARNING: " << num_buffers-num_free << "/" << num_buffers << " buffers still allocated" << endl; - } - for (list::iterator i = allocated.begin(); - i != allocated.end(); - i++) - delete[] *i; } - - // individual buffers - void free(bufferptr& bp) { - free(bp.c_str()); - } - void free(char *p) { - dout(10) << "bufferpool.free " << (void*)p << endl; - freelist.push_back(p); - num_free++; + void free(char *p, unsigned len) { + dout(10) << "bufferpool.free " << (void*)p << " len " << len << endl; + munmap(p, len); } - static void aligned_buffer_free_func(void *arg, char *ptr) { + static void aligned_buffer_free_func(void *arg, char *ptr, unsigned len) { AlignedBufferPool *pool = (AlignedBufferPool*)arg; - pool->free(ptr); + pool->free(ptr, len); } + buffer *alloc(int bytes) { + assert(bytes % alignment == 0); + char *p = (char*)mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + assert(p); - // allocate a single buffer - buffer* alloc() { - // get more memory? - if (freelist.empty()) { - int get = (num_buffers ? num_buffers:1) * buffer_size; - if (get < MIN_ALLOC) get = MIN_ALLOC; - - char *n = new char[get]; - assert(n); - memset(n, 0, get); - allocated.push_back(n); - - // add items to freelist - int num = get / buffer_size; - char *p = n; - int misalign = (unsigned)p % buffer_size; - if (misalign) { - p += buffer_size - misalign; - num--; - } - dout(2) << "bufferpool.alloc allocated " << get << " bytes, got " << num << " aligned buffers" << endl; - while (num--) { - freelist.push_back( p ); - num_free++; - num_buffers++; - p += buffer_size; - } - } - - // allocate one. - assert(!freelist.empty()); - char *p = freelist.front(); dout(10) << "bufferpool.alloc " << (void*)p << endl; - freelist.pop_front(); - num_free--; - return new buffer(p, buffer_size, BUFFER_MODE_NOCOPY|BUFFER_MODE_NOFREE|BUFFER_MODE_CUSTOMFREE, - buffer_size, + + return new buffer(p, bytes, BUFFER_MODE_NOCOPY|BUFFER_MODE_NOFREE|BUFFER_MODE_CUSTOMFREE, + bytes, aligned_buffer_free_func, this); } + // allocate a single buffer + buffer* alloc_page() { + return alloc(alignment); + } // bufferlists - void alloc_list(int n, bufferlist& bl) { - bl.clear(); - while (n--) { - bl.push_back(alloc()); - } - } - void free_list(bufferlist& bl) { - for (list::iterator i = bl.buffers().begin(); - i != bl.buffers().end(); - i++) - free(*i); + void alloc(int bytes, bufferlist& bl) { bl.clear(); + bl.push_back( alloc(bytes) ); } diff --git a/ceph/ebofs/Ebofs.cc b/ceph/ebofs/Ebofs.cc index 0e3bcd2600531..96b55aa029044 100644 --- a/ceph/ebofs/Ebofs.cc +++ b/ceph/ebofs/Ebofs.cc @@ -175,7 +175,7 @@ int Ebofs::write_super() sb.table_nodepool.region_loc[i] = table_nodepool.get_region_loc(i); } - bufferptr bp = bufferpool.alloc(); + bufferptr bp = bufferpool.alloc(EBOFS_BLOCK_SIZE); memcpy(bp.c_str(), (const char*)&sb, sizeof(sb)); dev.write(bno, 1, bp); return 0; @@ -220,7 +220,7 @@ Onode* Ebofs::get_onode(object_t oid) // read it! bufferlist bl; - bufferpool.alloc_list( onode_loc.length, bl ); + bufferpool.alloc( EBOFS_BLOCK_SIZE*onode_loc.length, bl ); dev.read( onode_loc.start, onode_loc.length, bl ); // parse data block @@ -260,7 +260,7 @@ void Ebofs::write_onode(Onode *on) unsigned blocks = (bytes-1)/EBOFS_BLOCK_SIZE + 1; bufferlist bl; - bufferpool.alloc_list( blocks, bl ); + bufferpool.alloc( EBOFS_BLOCK_SIZE*blocks, bl ); // place on disk if (on->onode_loc.length < blocks) { @@ -385,7 +385,7 @@ Cnode* Ebofs::get_cnode(object_t cid) // read it! bufferlist bl; - bufferpool.alloc_list( cnode_loc.length, bl ); + bufferpool.alloc( EBOFS_BLOCK_SIZE*cnode_loc.length, bl ); dev.read( cnode_loc.start, cnode_loc.length, bl ); // parse data block @@ -415,7 +415,7 @@ void Ebofs::write_cnode(Cnode *cn) unsigned blocks = (bytes-1)/EBOFS_BLOCK_SIZE + 1; bufferlist bl; - bufferpool.alloc_list( blocks, bl ); + bufferpool.alloc( EBOFS_BLOCK_SIZE*blocks, bl ); // place on disk if (cn->cnode_loc.length < blocks) { @@ -599,7 +599,7 @@ void Ebofs::bh_read(Onode *on, BufferHead *bh) on->map_extents(bh->start(), bh->length(), ex); // alloc new buffer - bc.bufferpool.alloc_list(bh->length(), bh->data); // new buffers! + bc.bufferpool.alloc(EBOFS_BLOCK_SIZE*bh->length(), bh->data); // new buffers! // lay out on disk block_t bhoff = 0; @@ -745,7 +745,7 @@ void Ebofs::apply_write(Onode *on, size_t len, off_t off, bufferlist& bl) if (bh->partial_is_complete(on->object_size)) { dout(10) << "apply_write completed partial " << *bh << endl; - bc.bufferpool.alloc_list(bh->length(), bh->data); // new buffers! + bc.bufferpool.alloc(EBOFS_BLOCK_SIZE*bh->length(), bh->data); // new buffers! bh->data.zero(); bh->apply_partial(); bc.mark_dirty(bh); @@ -804,7 +804,7 @@ void Ebofs::apply_write(Onode *on, size_t len, off_t off, bufferlist& bl) assert(zleft+left >= (off_t)(EBOFS_BLOCK_SIZE*bh->length())); // alloc new buffers. - bc.bufferpool.alloc_list(bh->length(), bh->data); + bc.bufferpool.alloc(EBOFS_BLOCK_SIZE*bh->length(), bh->data); // copy! unsigned len_in_bh = bh->length()*EBOFS_BLOCK_SIZE; diff --git a/ceph/ebofs/Ebofs.h b/ceph/ebofs/Ebofs.h index 39f66652780cb..8702da0e851e4 100644 --- a/ceph/ebofs/Ebofs.h +++ b/ceph/ebofs/Ebofs.h @@ -41,10 +41,10 @@ class Ebofs : public ObjectStore { block_t free_blocks; Allocator allocator; friend class Allocator; - + // ** buffers ** AlignedBufferPool bufferpool; - + // ** tables and sets ** // nodes diff --git a/ceph/ebofs/Onode.h b/ceph/ebofs/Onode.h index 92ad38a077208..dba1a5e3c6a47 100644 --- a/ceph/ebofs/Onode.h +++ b/ceph/ebofs/Onode.h @@ -1,38 +1,22 @@ #ifndef __EBOFS_ONODE_H #define __EBOFS_ONODE_H - #include "include/lru.h" #include "types.h" #include "BufferCache.h" -class AttrVal { - public: - char *data; - int len; - AttrVal() : data(0), len(0) {} - AttrVal(char *from, int l) : - len(l) { - data = new char[len]; - memcpy(data, from, len); - } - AttrVal(const AttrVal &other) { - len = other.len; - data = new char[len]; - memcpy(data, other.data, len); - } - AttrVal& operator=(const AttrVal &other) { - if (data) delete[] data; - len = other.len; - data = new char[len]; - memcpy(data, other.data, len); - return *this; - } - ~AttrVal() { - delete[] data; - } -}; +/* + * object node (like an inode) + * + * holds object metadata, including + * size + * allocation (extent list) + * attributes + * + */ + + class Onode : public LRUObject { private: diff --git a/ceph/ebofs/nodes.h b/ceph/ebofs/nodes.h index 93d02c738767d..b12f50f65f81d 100644 --- a/ceph/ebofs/nodes.h +++ b/ceph/ebofs/nodes.h @@ -237,7 +237,7 @@ class NodePool { for (block_t boff = 0; boff < r->location.length; boff += EBOFS_NODE_BLOCKS) { nodeid_t nid = NodeRegion::make_nodeid(r->get_region_id(), boff); - bufferptr bp = bufferpool.alloc(); + bufferptr bp = bufferpool.alloc(EBOFS_NODE_BYTES); dev.read(r->location.start + (block_t)boff, EBOFS_NODE_BLOCKS, bp); @@ -296,7 +296,7 @@ class NodePool { r->committing = r->limbo; r->limbo.clear(); - bufferptr freebuffer = bufferpool.alloc(); + bufferptr freebuffer = bufferpool.alloc(EBOFS_NODE_BYTES); Node freenode(1, freebuffer); freenode.set_status(Node::STATUS_FREE); for (set::iterator i = r->committing.begin(); @@ -347,7 +347,7 @@ class NodePool { return -1; } Node* new_node() { - bufferptr bp = bufferpool.alloc(); + bufferptr bp = bufferpool.alloc(EBOFS_NODE_BYTES); Node *n = new Node(new_nodeid(), bp); n->clear(); dbtout << "pool.new_node " << n->get_id() << endl; diff --git a/ceph/ebofs/types.h b/ceph/ebofs/types.h index aadadc4f38afd..0931c3ca61369 100644 --- a/ceph/ebofs/types.h +++ b/ceph/ebofs/types.h @@ -18,7 +18,6 @@ using namespace __gnu_cxx; #define MAX(a,b) ((a)>=(b) ? (a):(b)) - /* - this is to make some of the STL types work with 64 bit values, string hash keys, etc. - added when i was using an old STL.. maybe try taking these out and see if things @@ -150,6 +149,39 @@ struct ebofs_super { +/* + * really simple container for (collection|object) attribute values, + * which are a (void*,int) pair. hide associated memory management + * ugliness. + */ +class AttrVal { + public: + char *data; + int len; + AttrVal() : data(0), len(0) {} + AttrVal(char *from, int l) : + len(l) { + data = new char[len]; + memcpy(data, from, len); + } + AttrVal(const AttrVal &other) { + len = other.len; + data = new char[len]; + memcpy(data, other.data, len); + } + AttrVal& operator=(const AttrVal &other) { + if (data) delete[] data; + len = other.len; + data = new char[len]; + memcpy(data, other.data, len); + return *this; + } + ~AttrVal() { + delete[] data; + } +}; + + #endif diff --git a/ceph/include/buffer.h b/ceph/include/buffer.h index e198800fc0510..3ec8958f11162 100644 --- a/ceph/include/buffer.h +++ b/ceph/include/buffer.h @@ -43,7 +43,7 @@ extern Mutex bufferlock; extern long buffer_total_alloc; -typedef void (buffer_free_func_t)(void*,char*); +typedef void (buffer_free_func_t)(void*,char*,unsigned); /* @@ -98,7 +98,7 @@ class buffer { bdbout(1) << "buffer.des " << *this << endl; if (free_func) { bdbout(1) << "buffer.custom_free_func " << free_func_arg << " " << (void*)_dataptr << endl; - free_func( free_func_arg, _dataptr ); + free_func( free_func_arg, _dataptr, _alloc_len ); } else if (_dataptr && _myptr) { bdbout(1) << "buffer.free " << (void*)_dataptr << endl; -- 2.39.5