]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Fix write operation on a deleted object in the same transaction
authorHaomai Wang <haomaiwang@gmail.com>
Wed, 26 Feb 2014 09:46:07 +0000 (17:46 +0800)
committerroot <root@ceph-test.(none)>
Tue, 26 Aug 2014 04:39:35 +0000 (04:39 +0000)
If the following op happened:
touch obj
delete obj
write obj

KeyValueStore will fail at "write" operation.

Signed-off-by: Haomai Wang <haomaiwang@gmail.com>
src/os/GenericObjectMap.h
src/os/KeyValueStore.cc

index c9c64bc701efeddb5306f6f14b786b7625c323f0..80e100eaa71231d63835a5b9c6ce9ed215a02f1b 100644 (file)
@@ -371,6 +371,12 @@ protected:
     return GenericObjectMapIterator(new GenericObjectMapIteratorImpl(this, header, prefix));
   }
 
+  Header generate_new_header(const coll_t &cid, const ghobject_t &oid,
+                             Header parent, KeyValueDB::Transaction t) {
+    Mutex::Locker l(header_lock);
+    return _generate_new_header(cid, oid, parent, t);
+  }
+
   // Scan keys in header into out_keys and out_values (if nonnull)
   int scan(Header header, const string &prefix, const set<string> &in_keys,
            set<string> *out_keys, map<string, bufferlist> *out_values);
@@ -394,11 +400,6 @@ protected:
    */
   Header _generate_new_header(const coll_t &cid, const ghobject_t &oid,
                               Header parent, KeyValueDB::Transaction t);
-  Header generate_new_header(const coll_t &cid, const ghobject_t &oid,
-                             Header parent, KeyValueDB::Transaction t) {
-    Mutex::Locker l(header_lock);
-    return _generate_new_header(cid, oid, parent, t);
-  }
 
   // Lookup leaf header for c oid
   Header _lookup_header(const coll_t &cid, const ghobject_t &oid);
index 925578c75f718078caa495f3bb368a28b14b7d26..9ea7215578b7e1d1bc4cd34587498748b23965f0 100644 (file)
@@ -84,7 +84,7 @@ int StripObjectMap::create_strip_header(const coll_t &cid,
                                         StripObjectHeader &strip_header,
                                         KeyValueDB::Transaction t)
 {
-  Header header = lookup_create_header(cid, oid, t);
+  Header header = generate_new_header(cid, oid, Header(), t);
   if (!header)
     return -EINVAL;
 
@@ -246,16 +246,22 @@ int KeyValueStore::BufferTransaction::lookup_cached_header(
 
   StripHeaderMap::iterator it = strip_headers.find(make_pair(cid, oid));
   if (it != strip_headers.end()) {
-    if (it->second.deleted)
+
+    if (!it->second.deleted) {
+      if (strip_header)
+        *strip_header = &it->second;
+      return 0;
+    } else if (!create_if_missing) {
       return -ENOENT;
+    }
 
-    if (strip_header)
-      *strip_header = &it->second;
-    return 0;
+    // If (it->second.deleted && create_if_missing) go down
+    r = -ENOENT;
+  } else {
+    r = store->backend->lookup_strip_header(cid, oid, header);
   }
 
-  r = store->backend->lookup_strip_header(cid, oid, header);
-  if (r < 0 && create_if_missing) {
+  if (r == -ENOENT && create_if_missing) {
     r = store->backend->create_strip_header(cid, oid, header, t);
   }
 
@@ -385,6 +391,7 @@ int KeyValueStore::BufferTransaction::submit_transaction()
       continue;
 
     r = store->backend->save_strip_header(header, t);
+
     if (r < 0) {
       dout(10) << __func__ << " save strip header failed " << dendl;
       goto out;
@@ -1624,6 +1631,8 @@ int KeyValueStore::_remove(coll_t cid, const ghobject_t& oid,
     return r;
   }
 
+  header->max_size = 0;
+  header->bits.clear();
   r = t.clear_buffer(*header);
 
   dout(10) << __func__ << " " << cid << "/" << oid << " = " << r << dendl;