]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
minor bug fixes, cleanup
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Tue, 18 Dec 2007 23:23:45 +0000 (23:23 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Tue, 18 Dec 2007 23:23:45 +0000 (23:23 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2225 29311d96-e01e-0410-9327-a35deaab8ce9

branches/ebofs/ebofs/BufferCache.cc
branches/ebofs/ebofs/BufferCache.h
branches/ebofs/ebofs/Ebofs.cc
branches/ebofs/ebofs/Onode.h
branches/ebofs/ebofs/test.ebofs.cc

index 493dafe3023e4b6cf022e12582be48b4f14ee5fa..cd0b980e5fb001886f9995df5f9fb4ed447bd4e2 100644 (file)
@@ -115,15 +115,15 @@ void BufferHead::apply_partial()
 {
   assert(!partial.empty());
   dout(10) << "apply_partial on " << partial.size() << " substrings" << dendl;
+  csum_t *expect = oc->on->get_extent_csum_ptr(start(), 1);
   csum_t oldc = calc_csum(data.c_str(), EBOFS_BLOCK_SIZE);
   do_apply_partial(data, partial);
   csum_t newc = calc_csum(data.c_str(), EBOFS_BLOCK_SIZE);
-  csum_t *p = oc->on->get_extent_csum_ptr(start(), 1);
-  dout(10) << "apply_partial onode had " << hex << *p
+  dout(10) << "apply_partial onode expected " << hex << *expect
           << " bl was " << oldc
           << " now " << newc << dec << dendl;
-  assert(*p == oldc);
-  *p = newc;
+  assert(*expect == oldc);
+  *expect = newc;
   oc->on->data_csum += newc - oldc;
 }
 
@@ -165,13 +165,7 @@ void ObjectCache::rx_finish(ioh_t ioh, block_t start, block_t length, bufferlist
       bh->rx_ioh = 0;
 
     // trigger waiters
-    for (map<block_t,list<Context*> >::iterator p = bh->waitfor_read.begin();
-         p != bh->waitfor_read.end();
-         p++) {
-      assert(p->first >= bh->start() && p->first < bh->end());
-      waiters.splice(waiters.begin(), p->second);
-    }
-    bh->waitfor_read.clear();
+    bh->take_read_waiters(waiters);
 
     if (bh->is_rx()) {
       assert(bh->get_version() == 0);
@@ -805,11 +799,11 @@ void ObjectCache::discard_bh(BufferHead *bh, version_t super_epoch)
     bh->shadow_of->remove_shadow(bh);
   }
   
-  for (map<block_t,list<Context*> >::iterator p = bh->waitfor_read.begin();
-       p != bh->waitfor_read.end();
-       p++) 
-    finish_contexts(p->second, -1);
-  
+  // kick read waiters
+  list<Context*> finished;
+  bh->take_read_waiters(finished);
+  finish_contexts(finished, -1);
+
   bc->remove_bh(bh);
 }
 
@@ -1156,16 +1150,6 @@ void BufferCache::bh_write(Onode *on, BufferHead *bh, block_t shouldbe)
 
   on->oc->get();
   inc_unflushed( EBOFS_BC_FLUSH_BHWRITE, bh->epoch_modified );
-
-  /*
-  // assert: no partials on the same block
-  // hose any partial on the same block
-  if (bh->partial_write.count(ex.start)) {
-    dout(10) << "bh_write hosing parital write on same block " << ex.start << " " << *bh << dendl;
-    dec_unflushed( bh->partial_write[ex.start].epoch );
-    bh->partial_write.erase(ex.start);
-  }
-  */
 }
 
 
index af3073c907e902543e0c6f69d5e2ec609b68200e..c42bbc0fccbd82fb8e69e6e53f4f065060af79ce 100644 (file)
@@ -57,7 +57,7 @@ class BufferHead : public LRUObject {
 
   map<off_t, bufferlist>     partial;   // partial dirty content overlayed onto incoming data
 
-  map< block_t, list<Context*> > waitfor_read;
+  map<block_t, list<Context*> > waitfor_read;
   
   set<BufferHead*>  shadows;     // shadow bh's that clone()ed me.
   BufferHead*       shadow_of;
@@ -243,6 +243,14 @@ class BufferHead : public LRUObject {
   void apply_partial();
   void add_partial(off_t off, bufferlist& p);
 
+  void take_read_waiters(list<Context*>& finished) {
+    for (map<block_t,list<Context*> >::iterator p = waitfor_read.begin();
+         p != waitfor_read.end();
+         p++)
+      finished.splice(finished.begin(), p->second);
+    waitfor_read.clear();
+  }
+
 };
 
 inline ostream& operator<<(ostream& out, BufferHead& bh)
@@ -566,11 +574,11 @@ class BufferCache {
   }
   void inc_unflushed(int what, version_t epoch) {
     epoch_unflushed[what][epoch]++;
-    //cout << "inc_unflushed " << epoch << " now " << epoch_unflushed[epoch] << std::endl;
+    //cout << "inc_unflushed " << epoch << " now " << epoch_unflushed[what][epoch] << std::endl;
   }
   void dec_unflushed(int what, version_t epoch) {
     epoch_unflushed[what][epoch]--;
-    //cout << "dec_unflushed " << epoch << " now " << epoch_unflushed[epoch] << std::endl;
+    //cout << "dec_unflushed " << epoch << " now " << epoch_unflushed[what][epoch] << std::endl;
     if (epoch_unflushed[what][epoch] == 0) 
       flush_cond.Signal();
   }
@@ -593,14 +601,11 @@ class BufferCache {
     stat_waiter--;
   }
   void waitfor_partials() {
-    cout << "wait start " << partial_reads << std::endl;
     stat_waiter++;
-    while (partial_reads > 0) {
-      cout << "wait " << partial_reads << std::endl;
+    while (partial_reads > 0) 
       stat_cond.Wait(ebofs_lock);
-    }
     stat_waiter--;
-    cout << "wait finish " << partial_reads << std::endl;
+
   }
   void waitfor_flush() {
     flush_cond.Wait(ebofs_lock);
index 5bb84a3520f9f3e55835b925ea9d0865dc99b7bf..8f20f278319cf48985a424a174490738da3abd07 100644 (file)
@@ -1623,20 +1623,24 @@ int Ebofs::check_partial_edges(Onode *on, off_t off, off_t len,
 {
   // partial block overwrite at head or tail?
   off_t last_block_byte = on->last_block * EBOFS_BLOCK_SIZE;
-  partial_head = off < last_block_byte && (off & EBOFS_BLOCK_MASK);
-  partial_tail = (off+len) < on->object_size && ((off+len) & EBOFS_BLOCK_MASK);
+  partial_head = (off < last_block_byte) && (off & EBOFS_BLOCK_MASK);
+  partial_tail = ((off+len) < on->object_size) && ((off+len) & EBOFS_BLOCK_MASK);
+  dout(0) << "check_partial_edges on " << *on << " " << off << "~" << len 
+          << " " << partial_head << "/" << partial_tail << dendl;
 
   if ((partial_head || partial_tail) && commit_starting) {
+    ObjectCache *oc = on->get_oc(&bc);
+
     // verify that partials don't depend on unread data!
     if (partial_head) {
       block_t bstart = off / EBOFS_BLOCK_SIZE;
-      BufferHead *bh = on->oc->find_bh_containing(bstart);
+      BufferHead *bh = oc->find_bh_containing(bstart);
       if (!bh) {
-       dout(0) << "check_partial_edges missing data for partial head, deferring" << dendl;
+       dout(10) << "check_partial_edges missing data for partial head, deferring" << dendl;
        return -1;
       }
       if (bh->is_missing() || bh->is_rx()) {
-       dout(0) << "check_partial_edges missing data for partial head " << *bh << ", deferring" << dendl;
+       dout(10) << "check_partial_edges missing data for partial head " << *bh << ", deferring" << dendl;
        return -1;
       }
       if (bh->is_partial()) {
@@ -1644,20 +1648,20 @@ int Ebofs::check_partial_edges(Onode *on, off_t off, off_t len,
        int end_in_bh = MAX(EBOFS_BLOCK_SIZE, off_in_bh+len);
        if (!(off_in_bh == 0 || bh->have_partial_range(0, off_in_bh)) ||
            !(end_in_bh == EBOFS_BLOCK_SIZE || bh->have_partial_range(end_in_bh, EBOFS_BLOCK_SIZE-end_in_bh))) {
-         dout(0) << "check_partial_edges can't complete partial head " << *bh << ", deferring" << dendl;
+         dout(10) << "check_partial_edges can't complete partial head " << *bh << ", deferring" << dendl;
          return -1;
        }
       }      
     }
     if (partial_tail) {
       block_t blast = (len+off-1) / EBOFS_BLOCK_SIZE;
-      BufferHead *bh = on->oc->find_bh_containing(blast);
+      BufferHead *bh = oc->find_bh_containing(blast);
       if (!bh) {
-       dout(0) << "check_partial_edges missing data for partial tail, deferring" << dendl;
+       dout(10) << "check_partial_edges missing data for partial tail, deferring" << dendl;
        return -1;
       } 
       if (bh->is_missing() || bh->is_rx()) {
-       dout(0) << "check_partial_edges missing data for partial tail " << *bh << ", deferring" << dendl;
+       dout(10) << "check_partial_edges missing data for partial tail " << *bh << ", deferring" << dendl;
        return -1;
       }
       if (bh->is_partial()) {
@@ -1668,7 +1672,7 @@ int Ebofs::check_partial_edges(Onode *on, off_t off, off_t len,
          end = last_block_byte & EBOFS_BLOCK_MASK;
        if (!(off_in_bh == 0 || bh->have_partial_range(0, off_in_bh)) ||
            !(end_in_bh >= end || bh->have_partial_range(end_in_bh, end-end_in_bh))) {
-         dout(0) << "check_partial_edges can't complete partial tail " << *bh << ", deferring" << dendl;
+         dout(10) << "check_partial_edges can't complete partial tail " << *bh << ", deferring" << dendl;
          return -1;
        }
       }      
@@ -1731,6 +1735,7 @@ int Ebofs::apply_write(Onode *on, off_t off, off_t len, const bufferlist& bl)
   version_t highv = ++oc->write_count;
   
   // copy from bl into buffer cache
+  list<Context*> finished;
   unsigned blpos = 0;       // byte pos in input buffer
   for (map<block_t, BufferHead*>::iterator i = hits.begin();
        i != hits.end(); 
@@ -1763,6 +1768,9 @@ int Ebofs::apply_write(Onode *on, off_t off, off_t len, const bufferlist& bl)
       }
     }
 
+    // take read waiters
+    bh->take_read_waiters(finished);  // this is a bit aggressive, since we kick waiters on partials
+
     // need to split off partial?  (partials can only be ONE block)
     if ((bh->is_missing() || bh->is_rx()) && bh->length() > 1) {
       if (bh->start() == bstart && partial_head) {
@@ -1846,11 +1854,13 @@ int Ebofs::apply_write(Onode *on, off_t off, off_t len, const bufferlist& bl)
           dout(10) << "apply_write  rx -> partial " << *bh << dendl;
           assert(bh->length() == 1);
           bc.mark_partial(bh);
+         assert(!commit_starting);  // otherwise, but in check_partial_edges
         }
         else if (bh->is_missing() || bh->is_corrupt()) {
           dout(10) << "apply_write  missing -> partial " << *bh << dendl;
           assert(bh->length() == 1);
           bc.mark_partial(bh);
+         assert(!commit_starting);  // otherwise, but in check_partial_edges
 
           // take care to read from _old_ disk block locations!
           if (bh->start() == bstart)
@@ -2010,13 +2020,14 @@ int Ebofs::apply_write(Onode *on, off_t off, off_t len, const bufferlist& bl)
   oc->scrub_csums();
 
   dirty_onode(on);
+  finish_contexts(finished);
   return 0;
 }
 
 
 int Ebofs::apply_zero(Onode *on, off_t off, size_t len)
 {
-  ObjectCache *oc = on->get_oc(&bc);
+  dout(10) << "apply_zero " << off << "~" << len << " on " << *on << dendl;
 
   bool partial_head, partial_tail;
   if (check_partial_edges(on, off, len, partial_head, partial_tail) < 0)
@@ -2024,15 +2035,17 @@ int Ebofs::apply_zero(Onode *on, off_t off, size_t len)
 
   // zero edges
   // head?
-  if (partial_head) {
-    assert(off & EBOFS_BLOCK_MASK);
+  if (off & EBOFS_BLOCK_MASK) {
     size_t l = EBOFS_BLOCK_SIZE - (off & EBOFS_BLOCK_MASK);
     if (l > len) l = len;
-    bufferptr bp(l);
-    bp.zero();
-    bufferlist bl;
-    bl.push_back(bp);
-    apply_write(on, off, bl.length(), bl);
+    if (partial_head) {
+      bufferptr bp(l);
+      bp.zero();
+      bufferlist bl;
+      bl.push_back(bp);
+      int r = apply_write(on, off, bl.length(), bl);
+      assert(r == 0);
+    }
     off += l;
     len -= l;
   }
@@ -2045,7 +2058,8 @@ int Ebofs::apply_zero(Onode *on, off_t off, size_t len)
     bp.zero();
     bufferlist bl;
     bl.push_back(bp);
-    apply_write(on, off+len-bl.length(), bp.length(), bl);
+    int r = apply_write(on, off+len-bl.length(), bp.length(), bl);
+    assert(r == 0);
     len -= l;
   }
   if (len == 0) return 0;  // done!
@@ -2059,9 +2073,9 @@ int Ebofs::apply_zero(Onode *on, off_t off, size_t len)
   assert(blen > 0);
 
   map<block_t,BufferHead*> hits;
+  ObjectCache *oc = on->get_oc(&bc);
   oc->map_write(bstart, blen, hits, super_epoch);
 
-  list<Context*> finished;
   map<block_t,BufferHead*>::iterator p = hits.begin();
   while (p != hits.end()) {
     map<block_t,BufferHead*>::iterator next = p;
@@ -2090,7 +2104,7 @@ int Ebofs::apply_zero(Onode *on, off_t off, size_t len)
   on->uncommitted.subtract(olduncom);
   dout(10) << "_zeroed new uncom " << on->uncommitted << dendl;
 
-  finish_contexts(finished, -1);
+  dirty_onode(on);
   return 0;
 }
 
@@ -2773,7 +2787,6 @@ int Ebofs::_write(pobject_t oid, off_t offset, size_t length, const bufferlist&
     // apply write to buffer cache
     if (length > 0) {
       int r = apply_write(on, offset, length, bl);
-      dout(1) << "apply_write returned " << r << dendl;
       if (r == 0) 
        break; // yay!
       assert(r < 0);
index 85bd658d05ba1e16f9640fe3e5210ccd9d5e31d9..a8ef3cbb13d26eaba105a290d74d8dff0fb31069 100644 (file)
@@ -180,7 +180,7 @@ public:
       for (map<block_t,ExtentCsum>::iterator p = extent_map.begin();
            p != extent_map.end();
            p++) {
-        cout << " verify_extents " << p->first << ": " << p->second << std::endl;
+        //cout << " verify_extents " << p->first << ": " << p->second << std::endl;
         assert(pos == p->first);
        pos += p->second.ex.length;
        if (p->second.ex.start) {
@@ -192,7 +192,7 @@ public:
          }
        }
       }
-      cout << " verify_extents got csum " << hex << csum << " want " << data_csum << dec << std::endl;
+      //cout << " verify_extents got csum " << hex << csum << " want " << data_csum << dec << std::endl;
 
       assert(s.size() == count);
       assert(count == alloc_blocks);
index 8dcc4961e26661ff973dac396868479c9b828b63..dd78b8ff9a11ebb7a4914c8a73f11d2401536e1d 100644 (file)
@@ -217,13 +217,13 @@ int main(int argc, char **argv)
   }
 
   utime_t now = g_clock.now();
-  utime_t dur(seconds,0);
+  utime_t dur(seconds, 0);
   utime_t end = now + dur;
   cout << "stop at " << end << std::endl;
   while (now < end) {
     sleep(1);
     now = g_clock.now();
-    cout << now << std::endl;
+    //cout << now << std::endl;
   }
 
   cout << "stopping" << std::endl;