]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/DBObjectMap, FileStore: omap_clear should not remove xattrs
authorSamuel Just <sam.just@inktank.com>
Fri, 10 Jan 2014 21:23:32 +0000 (13:23 -0800)
committerSamuel Just <sam.just@inktank.com>
Fri, 10 Jan 2014 22:02:25 +0000 (14:02 -0800)
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 <sam.just@inktank.com>
src/os/DBObjectMap.cc
src/os/DBObjectMap.h
src/os/FileStore.cc
src/os/ObjectMap.h

index 635870b0db52f561d963d206c1801e2767aa6fc0..059984fd16141148198bef092dc70073d57f6c9c 100644 (file)
@@ -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<string, bufferlist> 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<string, bufferlist> *out)
index 459447f9c97e36b4837a397e039e6de7a44a8259..eb3950cfa3be0e316799f8997e4ca32383a1d837 100644 (file)
@@ -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<string> &to_clear,
index 22db6002db556c92f37d1e2bec3a54b20bac303b..2f4bfb696463c9810606474acf3d6b15413a85a0 100644 (file)
@@ -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;
index 7717aac7437a0a7384d56ba1bc5fc228b4fd0466..b460a95663687673e16b8d82821d9c8b1c8059ce 100644 (file)
@@ -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<string> &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<string> *out       ///< [out] attrs and values
+    set<string> *out                   ///< [out] attrs and values
     ) = 0;
 
   /// set xattrs in to_set