bool operator<=(const cls_rgw_obj_key& k) const {
return !(k < *this);
}
- bool empty() {
+ bool empty() const {
return name.empty();
}
void encode(bufferlist &bl) const {
}
}
+ // takes an oid and parses out the namespace (ns), name, and
+ // instance
static bool parse_raw_oid(const string& oid, rgw_obj_key *key) {
key->instance.clear();
key->ns.clear();
+bool MultipartMetaFilter::filter(const string& name, string& key) {
+ // the length of the suffix so we can skip past it
+ static const size_t MP_META_SUFFIX_LEN = MP_META_SUFFIX.length();
+
+ size_t len = name.size();
+
+ // make sure there's room for suffix plus at least one more
+ // character
+ if (len <= MP_META_SUFFIX_LEN)
+ return false;
+
+ size_t pos = name.find(MP_META_SUFFIX, len - MP_META_SUFFIX_LEN);
+ if (pos == string::npos)
+ return false;
+
+ pos = name.rfind('.', pos - 1);
+ if (pos == string::npos)
+ return false;
+
+ key = name.substr(0, pos);
+
+ return true;
+}
+
+
bool RGWMultiPart::xml_end(const char *el)
{
RGWMultiPartNumber *num_obj = static_cast<RGWMultiPartNumber *>(find_first("PartNumber"));
(strncmp(uid, MULTIPART_UPLOAD_ID_PREFIX_LEGACY, sizeof(MULTIPART_UPLOAD_ID_PREFIX_LEGACY) - 1) == 0);
}
-int list_multipart_parts(RGWRados *store, RGWBucketInfo& bucket_info, CephContext *cct,
- const string& upload_id,
- string& meta_oid, int num_parts,
- int marker, map<uint32_t, RGWUploadPartInfo>& parts,
- int *next_marker, bool *truncated,
- bool assume_unsorted)
+int list_multipart_parts(RGWRados *store, RGWBucketInfo& bucket_info,
+ CephContext *cct,
+ const string& upload_id,
+ const string& meta_oid, int num_parts,
+ int marker, map<uint32_t, RGWUploadPartInfo>& parts,
+ int *next_marker, bool *truncated,
+ bool assume_unsorted)
{
map<string, bufferlist> parts_map;
map<string, bufferlist>::iterator iter;
}
int list_multipart_parts(RGWRados *store, struct req_state *s,
- const string& upload_id,
- string& meta_oid, int num_parts,
- int marker, map<uint32_t, RGWUploadPartInfo>& parts,
- int *next_marker, bool *truncated,
- bool assume_unsorted)
+ const string& upload_id,
+ const string& meta_oid, int num_parts,
+ int marker, map<uint32_t, RGWUploadPartInfo>& parts,
+ int *next_marker, bool *truncated,
+ bool assume_unsorted)
{
return list_multipart_parts(store, s->bucket_info, s->cct, upload_id, meta_oid, num_parts, marker, parts, next_marker, truncated, assume_unsorted);
}
#include "rgw_xml.h"
#include "rgw_rados.h"
-#define MP_META_SUFFIX ".meta"
#define MULTIPART_UPLOAD_ID_PREFIX_LEGACY "2/"
#define MULTIPART_UPLOAD_ID_PREFIX "2~" // must contain a unique char that may not come up in gen_rand_alpha()
~RGWMultiXMLParser() override {}
};
+/**
+ * A filter to a) test whether an object name is a multipart meta
+ * object, and b) filter out just the key used to determine the bucket
+ * index shard.
+ *
+ * Objects for multipart meta have names adorned with an upload id and
+ * other elements -- specifically a ".", MULTIPART_UPLOAD_ID_PREFIX,
+ * unique id, and MP_META_SUFFIX. This filter will return true when
+ * the name provided is such. It will also extract the key used for
+ * bucket index shard calculation from the adorned name.
+ */
class MultipartMetaFilter : public RGWAccessListFilter {
public:
MultipartMetaFilter() {}
- bool filter(string& name, string& key) override {
- int len = name.size();
- if (len < 6)
- return false;
- size_t pos = name.find(MP_META_SUFFIX, len - 5);
- if (pos == string::npos)
- return false;
-
- pos = name.rfind('.', pos - 1);
- if (pos == string::npos)
- return false;
-
- key = name.substr(0, pos);
-
- return true;
- }
-};
+ /**
+ * @param name [in] The object name as it appears in the bucket index.
+ * @param key [out] An output parameter that will contain the bucket
+ * index key if this entry is in the form of a multipart meta object.
+ * @return true if the name provided is in the form of a multipart meta
+ * object, false otherwise
+ */
+ bool filter(const string& name, string& key) override;
+}; // class MultipartMetaFilter
extern bool is_v2_upload_id(const string& upload_id);
-extern int list_multipart_parts(RGWRados *store, RGWBucketInfo& bucket_info, CephContext *cct,
+extern int list_multipart_parts(RGWRados *store, RGWBucketInfo& bucket_info,
+ CephContext *cct,
const string& upload_id,
- string& meta_oid, int num_parts,
+ const string& meta_oid, int num_parts,
int marker, map<uint32_t, RGWUploadPartInfo>& parts,
int *next_marker, bool *truncated,
bool assume_unsorted = false);
extern int list_multipart_parts(RGWRados *store, struct req_state *s,
const string& upload_id,
- string& meta_oid, int num_parts,
+ const string& meta_oid, int num_parts,
int marker, map<uint32_t, RGWUploadPartInfo>& parts,
int *next_marker, bool *truncated,
bool assume_unsorted = false);
}
static int get_multipart_info(RGWRados *store, struct req_state *s,
- string& meta_oid,
+ const string& meta_oid,
RGWAccessControlPolicy *policy,
map<string, bufferlist> *attrs,
multipart_upload_info *upload_info)
static RGWObjCategory main_category = RGWObjCategory::Main;
#define RGW_USAGE_OBJ_PREFIX "usage."
-
#define dout_subsys ceph_subsys_rgw
+const std::string MP_META_SUFFIX = ".meta";
+
static bool rgw_get_obj_data_pool(const RGWZoneGroup& zonegroup, const RGWZoneParams& zone_params,
const rgw_placement_rule& head_placement_rule,
int RGWRados::cls_bucket_list_ordered(RGWBucketInfo& bucket_info,
int shard_id,
- rgw_obj_index_key& start,
+ const rgw_obj_index_key& start,
const string& prefix,
uint32_t num_entries,
bool list_versions,
int RGWRados::cls_bucket_list_unordered(RGWBucketInfo& bucket_info,
int shard_id,
- rgw_obj_index_key& start,
+ const rgw_obj_index_key& start,
const string& prefix,
uint32_t num_entries,
bool list_versions,
#define RGW_SHARDS_PRIME_0 7877
#define RGW_SHARDS_PRIME_1 65521
+extern const std::string MP_META_SUFFIX;
+
// only called by rgw_shard_id and rgw_bucket_shard_index
static inline int rgw_shards_mod(unsigned hval, int max_shards)
{
int cls_obj_complete_cancel(BucketShard& bs, string& tag, rgw_obj& obj, uint16_t bilog_flags, rgw_zone_set *zones_trace = nullptr);
int cls_obj_set_bucket_tag_timeout(RGWBucketInfo& bucket_info, uint64_t timeout);
int cls_bucket_list_ordered(RGWBucketInfo& bucket_info, int shard_id,
- rgw_obj_index_key& start, const string& prefix,
+ const rgw_obj_index_key& start,
+ const string& prefix,
uint32_t num_entries, bool list_versions,
map<string, rgw_bucket_dir_entry>& m,
bool *is_truncated,
rgw_obj_index_key *last_entry,
bool (*force_check_filter)(const string& name) = nullptr);
int cls_bucket_list_unordered(RGWBucketInfo& bucket_info, int shard_id,
- rgw_obj_index_key& start, const string& prefix,
+ const rgw_obj_index_key& start,
+ const string& prefix,
uint32_t num_entries, bool list_versions,
vector<rgw_bucket_dir_entry>& ent_list,
bool *is_truncated, rgw_obj_index_key *last_entry,
};
-#define MP_META_SUFFIX ".meta"
-
class RGWMPObj {
string oid;
string prefix;
meta = prefix + upload_id + MP_META_SUFFIX;
prefix.append(part_unique_str);
}
- string& get_meta() { return meta; }
- string get_part(int num) {
+ const string& get_meta() const { return meta; }
+ string get_part(int num) const {
char buf[16];
snprintf(buf, 16, ".%d", num);
string s = prefix;
s.append(buf);
return s;
}
- string get_part(string& part) {
+ string get_part(const string& part) const {
string s = prefix;
s.append(".");
s.append(part);
return s;
}
- string& get_upload_id() {
+ const string& get_upload_id() const {
return upload_id;
}
- string& get_key() {
+ const string& get_key() const {
return oid;
}
bool from_meta(string& meta) {
meta = "";
upload_id = "";
}
-};
+}; // class RGWMPObj
class RGWRadosThread {
s->formatter->dump_string("Bucket", s->bucket_name);
if (!prefix.empty())
s->formatter->dump_string("ListMultipartUploadsResult.Prefix", prefix);
- string& key_marker = marker.get_key();
+ const string& key_marker = marker.get_key();
if (!key_marker.empty())
s->formatter->dump_string("KeyMarker", key_marker);
- string& upload_id_marker = marker.get_upload_id();
+ const string& upload_id_marker = marker.get_upload_id();
if (!upload_id_marker.empty())
s->formatter->dump_string("UploadIdMarker", upload_id_marker);
string next_key = next_marker.mp.get_key();
class RGWAccessListFilter {
public:
virtual ~RGWAccessListFilter() {}
- virtual bool filter(string& name, string& key) = 0;
+ virtual bool filter(const string& name, string& key) = 0;
};
struct RGWAccessListFilterPrefix : public RGWAccessListFilter {
string prefix;
explicit RGWAccessListFilterPrefix(const string& _prefix) : prefix(_prefix) {}
- bool filter(string& name, string& key) override {
+ bool filter(const string& name, string& key) override {
return (prefix.compare(key.substr(0, prefix.size())) == 0);
}
};