From: Samuel Just Date: Fri, 10 Jan 2014 21:23:32 +0000 (-0800) Subject: os/DBObjectMap, FileStore: omap_clear should not remove xattrs X-Git-Tag: v0.77~28^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0c81849c4f1661ce89b8623edaf2873bb6611f62;p=ceph.git os/DBObjectMap, FileStore: omap_clear should not remove xattrs Prevously, FileStore::_omap_clear() used ObjectMap::clear(), which incorrectly also blasts any stored xattrs. Instead, add ObjectMap::clear_keys_header() to handle this case efficiently. Fixes: #7065 Fixes: #7135 Signed-off-by: Samuel Just --- diff --git a/src/os/DBObjectMap.cc b/src/os/DBObjectMap.cc index 635870b0db5..059984fd161 100644 --- a/src/os/DBObjectMap.cc +++ b/src/os/DBObjectMap.cc @@ -769,6 +769,42 @@ int DBObjectMap::rm_keys(const ghobject_t &oid, return db->submit_transaction(t); } +int DBObjectMap::clear_keys_header(const ghobject_t &oid, + const SequencerPosition *spos) +{ + KeyValueDB::Transaction t = db->get_transaction(); + Header header = lookup_map_header(oid); + if (!header) + return -ENOENT; + if (check_spos(oid, header, spos)) + return 0; + + // save old attrs + KeyValueDB::Iterator iter = db->get_iterator(xattr_prefix(header)); + if (!iter) + return -EINVAL; + map attrs; + for (iter->seek_to_first(); !iter->status() && iter->valid(); iter->next()) + attrs.insert(make_pair(iter->key(), iter->value())); + if (iter->status()) + return iter->status(); + + // remove current header + remove_map_header(oid, header, t); + assert(header->num_children > 0); + header->num_children--; + int r = _clear(header, t); + if (r < 0) + return r; + + // create new header + Header newheader = _generate_new_header(oid, Header()); + set_map_header(oid, *newheader, t); + if (attrs.size()) + t->set(xattr_prefix(newheader), attrs); + return db->submit_transaction(t); +} + int DBObjectMap::get(const ghobject_t &oid, bufferlist *_header, map *out) diff --git a/src/os/DBObjectMap.h b/src/os/DBObjectMap.h index 459447f9c97..eb3950cfa3b 100644 --- a/src/os/DBObjectMap.h +++ b/src/os/DBObjectMap.h @@ -94,6 +94,11 @@ public: const SequencerPosition *spos=0 ); + int clear_keys_header( + const ghobject_t &oid, + const SequencerPosition *spos=0 + ); + int rm_keys( const ghobject_t &oid, const set &to_clear, diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index 22db6002db5..2f4bfb69646 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -4380,7 +4380,7 @@ int FileStore::_omap_clear(coll_t cid, const ghobject_t &hoid, int r = lfn_find(cid, hoid, &path); if (r < 0) return r; - r = object_map->clear(hoid, &spos); + r = object_map->clear_keys_header(hoid, &spos); if (r < 0 && r != -ENOENT) return r; return 0; diff --git a/src/os/ObjectMap.h b/src/os/ObjectMap.h index 7717aac7437..b460a956636 100644 --- a/src/os/ObjectMap.h +++ b/src/os/ObjectMap.h @@ -54,13 +54,19 @@ public: const SequencerPosition *spos=0 ///< [in] sequencer position ) = 0; - /// Clear all map keys and values from oid + /// Clear all map keys and values in to_clear from oid virtual int rm_keys( const ghobject_t &oid, ///< [in] object containing map const set &to_clear, ///< [in] Keys to clear const SequencerPosition *spos=0 ///< [in] sequencer position ) = 0; + /// Clear all omap keys and the header + virtual int clear_keys_header( + const ghobject_t &oid, ///< [in] oid to clear + const SequencerPosition *spos=0 ///< [in] sequencer position + ) = 0; + /// Get all keys and values virtual int get( const ghobject_t &oid, ///< [in] object containing map @@ -98,7 +104,7 @@ public: /// Get all xattrs virtual int get_all_xattrs( const ghobject_t &oid, ///< [in] object - set *out ///< [out] attrs and values + set *out ///< [out] attrs and values ) = 0; /// set xattrs in to_set