]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
basic read/write support for holes. with bugs.
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Wed, 21 Nov 2007 18:34:47 +0000 (18:34 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Wed, 21 Nov 2007 18:34:47 +0000 (18:34 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2102 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/include/buffer.h

index a51b25c40c715ab8d10f668645daa96ab1000eb6..c7b102c8f59255e1cbbea50156e2ac3e40ba7b11 100644 (file)
@@ -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;
       
index 094f444364204a25bff6bdeb942c4417f0fd7fac..dda4926ea1f09fabfa21f32037493344c3dc3dfc 100644 (file)
@@ -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";
index f17e3dc299e0bd8c9c9ca9b0187a002b024043c7..87b830a1c793abc62a63c35c6bb279c0ef4e6f5f 100644 (file)
@@ -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<Extent> old;
     on->map_extents(bstart, blen, old, 0);
     for (unsigned i=0; i<old.size(); i++)
@@ -1861,6 +1866,16 @@ void Ebofs::apply_zero(Onode *on, off_t off, size_t len)
        allocator.release(old[i]);
     Extent hole(0, blen);      
     on->set_extent(bstart, hole);
+
+    // adjust uncom
+    interval_set<block_t> zeroed;
+    zeroed.insert(bstart, blen);
+    interval_set<block_t> 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);
index 5d6734dfc0d7863e23b883970a95f3890e726b90..dc136c8b01b238eb562a4f4018975523c066db3b 100644 (file)
@@ -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;
     }
 
index 5e48b6ce91bf69b5248b38315028516039ed7de6..ded9fe28741ab4c8cf56448fab3637416483acd8 100644 (file)
@@ -755,6 +755,12 @@ public:
        _buffers.push_back(*p);
     }
     
+    void append_zero(unsigned len) {
+      ptr bp(len);
+      bp.zero();
+      append(bp);
+    }
+
     
     /*
      * get a char