]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
*** empty log message ***
authorsage <sage@29311d96-e01e-0410-9327-a35deaab8ce9>
Tue, 6 Dec 2005 01:11:02 +0000 (01:11 +0000)
committersage <sage@29311d96-e01e-0410-9327-a35deaab8ce9>
Tue, 6 Dec 2005 01:11:02 +0000 (01:11 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@518 29311d96-e01e-0410-9327-a35deaab8ce9

ceph/ebofs/AlignedBufferPool.h
ceph/ebofs/Ebofs.cc
ceph/ebofs/Ebofs.h
ceph/ebofs/Onode.h
ceph/ebofs/nodes.h
ceph/ebofs/types.h
ceph/include/buffer.h

index 1ada70c3722d7d820e947bb57f93f6e4d338dd2b..3347bd7abe879d5037f788e09dd26880470591ea 100644 (file)
 #include <list>
 using namespace std;
 
+#include <sys/mman.h>
+
 #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<char*>     allocated; // my pools
-  list<char*>     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<char*>::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<bufferptr>::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) );
   }
 
 
index 0e3bcd2600531d87732d34dda0f1b708a586ce52..96b55aa0290443120cf8101cbab703d4e964f673 100644 (file)
@@ -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;
index 39f66652780cb51c1a086ee95a9e9e221e5cf542..8702da0e851e465aa0b41116aa69be1fbc7a1cf0 100644 (file)
@@ -41,10 +41,10 @@ class Ebofs : public ObjectStore {
   block_t      free_blocks;
   Allocator    allocator;
   friend class Allocator;
-
+  
   // ** buffers **
   AlignedBufferPool bufferpool;
-
+  
 
   // ** tables and sets **
   // nodes
index 92ad38a077208389a86ef9bb73fcac5e4f01315a..dba1a5e3c6a47693de8924fc8cd10a0acef91f64 100644 (file)
@@ -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:
index 93d02c738767d934d90d573d78701221d3cf730b..b12f50f65f81dbbd9b1ed7e7514032d6cf645f87 100644 (file)
@@ -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<int>::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;
index aadadc4f38afdb1c5bb3424485c86dd03d8381d7..0931c3ca61369a7ec9c8f02a0f896e527e83dfb0 100644 (file)
@@ -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
index e198800fc05108eea18a5c04328bc37304b46229..3ec8958f11162025d8d9678b8eecf6bb9cdf6a44 100644 (file)
@@ -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;