]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/: Add CollectionIndex::prep_delete
authorSamuel Just <sam.just@inktank.com>
Sun, 18 Nov 2012 02:18:23 +0000 (18:18 -0800)
committerSamuel Just <sam.just@inktank.com>
Fri, 18 Jan 2013 18:45:43 +0000 (10:45 -0800)
If an unlink is interupted between removing the file
and updating the subdir attribute, the attribute will
overestimate the number of files in the directory.  This
is by design, at worst we will merge the collection later
than intended, but closing the gap would require a second
subdir xattr update.  However, this can in extreme cases
result in a collection with subdirectories but no objects.
FileStore::_destry_collection would therefore see an
erroneous -ENOTEMPTY.

prep_delete allows the CollectionIndex implementation to
clean up state prior to removal.

Signed-off-by: Samuel Just <sam.just@inktank.com>
(cherry picked from commit fdc5e5d1877d7d7ed3851b9ec01f884559748249)

Conflicts:

src/os/HashIndex.cc
src/os/HashIndex.h

src/os/CollectionIndex.h
src/os/FileStore.cc
src/os/HashIndex.cc
src/os/HashIndex.h

index d931a88b2d5d7f4f6c18e5341e718043ff54638a..4cd1c1762fd31a52bd9af603daace6a8bc5407e3 100644 (file)
@@ -166,6 +166,9 @@ protected:
     vector<hobject_t> *ls ///< [out] Listed Objects
     ) = 0;
 
+  /// Call prior to removing directory
+  virtual int prep_delete() { return 0; }
+
   /// Virtual destructor
   virtual ~CollectionIndex() {}
 };
index 9ab0e74b9c0fbabf13da91c634a6cdbdd0d24767..a039348c5e415b6576f78b01aa1d2ab794264b2c 100644 (file)
@@ -4705,6 +4705,15 @@ int FileStore::_create_collection(coll_t c)
 
 int FileStore::_destroy_collection(coll_t c) 
 {
+  {
+    Index from;
+    int r = get_index(c, &from);
+    if (r < 0)
+      return r;
+    r = from->prep_delete();
+    if (r < 0)
+      return r;
+  }
   char fn[PATH_MAX];
   get_cdir(c, fn, sizeof(fn));
   dout(15) << "_destroy_collection " << fn << dendl;
index 4c97c8a69cd4fb9ed3b726fe8e0eb14aa101ef88..a6105e084e4dcb885264dcad015823ec53c62b2f 100644 (file)
@@ -143,6 +143,34 @@ int HashIndex::_collection_list_partial(const hobject_t &start,
   return list_by_hash(path, min_count, max_count, seq, next, ls);
 }
 
+int HashIndex::prep_delete() {
+  return recursive_remove(vector<string>());
+}
+
+int HashIndex::recursive_remove(const vector<string> &path) {
+  set<string> subdirs;
+  int r = list_subdirs(path, &subdirs);
+  if (r < 0)
+    return r;
+  map<string, hobject_t> objects;
+  r = list_objects(path, 0, 0, &objects);
+  if (r < 0)
+    return r;
+  if (objects.size())
+    return -ENOTEMPTY;
+  vector<string> subdir(path);
+  for (set<string>::iterator i = subdirs.begin();
+       i != subdirs.end();
+       ++i) {
+    subdir.push_back(*i);
+    r = recursive_remove(subdir);
+    if (r < 0)
+      return r;
+    subdir.pop_back();
+  }
+  return remove_path(path);
+}
+
 int HashIndex::start_split(const vector<string> &path) {
   bufferlist bl;
   InProgressOp op_tag(InProgressOp::SPLIT, path);
index cb0a3d2da20ce46f7a45aaf403c3ce173c17e745..68767bdb867b4708275e6c585690f9be4cf7ef2b 100644 (file)
@@ -143,7 +143,10 @@ public:
 
   /// @see CollectionIndex
   int cleanup();
-       
+
+  /// @see CollectionIndex
+  int prep_delete();
+
 protected:
   int _init();
 
@@ -175,6 +178,10 @@ protected:
     hobject_t *next
     );
 private:
+  /// Recursively remove path and its subdirs
+  int recursive_remove(
+    const vector<string> &path ///< [in] path to remove
+    ); /// @return Error Code, 0 on success
   /// Tag root directory at beginning of split
   int start_split(
     const vector<string> &path ///< [in] path to split