]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/newstore: send complete overwrite to a new fid
authorSage Weil <sage@redhat.com>
Wed, 1 Apr 2015 16:46:53 +0000 (09:46 -0700)
committerSage Weil <sage@redhat.com>
Tue, 1 Sep 2015 17:39:35 +0000 (13:39 -0400)
Signed-off-by: Sage Weil <sage@redhat.com>
src/os/newstore/NewStore.cc
src/test/objectstore/store_test.cc

index 1f3f62eb2daf23bfdf9c375354397a6b39f46cff..a0ce422f4a854def13c6fca02df0de868e9f1725 100644 (file)
@@ -47,6 +47,7 @@
   * abstract out fs specifics
   * fid xattr backpointer
   * kill collection_list_range
+  * inline first fsync_item in TransContext to void allocation?
 
  */
 
@@ -2896,6 +2897,34 @@ int NewStore::_do_write(TransContext *txc,
       goto out;
     }
     txc->sync_fd(fd);
+  } else if (offset == 0 &&
+            length >= o->onode.size) {
+    // overwrite to new fid
+    assert(o->onode.data_map.size() == 1);
+    fragment_t& f = o->onode.data_map.begin()->second;
+    assert(f.offset == 0);
+    assert(f.length == o->onode.size);
+
+    wal_op_t *op = _get_wal_op(txc);
+    op->op = wal_op_t::OP_REMOVE;
+    op->fid = f.fid;
+
+    f.length = length;
+    o->onode.size = length;
+    fd = _create_fid(txc, &f.fid);
+    if (fd < 0) {
+      r = fd;
+      goto out;
+    }
+    dout(20) << __func__ << " replace old fid " << op->fid
+            << " with new fid " << f.fid
+            << ", writing " << offset << "~" << length << dendl;
+    r = bl.write_fd(fd);
+    if (r < 0) {
+      derr << __func__ << " bl.write_fd error: " << cpp_strerror(r) << dendl;
+      goto out;
+    }
+    txc->sync_fd(fd);
   } else {
     // WAL
     assert(o->onode.data_map.size() == 1);
@@ -3510,13 +3539,13 @@ int NewStore::_clone(TransContext *txc,
   newo->onode.attrs = oldo->onode.attrs;
 
   // clone omap
-  if (o->onode.omap_head) {
+  if (newo->onode.omap_head) {
     dout(20) << __func__ << " clearing old omap data" << dendl;
-    _do_omap_clear(txc, o->onode.omap_head, true);
+    _do_omap_clear(txc, newo->onode.omap_head, true);
   }
   if (oldo->onode.omap_head) {
     dout(20) << __func__ << " copying omap data" << dendl;
-    _get_omap_id(txc, o);
+    _get_omap_id(txc, newo);
     KeyValueDB::Iterator it = db->get_iterator(PREFIX_OMAP);
     string head, tail;
     get_omap_header(oldo->onode.omap_head, &head);
@@ -3530,7 +3559,7 @@ int NewStore::_clone(TransContext *txc,
       } else {
        dout(30) << __func__ << "  got header/data " << it->key() << dendl;
        assert(it->key() < tail);
-       rewrite_omap_key(o->onode.omap_head, it->key(), &key);
+       rewrite_omap_key(newo->onode.omap_head, it->key(), &key);
        txc->t->set(PREFIX_OMAP, key, it->value());
       }
       it->next();
index 7cb07664e1fd02cb986fa1fe33ea909e5b838804..8ce487823446cb70d43d57fddff45a2d19cc0a3b 100644 (file)
@@ -397,6 +397,21 @@ TEST_P(StoreTest, SimpleObjectTest) {
     in.hexdump(cout);
     ASSERT_TRUE(in.contents_equal(exp));
   }
+  {
+    ObjectStore::Transaction t;
+    bufferlist bl;
+    bl.append("abcde01234012340123401234abcde01234012340123401234abcde01234012340123401234abcde01234012340123401234");
+    t.write(cid, hoid, 0, bl.length(), bl);
+    cerr << "larger overwrite" << std::endl;
+    r = store->apply_transaction(t);
+    ASSERT_EQ(r, 0);
+
+    bufferlist in;
+    r = store->read(cid, hoid, 0, bl.length(), in);
+    ASSERT_EQ(bl.length(), r);
+    in.hexdump(cout);
+    ASSERT_TRUE(in.contents_equal(bl));
+  }
   {
     ObjectStore::Transaction t;
     t.remove(cid, hoid);