]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore/BlueStore: fix _zero when previous extent partially unwritten
authorSage Weil <sage@redhat.com>
Tue, 22 Dec 2015 19:33:02 +0000 (14:33 -0500)
committerSage Weil <sage@redhat.com>
Fri, 1 Jan 2016 18:07:25 +0000 (13:07 -0500)
Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.cc

index a2840f9c34bca4429586f2693b6d6ea1ee680a87..db2f3180a8b024c1a89a9e886ecd92c79b6a4437 100644 (file)
@@ -5194,12 +5194,32 @@ int BlueStore::_zero(TransContext *txc,
   RWLock::WLocker l(c->lock);
   EnodeRef enode;
   OnodeRef o = c->get_onode(oid, true);
+  _dump_onode(o);
   _assign_nid(txc, o);
 
   // overlay
   _do_overlay_trim(txc, o, offset, length);
 
+  uint64_t block_size = bdev->get_block_size();
   map<uint64_t,bluestore_extent_t>::iterator bp = o->onode.seek_extent(offset);
+
+  // zero tail of previous existing extent?
+  // (this happens if the old eof was partway through a previous extent,
+  // and we implicitly zero the rest of it by writing to a larger offset.)
+  if (offset > o->onode.size) {
+    uint64_t end = ROUND_UP_TO(o->onode.size, block_size);
+    map<uint64_t, bluestore_extent_t>::iterator pp = o->onode.find_extent(end);
+    if (offset > end &&
+       pp != o->onode.block_map.end()) {
+      uint64_t x_off = end - pp->first;
+      uint64_t x_len = pp->second.length - x_off;
+      dout(10) << __func__ << " zero tail " << x_off << "~" << x_len
+              << " of prior extent " << pp->first << ": " << pp->second
+              << dendl;
+      bdev->aio_zero(pp->second.offset + x_off, x_len, &txc->ioc);
+    }
+  }
+
   while (bp != o->onode.block_map.end()) {
     if (bp->first >= offset + length)
       break;