]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab ft=cpp | |
3 | ||
4 | /* | |
5 | * Ceph - scalable distributed file system | |
6 | * | |
7 | * Copyright (C) 2019 Red Hat, Inc. | |
8 | * | |
9 | * This is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU Lesser General Public | |
11 | * License version 2.1, as published by the Free Software | |
12 | * Foundation. See file COPYING. | |
13 | * | |
14 | */ | |
15 | ||
16 | ||
17 | #pragma once | |
18 | ||
e306af50 TL |
19 | #include <iomanip> |
20 | ||
1e59de90 | 21 | #include "rgw_service.h" |
9f95a23c TL |
22 | |
23 | #include "svc_rados.h" | |
24 | ||
25 | extern const std::string MP_META_SUFFIX; | |
26 | ||
27 | class RGWMPObj { | |
20effc67 TL |
28 | std::string oid; |
29 | std::string prefix; | |
30 | std::string meta; | |
31 | std::string upload_id; | |
9f95a23c TL |
32 | public: |
33 | RGWMPObj() {} | |
20effc67 | 34 | RGWMPObj(const std::string& _oid, const std::string& _upload_id) { |
9f95a23c TL |
35 | init(_oid, _upload_id, _upload_id); |
36 | } | |
20effc67 TL |
37 | RGWMPObj(const std::string& _oid, std::optional<std::string> _upload_id) { |
38 | if (_upload_id) { | |
39 | init(_oid, *_upload_id, *_upload_id); | |
40 | } else { | |
41 | from_meta(_oid); | |
42 | } | |
43 | } | |
44 | void init(const std::string& _oid, const std::string& _upload_id) { | |
9f95a23c TL |
45 | init(_oid, _upload_id, _upload_id); |
46 | } | |
20effc67 | 47 | void init(const std::string& _oid, const std::string& _upload_id, const std::string& part_unique_str) { |
9f95a23c TL |
48 | if (_oid.empty()) { |
49 | clear(); | |
50 | return; | |
51 | } | |
52 | oid = _oid; | |
53 | upload_id = _upload_id; | |
54 | prefix = oid + "."; | |
55 | meta = prefix + upload_id + MP_META_SUFFIX; | |
56 | prefix.append(part_unique_str); | |
57 | } | |
20effc67 TL |
58 | const std::string& get_meta() const { return meta; } |
59 | std::string get_part(int num) const { | |
9f95a23c TL |
60 | char buf[16]; |
61 | snprintf(buf, 16, ".%d", num); | |
20effc67 | 62 | std::string s = prefix; |
9f95a23c TL |
63 | s.append(buf); |
64 | return s; | |
65 | } | |
20effc67 TL |
66 | std::string get_part(const std::string& part) const { |
67 | std::string s = prefix; | |
9f95a23c TL |
68 | s.append("."); |
69 | s.append(part); | |
70 | return s; | |
71 | } | |
20effc67 | 72 | const std::string& get_upload_id() const { |
9f95a23c TL |
73 | return upload_id; |
74 | } | |
20effc67 | 75 | const std::string& get_key() const { |
9f95a23c TL |
76 | return oid; |
77 | } | |
20effc67 | 78 | bool from_meta(const std::string& meta) { |
9f95a23c TL |
79 | int end_pos = meta.rfind('.'); // search for ".meta" |
80 | if (end_pos < 0) | |
81 | return false; | |
82 | int mid_pos = meta.rfind('.', end_pos - 1); // <key>.<upload_id> | |
83 | if (mid_pos < 0) | |
84 | return false; | |
85 | oid = meta.substr(0, mid_pos); | |
86 | upload_id = meta.substr(mid_pos + 1, end_pos - mid_pos - 1); | |
87 | init(oid, upload_id, upload_id); | |
88 | return true; | |
89 | } | |
90 | void clear() { | |
91 | oid = ""; | |
92 | prefix = ""; | |
93 | meta = ""; | |
94 | upload_id = ""; | |
95 | } | |
e306af50 TL |
96 | friend std::ostream& operator<<(std::ostream& out, const RGWMPObj& obj) { |
97 | return out << "RGWMPObj:{ prefix=" << std::quoted(obj.prefix) << | |
98 | ", meta=" << std::quoted(obj.meta) << " }"; | |
99 | } | |
9f95a23c TL |
100 | }; // class RGWMPObj |
101 | ||
102 | /** | |
103 | * A filter to a) test whether an object name is a multipart meta | |
104 | * object, and b) filter out just the key used to determine the bucket | |
105 | * index shard. | |
106 | * | |
107 | * Objects for multipart meta have names adorned with an upload id and | |
108 | * other elements -- specifically a ".", MULTIPART_UPLOAD_ID_PREFIX, | |
109 | * unique id, and MP_META_SUFFIX. This filter will return true when | |
110 | * the name provided is such. It will also extract the key used for | |
111 | * bucket index shard calculation from the adorned name. | |
112 | */ | |
113 | class MultipartMetaFilter : public RGWAccessListFilter { | |
114 | public: | |
115 | MultipartMetaFilter() {} | |
116 | ||
20effc67 TL |
117 | virtual ~MultipartMetaFilter() override; |
118 | ||
9f95a23c TL |
119 | /** |
120 | * @param name [in] The object name as it appears in the bucket index. | |
121 | * @param key [out] An output parameter that will contain the bucket | |
122 | * index key if this entry is in the form of a multipart meta object. | |
123 | * @return true if the name provided is in the form of a multipart meta | |
124 | * object, false otherwise | |
125 | */ | |
20effc67 | 126 | bool filter(const std::string& name, std::string& key) override; |
9f95a23c TL |
127 | }; |
128 | ||
129 | class RGWSI_Tier_RADOS : public RGWServiceInstance | |
130 | { | |
131 | RGWSI_Zone *zone_svc{nullptr}; | |
132 | ||
133 | public: | |
134 | RGWSI_Tier_RADOS(CephContext *cct): RGWServiceInstance(cct) {} | |
135 | ||
136 | void init(RGWSI_Zone *_zone_svc) { | |
137 | zone_svc = _zone_svc; | |
138 | } | |
139 | ||
140 | static inline bool raw_obj_to_obj(const rgw_bucket& bucket, const rgw_raw_obj& raw_obj, rgw_obj *obj) { | |
20effc67 | 141 | ssize_t pos = raw_obj.oid.find('_', bucket.marker.length()); |
9f95a23c TL |
142 | if (pos < 0) { |
143 | return false; | |
144 | } | |
145 | ||
146 | if (!rgw_obj_key::parse_raw_oid(raw_obj.oid.substr(pos + 1), &obj->key)) { | |
147 | return false; | |
148 | } | |
149 | obj->bucket = bucket; | |
150 | ||
151 | return true; | |
152 | } | |
153 | }; | |
154 |