]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
*** empty log message ***
authorsage <sage@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 15 Dec 2005 23:55:54 +0000 (23:55 +0000)
committersage <sage@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 15 Dec 2005 23:55:54 +0000 (23:55 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@526 29311d96-e01e-0410-9327-a35deaab8ce9

14 files changed:
ceph/config.cc
ceph/config.h
ceph/doc/osd_outline.txt [new file with mode: 0644]
ceph/doc/shared_write_states_nogo.txt [new file with mode: 0644]
ceph/ebofs/Allocator.cc
ceph/ebofs/Allocator.h
ceph/ebofs/BufferCache.cc
ceph/ebofs/BufferCache.h
ceph/ebofs/Cnode.h [new file with mode: 0644]
ceph/ebofs/Ebofs.cc
ceph/ebofs/Ebofs.h
ceph/ebofs/Table.h
ceph/ebofs/mkfs.ebofs.cc
ceph/ebofs/nodes.h

index 7d03cf6f012cde4c246e4532c3bd8f1f9de2085d..9fc8de9fdc0a9d8858511d81484ed1d2fd43bed7 100644 (file)
@@ -57,6 +57,7 @@ md_config_t g_conf = {
   debug_filer: 0,
   debug_client: 0,
   debug_osd: 0,
+  debug_ebofs: 1,
   debug_bdev: 1,         // block device
   
   // --- client ---
@@ -113,7 +114,7 @@ md_config_t g_conf = {
   
   osd_fakestore_syncthreads: 4,
 
-  ebofs_bc_size: 100,    // measured in 4k blocks
+  ebofs_bc_size: (50 *256),    // measured in 4k blocks, or *256 for MB
 
 
   // --- fakeclient (mds regression testing) ---
@@ -204,6 +205,8 @@ void parse_config_options(vector<char*>& args)
          g_conf.debug_client = atoi(args[++i]);
        else if (strcmp(args[i], "--debug_osd") == 0) 
          g_conf.debug_osd = atoi(args[++i]);
+       else if (strcmp(args[i], "--debug_ebofs") == 0) 
+         g_conf.debug_ebofs = atoi(args[++i]);
        else if (strcmp(args[i], "--debug_bdev") == 0) 
          g_conf.debug_bdev = atoi(args[++i]);
 
index 1fdc64fd231dfcae7738970b2cf4f02b9f9839ee..3a78656108ce9dd8828e27a1a9e3c27087793780 100644 (file)
@@ -35,6 +35,7 @@ struct md_config_t {
   int debug_filer;
   int debug_client;
   int debug_osd;
+  int debug_ebofs;
   int debug_bdev;
 
   // client
diff --git a/ceph/doc/osd_outline.txt b/ceph/doc/osd_outline.txt
new file mode 100644 (file)
index 0000000..2c6f328
--- /dev/null
@@ -0,0 +1,37 @@
+
+intro
+
+osd cluster map
+ requirements
+ desireable properties
+ (c)rush
+
+failure detection
+ distributed ping or heartbeat
+ central filter, notifier
+
+design
+ placement seed, class/superset, groups
+
+normal operation
+ reads
+ writes
+
+recovery
+ triggers: failed disk, or total cluster reorganization
+
+ notify
+ peering
+ pull
+ push
+ clean
+
+writes during recovery
+
+graceful data loss + recovery?
+
+
+
+
+
+
diff --git a/ceph/doc/shared_write_states_nogo.txt b/ceph/doc/shared_write_states_nogo.txt
new file mode 100644 (file)
index 0000000..f409617
--- /dev/null
@@ -0,0 +1,39 @@
+
+// stable states          // ------auth-----    -----replica-----
+#define LOCK_SYNC      0  // R . / .  . . WB    same                ... for stat()
+#define LOCK_LOCK      1  // R W / RC . . .     . . / RC . . .      ... for truncate(), fsync()
+#define LOCK_RDONLY    2  // R . / RC R . .     same
+#define LOCK_MIXED     3  // . . / .  R W .     same
+#define LOCK_WRONLY    4  // . . / .  . W WB    same
+
+// transition states
+#define LOCK_GSYNCR    8  // R . / RC . . .     same
+#define LOCK_GSYNCMW   9  // . . / RC . . WB    same
+#define LOCK_GSYNCMW2  9  // . . / RC . . WB    same
+
+#define LOCK_GLOCKSR   5  // R . / RC . . .     . . / RC . . .
+#define LOCK_GLOCKMW   7  // . . / RC . . .     same
+
+#define LOCK_GRDONLYM  10 // . . / .  R . .     same
+#define LOCK_GRDONLYM2 10 //      ---           . . / .  R . .     
+#define LOCK_GRDONLYW  11 // . . / .  . . .     same
+#define LOCK_GRDONLYW2 11 //      ---           . . / .  . . .     
+#define LOCK_GRDONLYS  12 // R . / RC . . .     same
+#define LOCK_GRDONLYL  13 // R . / RC . . .          ---
+
+#define LOCK_GMIXEDR   14 // R . / .  R . .     . . / .  R . .
+#define LOCK_GMIXEDR2  15 //      ---           . . / .  R . .
+#define LOCK_GMIXEDW   16 // . . / .  . W .     same
+#define LOCK_GMIXEDW2  16 //      ---           . . / .  . W .     
+#define LOCK_GMIXEDS   16 // R . / .  . . .     . . / .  . . .
+#define LOCK_GMIXEDS2  16 //      ---           . . / .  . . .     
+#define LOCK_GMIXEDL   17 // R . / .  . . .          --- 
+
+#define LOCK_GWRONLYR  18 // R . / .  . . .     same
+#define LOCK_GWRONLYR2 18 //      ---           . . / .  . . .
+#define LOCK_GWRONLYM  19 // . . / .  . . .     same
+#define LOCK_GWRONLYM2 19 //      ---           . . / .  . . .
+#define LOCK_GWRONLYS  20 // R . / .  . . WB    same
+#define LOCK_GWRONLYS2 20 //      ---           . . / .  . . .
+#define LOCK_GWRONLYL  21
+
index daf8f10cbcdfc5295565653b7f9109557d578c10..e3d31c68d2e7ba110b9bb13be0aeea8811d6455a 100644 (file)
@@ -4,7 +4,7 @@
 
 
 #undef dout
-#define dout(x) if (x <= g_conf.debug) cout << "ebofs.allocator." 
+#define dout(x) if (x <= g_conf.debug_ebofs) cout << "ebofs.allocator." 
 
 
 void Allocator::dump_freelist()
@@ -12,6 +12,7 @@ void Allocator::dump_freelist()
   if (1) {
        interval_set<block_t> free;     // validate too
        
+       block_t n = 0;
        for (int b=0; b<=EBOFS_NUM_FREE_BUCKETS; b++) {
          Table<block_t,block_t> *tab;
          if (b < EBOFS_NUM_FREE_BUCKETS) {
@@ -21,12 +22,13 @@ void Allocator::dump_freelist()
                dout(30) << "dump limbo" << endl;
                tab = fs->limbo_tab;
          }
-         
+
          if (tab->get_num_keys() > 0) {
                Table<block_t,block_t>::Cursor cursor(tab);
                tab->find(0, cursor);
                while (1) {
                  dout(30) << "dump  ex " << cursor.current().key << "~" << cursor.current().value << endl;
+                 n += cursor.current().value;
                  assert(!free.contains( cursor.current().key, cursor.current().value ));
                  free.insert( cursor.current().key, cursor.current().value );
                  if (cursor.move_right() <= 0) break;
@@ -36,6 +38,7 @@ void Allocator::dump_freelist()
          }
        }
        
+       assert(n == fs->free_blocks);
        dout(31) << "dump combined freelist is " << free << endl;
   }
 }
@@ -158,36 +161,54 @@ int Allocator::allocate(Extent& ex, block_t num, block_t near)
 int Allocator::release(Extent& ex)
 {
   dout(10) << "release " << ex << " (into limbo)" << endl;
-  fs->limbo_tab->insert(ex.start, ex.length);
+  limbo.insert(ex.start, ex.length);
   fs->limbo_blocks += ex.length;
   return 0;
 }
 
+int Allocator::commit_limbo()
+{
+  dout(20) << "commit_limbo" << endl;
+  for (map<block_t,block_t>::iterator i = limbo.m.begin();
+          i != limbo.m.end();
+          i++) {
+       fs->limbo_tab->insert(i->first, i->second);
+       fs->free_blocks += i->second;
+  }
+  limbo.clear();
+  fs->limbo_blocks = 0;
+  dump_freelist();
+  return 0;
+}
+
 int Allocator::release_limbo()
 {
+  dump_freelist();
   if (fs->limbo_tab->get_num_keys() > 0) {
        Table<block_t,block_t>::Cursor cursor(fs->limbo_tab);
        fs->limbo_tab->find(0, cursor);
        while (1) {
          Extent ex(cursor.current().key, cursor.current().value);
          dout(20) << "release_limbo  ex " << ex << endl;
+
+         fs->free_blocks -= ex.length;
          _release(ex);
+
          if (cursor.move_right() <= 0) break;
        }
   }
   fs->limbo_tab->clear();
-  fs->limbo_blocks = 0;
+  dump_freelist();
   return 0;
 }
 
-int Allocator::_release(Extent& ex
+int Allocator::_release(Extent& orig
 {
-  Extent newex = ex;
-  
-  dout(15) << "_release " << ex << endl;
-
-  fs->free_blocks += ex.length;
+  dout(15) << "_release " << orig << endl;
+  fs->free_blocks += orig.length;
 
+  Extent newex = orig;
+  
   // one after us?
   for (int b=0; b<EBOFS_NUM_FREE_BUCKETS; b++) {
        Table<block_t,block_t>::Cursor cursor(fs->free_tab[b]);
@@ -220,8 +241,8 @@ int Allocator::_release(Extent& ex)
   }
   
   // ok, insert newex
-  int b = pick_bucket(ex.length);
-  fs->free_tab[b]->insert(ex.start, ex.length);
+  int b = pick_bucket(newex.length);
+  fs->free_tab[b]->insert(newex.start, newex.length);
   return 0;
 }
 
index 6f172d08f8d26d94d8994748310c2388ecfd5eb1..85264fda53568b0bf25e9aaa98028519a5101964 100644 (file)
@@ -11,7 +11,7 @@ class Allocator {
  protected:
   Ebofs *fs;
 
-  //interval_set<block_t> limbo;
+  interval_set<block_t> limbo;
 
   static int pick_bucket(block_t num) {
        int b = 0;
@@ -35,7 +35,11 @@ class Allocator {
   
   int allocate(Extent& ex, block_t num, block_t near=0);
   int release(Extent& ex);
-  int release_limbo();
+
+  int commit_limbo();  // limbo -> fs->limbo_tab
+  int release_limbo(); // fs->limbo_tab -> free_tabs
+
+
 };
 
 #endif
index 9c6245f83f1529cfaa96dc32201efcd1162890cc..2227c988898c2eff0b17f8d3eefe9ec5e201c7b9 100644 (file)
@@ -7,8 +7,7 @@
 
 
 #undef dout
-#define dout(x)  if (x <= g_conf.debug) cout << "ebofs.bh."
-
+#define dout(x)  if (x <= g_conf.debug_ebofs) cout << "ebofs.bh."
 
 
 void BufferHead::finish_partials()
@@ -33,6 +32,16 @@ void BufferHead::finish_partials()
   partial_write.clear();
 }
 
+void BufferHead::cancel_partials()
+{
+  dout(10) << "cancel_partials on " << *this << endl;
+  for (map<block_t, PartialWrite>::iterator p = partial_write.begin();
+          p != partial_write.end();
+          p++) {
+       oc->bc->dec_unflushed( p->second.epoch );
+  }
+}
+
 void BufferHead::queue_partial_write(block_t b)
 {
   if (partial_write.count(b)) {
@@ -57,7 +66,7 @@ void BufferHead::queue_partial_write(block_t b)
 
 
 #undef dout
-#define dout(x)  if (x <= g_conf.debug) cout << "ebofs.oc."
+#define dout(x)  if (x <= g_conf.debug_ebofs) cout << "ebofs.oc."
 
 
 void ObjectCache::rx_finish(ioh_t ioh, block_t start, block_t length)
@@ -496,10 +505,13 @@ void ObjectCache::tear_down()
           it++) {
        BufferHead *bh = it->second;
 
+       // cancel any pending/queued io, if possible.
        if (bh->is_tx()) 
          bc->bh_cancel_write(bh);
        if (bh->is_rx())
          bc->bh_cancel_read(bh);
+       if (bh->is_partial_writes()) 
+         bh->cancel_partials();
        
        for (map<block_t,list<Context*> >::iterator p = bh->waitfor_read.begin();
                 p != bh->waitfor_read.end();
@@ -508,6 +520,7 @@ void ObjectCache::tear_down()
        }
        //finish_contexts(bh->waitfor_flush, -1);
        
+       bc->remove_bh(bh);
        delete bh;
   }
   data.clear();
@@ -518,7 +531,7 @@ void ObjectCache::tear_down()
 /************** BufferCache ***************/
 
 #undef dout
-#define dout(x)  if (x <= g_conf.debug) cout << "ebofs.bc."
+#define dout(x)  if (x <= g_conf.debug_ebofs) cout << "ebofs.bc."
 
 
 
index 17189b40357c595a29c6a40140f1b85baa9efff4..adbadc260f3d02f66b2e8d5821f98228639b3f94 100644 (file)
@@ -119,6 +119,7 @@ class BufferHead : public LRUObject {
   
   bool is_partial_writes() { return !partial_write.empty(); }
   void finish_partials();
+  void cancel_partials();
   void queue_partial_write(block_t b);
 
 
@@ -493,9 +494,11 @@ class BufferCache {
   }
   void inc_unflushed(version_t epoch) {
        epoch_unflushed[epoch]++;
+       cout << "inc_unflushed " << epoch << " now " << epoch_unflushed[epoch] << endl;
   }
   void dec_unflushed(version_t epoch) {
        epoch_unflushed[epoch]--;
+       cout << "dec_unflushed " << epoch << " now " << epoch_unflushed[epoch] << endl;
        if (stat_waiter && 
                epoch_unflushed[epoch] == 0) 
          stat_cond.Signal();
diff --git a/ceph/ebofs/Cnode.h b/ceph/ebofs/Cnode.h
new file mode 100644 (file)
index 0000000..300ae8d
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef __EBOFS_CNODE_H
+#define __EBOFS_CNODE_H
+
+#include "Onode.h"
+
+/*
+ * collection node
+ *
+ * holds attribute metadata for collections.
+ * colletion membership is stored in b+tree tables, independent of tte cnode.
+ */
+
+class Cnode : public LRUObject
+{
+ private:
+  int ref;
+  bool dirty;
+
+ public:
+  coll_t coll_id;
+  Extent cnode_loc;
+
+  map<string,AttrVal> attr;
+
+ public:
+  Cnode(coll_t cid) : ref(0), dirty(false), coll_id(cid) {
+       cnode_loc.length = 0;
+  }
+  ~Cnode() {
+  }
+
+  block_t get_cnode_id() { return cnode_loc.start; }
+  int get_cnode_len() { return cnode_loc.length; }
+
+  void get() {
+       if (ref == 0) lru_pin();
+       ref++;
+  }
+  void put() {
+       ref--;
+       if (ref == 0) lru_unpin();
+  }
+
+  void mark_dirty() {
+       if (!dirty) {
+         dirty = true;
+         get();
+       }
+  }
+  void mark_clean() {
+       if (dirty) {
+         dirty = false;
+         put();
+       }
+  }
+  bool is_dirty() { return dirty; }
+
+
+  int get_attr_bytes() {
+       int s = 0;
+       for (map<string, AttrVal >::iterator i = attr.begin();
+                i != attr.end();
+                i++) {
+         s += i->first.length() + 1;
+         s += i->second.len + sizeof(int);
+       }
+       return s;
+  }
+  
+  //
+  //???void clear();
+
+  
+};
+
+#endif
index 5d575ac15480533598a6816b39c8f88d8e6e099f..b80fc7953f0ba64816927cc24859777b497cd1e3 100644 (file)
@@ -4,7 +4,7 @@
 // *******************
 
 #undef dout
-#define dout(x) if (x <= g_conf.debug) cout << "ebofs."
+#define dout(x) if (x <= g_conf.debug_ebofs) cout << "ebofs."
 
 int Ebofs::mount()
 {
@@ -116,7 +116,8 @@ int Ebofs::mkfs()
   left.length = num_blocks - left.start;
   dout(1) << "mkfs: free data blocks at " << left << endl;
   allocator.release( left );
-  allocator.release_limbo();
+  allocator.commit_limbo();   // -> limbo_tab
+  allocator.release_limbo();  // -> free_tab
 
   // write nodes, super, 2x
   dout(1) << "mkfs: flushing nodepool and superblocks (2x)" << endl;
@@ -276,13 +277,20 @@ int Ebofs::commit_thread_entry()
        }
 
        super_epoch++;
-       dout(10) << "commit_thread commit start, new epoch " << super_epoch 
-                        << ".  " << get_free_blocks() << " free in " << get_free_extents() << ", " 
-                        << get_limbo_blocks() << " limbo in " << get_limbo_extents() << endl;
+       dout(10) << "commit_thread commit start, new epoch " << super_epoch << endl;
+       dout(10) << "commit_thread   data: " 
+                        << get_free_blocks() << " free in " << get_free_extents() 
+                        << ", " << get_limbo_blocks() << " limbo in " << get_limbo_extents() << endl;
+       dout(10) << "commit_thread  nodes: " 
+                        << nodepool.num_free() << " free, " 
+                        << nodepool.num_limbo() << " limbo, " 
+                        << nodepool.num_total() << " total." << endl;
 
        // (async) write onodes+condes  (do this first; it currently involves inode reallocation)
        commit_inodes_start();
 
+       allocator.commit_limbo();   // limbo -> limbo_tab
+
        // (async) write btree nodes
        nodepool.commit_start( dev, super_epoch );
        
@@ -301,8 +309,17 @@ int Ebofs::commit_thread_entry()
        write_super(super_epoch, superbp);      
        ebofs_lock.Lock();
 
-       // free limbo space now (since we're done allocating things, AND we've flushed all previous epoch data)
-       allocator.release_limbo();
+       // free limbo space now 
+       // (since we're done allocating things, 
+       //  AND we've flushed all previous epoch data)
+       allocator.release_limbo();   // limbo_tab -> free_tabs
+       
+       // do we need more node space?
+       if (nodepool.num_free() < nodepool.num_total() / 3) {
+         dout(1) << "commit_thread running low on node space, allocating more." << endl;
+         assert(0);
+         //alloc_more_node_space();
+       }
 
        // kick waiters
        dout(10) << "commit_thread kicking commit+sync waiters" << endl;
@@ -1219,7 +1236,7 @@ int Ebofs::read(object_t oid,
   Onode *on = get_onode(oid);
   if (!on) {
        ebofs_lock.Unlock();
-       return -1;  // object dne?
+       return -ENOENT;  // object dne?
   }
 
   // read data into bl.  block as necessary.
@@ -1285,11 +1302,18 @@ int Ebofs::write(object_t oid,
   ebofs_lock.Lock();
   dout(7) << "write " << hex << oid << dec << " len " << len << " off " << off << endl;
   assert(len > 0);
+
+  // out of space?
+  if (len / EBOFS_BLOCK_SIZE + 10 >= free_blocks) {
+       dout(1) << "write failing, only " << free_blocks << " blocks free" << endl;
+       if (onsafe) delete onsafe;
+       ebofs_lock.Unlock();
+       return -ENOSPC;
+  }
   
-  // get inode
+  // get|create inode
   Onode *on = get_onode(oid);
-  if (!on) 
-       on = new_onode(oid);    // new inode!
+  if (!on) on = new_onode(oid);        // new inode!
   
   // apply write to buffer cache
   apply_write(on, len, off, bl);
@@ -1324,7 +1348,7 @@ int Ebofs::remove(object_t oid)
   Onode *on = get_onode(oid);
   if (!on) {
        ebofs_lock.Unlock();
-       return -1;
+       return -ENOENT;
   }
 
   // ok remove it!
@@ -1357,7 +1381,7 @@ int Ebofs::stat(object_t oid, struct stat *st)
   Onode *on = get_onode(oid);
   if (!on) {
        ebofs_lock.Unlock();
-       return -1;
+       return -ENOENT;
   }
   
   // ??
@@ -1373,7 +1397,7 @@ int Ebofs::stat(object_t oid, struct stat *st)
 int Ebofs::setattr(object_t oid, const char *name, void *value, size_t size)
 {
   Onode *on = get_onode(oid);
-  if (!on) return -1;
+  if (!on) return -ENOENT;
 
   string n(name);
   AttrVal val((char*)value, size);
@@ -1387,7 +1411,7 @@ int Ebofs::setattr(object_t oid, const char *name, void *value, size_t size)
 int Ebofs::getattr(object_t oid, const char *name, void *value, size_t size)
 {
   Onode *on = get_onode(oid);
-  if (!on) return -1;
+  if (!on) return -ENOENT;
 
   string n(name);
   if (on->attr.count(n) == 0) return -1;
@@ -1401,7 +1425,7 @@ int Ebofs::getattr(object_t oid, const char *name, void *value, size_t size)
 int Ebofs::rmattr(object_t oid, const char *name) 
 {
   Onode *on = get_onode(oid);
-  if (!on) return -1;
+  if (!on) return -ENOENT;
 
   string n(name);
   on->attr.erase(n);
@@ -1414,7 +1438,7 @@ int Ebofs::rmattr(object_t oid, const char *name)
 int Ebofs::listattr(object_t oid, vector<string>& attrs)
 {
   Onode *on = get_onode(oid);
-  if (!on) return -1;
+  if (!on) return -ENOENT;
 
   attrs.clear();
   for (map<string,AttrVal>::iterator i = on->attr.begin();
@@ -1457,7 +1481,7 @@ int Ebofs::create_collection(coll_t cid)
 
 int Ebofs::destroy_collection(coll_t cid)
 {
-  if (!collection_exists(cid)) return -1;
+  if (!collection_exists(cid)) return -ENOENT;
   Cnode *cn = new_cnode(cid);
   
   // hose mappings
@@ -1484,7 +1508,7 @@ bool Ebofs::collection_exists(coll_t cid)
 
 int Ebofs::collection_add(coll_t cid, object_t oid)
 {
-  if (!collection_exists(cid)) return -1;
+  if (!collection_exists(cid)) return -ENOENT;
   oc_tab->insert(idpair_t(oid,cid), true);
   co_tab->insert(idpair_t(cid,oid), true);
   return 0;
@@ -1492,7 +1516,7 @@ int Ebofs::collection_add(coll_t cid, object_t oid)
 
 int Ebofs::collection_remove(coll_t cid, object_t oid)
 {
-  if (!collection_exists(cid)) return -1;
+  if (!collection_exists(cid)) return -ENOENT;
   oc_tab->remove(idpair_t(oid,cid));
   co_tab->remove(idpair_t(cid,oid));
   return 0;
@@ -1500,7 +1524,7 @@ int Ebofs::collection_remove(coll_t cid, object_t oid)
 
 int Ebofs::collection_list(coll_t cid, list<object_t>& ls)
 {
-  if (!collection_exists(cid)) return -1;
+  if (!collection_exists(cid)) return -ENOENT;
   
   Table<idpair_t, bool>::Cursor cursor(co_tab);
 
@@ -1523,7 +1547,7 @@ int Ebofs::collection_list(coll_t cid, list<object_t>& ls)
 int Ebofs::collection_setattr(coll_t cid, const char *name, void *value, size_t size)
 {
   Cnode *cn = get_cnode(cid);
-  if (!cn) return -1;
+  if (!cn) return -ENOENT;
 
   string n(name);
   AttrVal val((char*)value, size);
@@ -1537,7 +1561,7 @@ int Ebofs::collection_setattr(coll_t cid, const char *name, void *value, size_t
 int Ebofs::collection_getattr(coll_t cid, const char *name, void *value, size_t size)
 {
   Cnode *cn = get_cnode(cid);
-  if (!cn) return -1;
+  if (!cn) return -ENOENT;
 
   string n(name);
   if (cn->attr.count(n) == 0) return -1;
@@ -1550,7 +1574,7 @@ int Ebofs::collection_getattr(coll_t cid, const char *name, void *value, size_t
 int Ebofs::collection_rmattr(coll_t cid, const char *name) 
 {
   Cnode *cn = get_cnode(cid);
-  if (!cn) return -1;
+  if (!cn) return -ENOENT;
 
   string n(name);
   cn->attr.erase(n);
@@ -1563,7 +1587,7 @@ int Ebofs::collection_rmattr(coll_t cid, const char *name)
 int Ebofs::collection_listattr(coll_t cid, vector<string>& attrs)
 {
   Cnode *cn = get_cnode(cid);
-  if (!cn) return -1;
+  if (!cn) return -ENOENT;
 
   attrs.clear();
   for (map<string,AttrVal>::iterator i = cn->attr.begin();
index 439f34c9959df7b2f1a6b6ac3d97c647d2203dfc..6f60c83a22be980f09900d32d6007390f9cbf2e1 100644 (file)
@@ -163,7 +163,8 @@ class Ebofs : public ObjectStore {
        mounted(false), unmounting(false), readonly(false), 
        super_epoch(0), commit_thread_started(false), mid_commit(false),
        commit_thread(this),
-       free_blocks(0), allocator(this),
+       free_blocks(0), limbo_blocks(0),
+       allocator(this),
        bufferpool(EBOFS_BLOCK_SIZE),
        nodepool(ebofs_lock),
        object_tab(0), limbo_tab(0), collection_tab(0), oc_tab(0), co_tab(0),
index 8bdd6b0d863e35573308ada91d4918e29935865d..b690816085176bcde156952720ede9d934e8e8a4 100644 (file)
@@ -6,7 +6,7 @@
 
 /** table **/
 
-#define dbtout dout(10)
+#define dbtout if (10 < g_conf.debug_ebofs) cout
 
 
 template<class K, class V>
@@ -463,7 +463,7 @@ class Table {
   }
 
   int insert(K key, V value) {
-       dbtout << "insert " << key << " -> " << value << endl;
+       //dbtout << "insert " << key << " -> " << value << endl;
        if (almost_full()) return -1;
        
        // empty?
index 8990cd7b2d39505199cba76730dd74a47463e4fc..aa2a3d4fdd44c7b17c9ca28adc88ff8009b929b9 100644 (file)
@@ -47,13 +47,13 @@ int main(int argc, char **argv)
        
        // test small writes
        if (1) {
-         char crap[10000];
-         memset(crap, 0, 10000);
+         char crap[1024*1024];
+         memset(crap, 0, 1024*1024);
          bufferlist bl;
-         bl.append(crap, 10000);
+         bl.append(crap, 1024*1024);
          
          // reandom write
-         if (0) {
+         if (1) {
                srand(0);
                for (int i=0; i<10000; i++) {
                  off_t off = rand() % 1000000;
@@ -63,14 +63,23 @@ int main(int argc, char **argv)
                  //fs.sync();
                  //fs.trim_buffer_cache();
                }
+               fs.remove(10);
+               for (int i=0; i<100; i++) {
+                 off_t off = rand() % 1000000;
+                 size_t len = 1+rand() % 10000;
+                 cout << endl << i << " writing bit at " << off << " len " << len << endl;
+                 fs.write(10, len, off, bl, (Context*)0);
+                 //fs.sync();
+                 //fs.trim_buffer_cache();
+               }
          }
          
-         if (1) {
+         if (0) {
                // sequential write
                srand(0);
                off_t off = 0;
                for (int i=0; i<10000; i++) {
-                 size_t len = 1+rand() % 10000;
+                 size_t len = 1024*1024;//1+rand() % 10000;
                  cout << endl << i << " writing bit at " << off << " len " << len << endl;
                  fs.write(10, len, off, bl, (Context*)0);
                  off += len;
index 943fcd308a3803801ffecc149e78c8ce285e1bcf..2097621d3b87df85d7501c8b744438d296dc421a 100644 (file)
@@ -29,6 +29,9 @@
 
 */
 
+#undef debofs
+#define debofs(x) if (x < g_conf.debug_ebofs) cout
+
 
 class Node {
  public:
@@ -120,6 +123,7 @@ class NodePool {
   
  protected:
   // on-disk block states
+  int num_nodes;
   set<nodeid_t> free;
   set<nodeid_t> dirty;
   set<nodeid_t> tx;
@@ -144,6 +148,7 @@ class NodePool {
  public:
   NodePool(Mutex &el) : 
        bufferpool(EBOFS_NODE_BYTES), 
+       num_nodes(0),
        ebofs_lock(el),
        flushing(0) {}
   ~NodePool() {
@@ -151,9 +156,12 @@ class NodePool {
        release_all();
   }
 
-  int num_free() {
-       return free.size();
-  }
+  int num_free() { return free.size(); }
+  int num_dirty() { return dirty.size(); }
+  int num_limbo() { return limbo.size(); }
+  int num_tx() { return tx.size(); }
+  int num_clean() { return clean.size(); }
+  int num_total() { return num_nodes; }
 
   // the caller had better adjust usemap locations...
   void add_region(Extent ex) {
@@ -162,20 +170,22 @@ class NodePool {
        for (unsigned o = 0; o < ex.length; o++) {
          free.insert( make_nodeid(region, o) );
        }
+       num_nodes += ex.length;
   }
   
   int init(struct ebofs_nodepool *np) {
        // regions
        for (int i=0; i<np->num_regions; i++) {
-         dout(3) << "init region " << i << " at " << np->region_loc[i] << endl;
+         debofs(3) << "init region " << i << " at " << np->region_loc[i] << endl;
          region_loc.push_back( np->region_loc[i] );
+         num_nodes += np->region_loc[i].length;
        }
 
        // usemap
        usemap_even = np->node_usemap_even;
        usemap_odd = np->node_usemap_odd;
-       dout(3) << "init even map at " << usemap_even << endl;
-       dout(3) << "init  odd map at " << usemap_odd << endl;
+       debofs(3) << "init even map at " << usemap_even << endl;
+       debofs(3) << "init  odd map at " << usemap_odd << endl;
 
        return 0;
   }
@@ -229,13 +239,13 @@ class NodePool {
          to read.  so it only really works when called from mount()!
        */
        for (unsigned r=0; r<region_loc.size(); r++) {
-         dout(3) << "ebofs.nodepool.read region " << r << " at " << region_loc[r] << endl;
+         debofs(3) << "ebofs.nodepool.read region " << r << " at " << region_loc[r] << endl;
          
          for (block_t boff = 0; boff < region_loc[r].length; boff++) {
                nodeid_t nid = make_nodeid(r, boff);
                
                if (!clean.count(nid)) continue;  
-               dout(20) << "ebofs.nodepool.read  node " << nid << endl;
+               debofs(20) << "ebofs.nodepool.read  node " << nid << endl;
 
                bufferptr bp = bufferpool.alloc(EBOFS_NODE_BYTES);
                dev.read(region_loc[r].start + (block_t)boff, EBOFS_NODE_BLOCKS, 
@@ -243,7 +253,7 @@ class NodePool {
                
                Node *n = new Node(nid, bp, Node::STATE_CLEAN);
                node_map[nid] = n;
-               dout(10) << "ebofs.nodepool.read  node " << n << " at " << (void*)n << endl;
+               debofs(10) << "ebofs.nodepool.read  node " << n << " at " << (void*)n << endl;
          }
        }
        return 0;
@@ -444,7 +454,7 @@ class NodePool {
   // new node
   Node* new_node(int type) {
        nodeid_t nid = alloc_id();
-       dout(15) << "ebofs.nodepool.new_node " << nid << endl;
+       debofs(15) << "ebofs.nodepool.new_node " << nid << endl;
        
        // alloc node
        bufferptr bp = bufferpool.alloc(EBOFS_NODE_BYTES);
@@ -459,7 +469,7 @@ class NodePool {
 
   void release(Node *n) {
        const nodeid_t nid = n->get_id();
-       dout(15) << "ebofs.nodepool.release on " << nid << endl;
+       debofs(15) << "ebofs.nodepool.release on " << nid << endl;
        node_map.erase(nid);
 
        if (n->is_dirty()) {
@@ -477,7 +487,7 @@ class NodePool {
   void release_all() {
        while (!node_map.empty()) {
          map<nodeid_t,Node*>::iterator i = node_map.begin();
-         dout(2) << "ebofs.nodepool.release_all leftover " << i->first << " " << i->second << endl;
+         debofs(2) << "ebofs.nodepool.release_all leftover " << i->first << " " << i->second << endl;
          release( i->second );
        }
        assert(node_map.empty());
@@ -487,7 +497,7 @@ class NodePool {
        // get new node id?
        nodeid_t oldid = n->get_id();
        nodeid_t newid = alloc_id();
-       dout(2) << "ebofs.nodepool.dirty_node on " << oldid << " now " << newid << endl;
+       debofs(2) << "ebofs.nodepool.dirty_node on " << oldid << " now " << newid << endl;
        
        // release old block
        if (n->is_clean()) {