diff options
-rw-r--r-- | src/os/CollectionIndex.h | 3 | ||||
-rw-r--r-- | src/os/FileStore.cc | 9 | ||||
-rw-r--r-- | src/os/HashIndex.cc | 28 | ||||
-rw-r--r-- | src/os/HashIndex.h | 9 | ||||
-rw-r--r-- | src/rgw/rgw_rados.cc | 3 |
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); |