From: Haomai Wang Date: Wed, 26 Feb 2014 09:46:07 +0000 (+0800) Subject: Fix write operation on a deleted object in the same transaction X-Git-Tag: v0.83~95^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=50c8fee8fda42f78ea563cab6229bdf0af3c8c99;p=ceph.git Fix write operation on a deleted object in the same transaction If the following op happened: touch obj delete obj write obj KeyValueStore will fail at "write" operation. Signed-off-by: Haomai Wang --- diff --git a/src/os/GenericObjectMap.h b/src/os/GenericObjectMap.h index c9c64bc701ef..80e100eaa712 100644 --- a/src/os/GenericObjectMap.h +++ b/src/os/GenericObjectMap.h @@ -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 &in_keys, set *out_keys, map *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); diff --git a/src/os/KeyValueStore.cc b/src/os/KeyValueStore.cc index 48b734762c70..bc56e43dcf4f 100644 --- a/src/os/KeyValueStore.cc +++ b/src/os/KeyValueStore.cc @@ -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; @@ -245,16 +245,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); } @@ -384,6 +390,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; @@ -1623,6 +1630,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;