summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/os/CollectionIndex.h3
-rw-r--r--src/os/FileStore.cc9
-rw-r--r--src/os/HashIndex.cc28
-rw-r--r--src/os/HashIndex.h9
-rw-r--r--src/rgw/rgw_rados.cc3
5 files changed, 51 insertions, 1 deletions
diff --git a/src/os/CollectionIndex.h b/src/os/CollectionIndex.h
index d931a88b2d5..4cd1c1762fd 100644
--- a/src/os/CollectionIndex.h
+++ b/src/os/CollectionIndex.h
@@ -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() {}
};
diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc
index 9ab0e74b9c0..a039348c5e4 100644
--- a/src/os/FileStore.cc
+++ b/src/os/FileStore.cc
@@ -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;
diff --git a/src/os/HashIndex.cc b/src/os/HashIndex.cc
index 4c97c8a69cd..a6105e084e4 100644
--- a/src/os/HashIndex.cc
+++ b/src/os/HashIndex.cc
@@ -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);
diff --git a/src/os/HashIndex.h b/src/os/HashIndex.h
index cb0a3d2da20..68767bdb867 100644
--- a/src/os/HashIndex.h
+++ b/src/os/HashIndex.h
@@ -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
diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc
index 08c28fba4c8..9592d438b54 100644
--- a/src/rgw/rgw_rados.cc
+++ b/src/rgw/rgw_rados.cc
@@ -1131,6 +1131,9 @@ int RGWRados::copy_obj(void *ctx,
attrs[RGW_ATTR_ETAG] = attrset[RGW_ATTR_ETAG];
attrset = attrs;
+ } else {
+ /* copying attrs from source, however acls should not be copied */
+ attrset[RGW_ATTR_ACL] = attrs[RGW_ATTR_ACL];
}
ret = rgwstore->put_obj_meta(ctx, dest_obj, end + 1, NULL, attrset, category, false, NULL, &first_chunk, &manifest);