]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: _do_zero_tail_extent: do not assume tail block is zeroed
authorSage Weil <sage@redhat.com>
Mon, 28 Mar 2016 19:35:31 +0000 (15:35 -0400)
committerSage Weil <sage@redhat.com>
Wed, 30 Mar 2016 15:23:15 +0000 (11:23 -0400)
We will change this shortly.

Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.cc

index 4add5a1bcd7c8bec759fd58a9065165ca34e9c2c..e9b6b0f780bdfcaeca53cf18f67e60ca48dc0197 100644 (file)
 
 #define dout_subsys ceph_subsys_bluestore
 
-/*
-
-  TODO:
-
-  * superblock, features
-  * bdev: smarter zeroing
-  * zero overlay in onode?
-  * discard
-  * aio read?
-  * read uses local ioc
-  * refcounted extents (for efficient clone)
-  * overlay does inefficient zeroing on unwritten extent
-
- */
-
-/*
- * Some invariants:
- *
- * - If the end of the object is a partial block, and is not an overlay,
- *   the remainder of that block will always be zeroed.  (It has to be written
- *   anyway, so we may as well have written zeros.)
- *
- */
-
 const string PREFIX_SUPER = "S";   // field -> value
 const string PREFIX_COLL = "C";    // collection name -> cnode_t
 const string PREFIX_OBJ = "O";     // object name -> onode_t
@@ -5758,25 +5734,42 @@ void BlueStore::_do_zero_tail_extent(
   const uint64_t block_size = bdev->get_block_size();
   const uint64_t block_mask = ~(block_size - 1);
 
+  dout(10) << __func__ << " offset " << offset << " extent "
+          << pp->first << ": " << pp->second << dendl;
   assert(offset > o->onode.size);
   assert(pp != o->onode.block_map.end());
 
-  // we currently assume that any partial tail block is always zeroed
-  uint64_t end = ROUND_UP_TO(o->onode.size, block_size);
-
   // we assume the caller will handle any partial block they start with
   offset &= block_mask;
+  if (offset <= o->onode.size)
+    return;
 
-  // 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 > 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
+  uint64_t end_block = ROUND_UP_TO(o->onode.size, block_size);
+
+  if (end_block > o->onode.size) {
+    // end was in a partial block, do wal r/m/w.
+    bluestore_wal_op_t *op = _get_wal_op(txc, o);
+    op->op = bluestore_wal_op_t::OP_ZERO;
+    uint64_t x_off = o->onode.size;
+    uint64_t x_len = end_block - x_off;
+    op->extent.offset = pp->second.offset + x_off - pp->first;
+    op->extent.length = x_len;
+    dout(10) << __func__ << " wal zero tail partial block "
+            << x_off << "~" << x_len << " at " << op->extent
             << dendl;
-    bdev->aio_zero(pp->second.offset + x_off, x_len, &txc->ioc);
+    assert(!pp->second.has_flag(bluestore_extent_t::FLAG_COW_HEAD));
+    assert(!pp->second.has_flag(bluestore_extent_t::FLAG_COW_TAIL));
+  }
+  if (offset > end_block) {
+    // end was block-aligned.  zero the rest of the extent now.
+    uint64_t x_off = end_block - pp->first;
+    uint64_t x_len = pp->second.length - x_off;
+    if (x_len > 0) {
+      dout(10) << __func__ << " zero tail " << x_off << "~" << x_len
+              << " of tail extent " << pp->first << ": " << pp->second
+              << dendl;
+      bdev->aio_zero(pp->second.offset + x_off, x_len, &txc->ioc);
+    }
   }
 }