]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/driver/rados/rgw_metadata.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / rgw / driver / rados / rgw_metadata.cc
CommitLineData
1e59de90
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#include "rgw_metadata.h"
5
6#include "rgw_zone.h"
7#include "rgw_mdlog.h"
8
9#include "services/svc_zone.h"
10#include "services/svc_cls.h"
11
12#define dout_subsys ceph_subsys_rgw
13
14using namespace std;
15
16const std::string RGWMetadataLogHistory::oid = "meta.history";
17
18struct obj_version;
19
20void rgw_shard_name(const string& prefix, unsigned max_shards, const string& key, string& name, int *shard_id)
21{
22 uint32_t val = ceph_str_hash_linux(key.c_str(), key.size());
23 char buf[16];
24 if (shard_id) {
25 *shard_id = val % max_shards;
26 }
27 snprintf(buf, sizeof(buf), "%u", (unsigned)(val % max_shards));
28 name = prefix + buf;
29}
30
31void rgw_shard_name(const string& prefix, unsigned max_shards, const string& section, const string& key, string& name)
32{
33 uint32_t val = ceph_str_hash_linux(key.c_str(), key.size());
34 val ^= ceph_str_hash_linux(section.c_str(), section.size());
35 char buf[16];
36 snprintf(buf, sizeof(buf), "%u", (unsigned)(val % max_shards));
37 name = prefix + buf;
38}
39
40void rgw_shard_name(const string& prefix, unsigned shard_id, string& name)
41{
42 char buf[16];
43 snprintf(buf, sizeof(buf), "%u", shard_id);
44 name = prefix + buf;
45}
46
47int RGWMetadataLog::add_entry(const DoutPrefixProvider *dpp, const string& hash_key, const string& section, const string& key, bufferlist& bl) {
48 if (!svc.zone->need_to_log_metadata())
49 return 0;
50
51 string oid;
52 int shard_id;
53
54 rgw_shard_name(prefix, cct->_conf->rgw_md_log_max_shards, hash_key, oid, &shard_id);
55 mark_modified(shard_id);
56 real_time now = real_clock::now();
57 return svc.cls->timelog.add(dpp, oid, now, section, key, bl, null_yield);
58}
59
60int RGWMetadataLog::get_shard_id(const string& hash_key, int *shard_id)
61{
62 string oid;
63
64 rgw_shard_name(prefix, cct->_conf->rgw_md_log_max_shards, hash_key, oid, shard_id);
65 return 0;
66}
67
68int RGWMetadataLog::store_entries_in_shard(const DoutPrefixProvider *dpp, list<cls_log_entry>& entries, int shard_id, librados::AioCompletion *completion)
69{
70 string oid;
71
72 mark_modified(shard_id);
73 rgw_shard_name(prefix, shard_id, oid);
74 return svc.cls->timelog.add(dpp, oid, entries, completion, false, null_yield);
75}
76
77void RGWMetadataLog::init_list_entries(int shard_id, const real_time& from_time, const real_time& end_time,
78 const string& marker, void **handle)
79{
80 LogListCtx *ctx = new LogListCtx();
81
82 ctx->cur_shard = shard_id;
83 ctx->from_time = from_time;
84 ctx->end_time = end_time;
85 ctx->marker = marker;
86
87 get_shard_oid(ctx->cur_shard, ctx->cur_oid);
88
89 *handle = (void *)ctx;
90}
91
92void RGWMetadataLog::complete_list_entries(void *handle) {
93 LogListCtx *ctx = static_cast<LogListCtx *>(handle);
94 delete ctx;
95}
96
97int RGWMetadataLog::list_entries(const DoutPrefixProvider *dpp, void *handle,
98 int max_entries,
99 list<cls_log_entry>& entries,
100 string *last_marker,
101 bool *truncated) {
102 LogListCtx *ctx = static_cast<LogListCtx *>(handle);
103
104 if (!max_entries) {
105 *truncated = false;
106 return 0;
107 }
108
109 std::string next_marker;
110 int ret = svc.cls->timelog.list(dpp, ctx->cur_oid, ctx->from_time, ctx->end_time,
111 max_entries, entries, ctx->marker,
112 &next_marker, truncated, null_yield);
113 if ((ret < 0) && (ret != -ENOENT))
114 return ret;
115
116 ctx->marker = std::move(next_marker);
117 if (last_marker) {
118 *last_marker = ctx->marker;
119 }
120
121 if (ret == -ENOENT)
122 *truncated = false;
123
124 return 0;
125}
126
127int RGWMetadataLog::get_info(const DoutPrefixProvider *dpp, int shard_id, RGWMetadataLogInfo *info)
128{
129 string oid;
130 get_shard_oid(shard_id, oid);
131
132 cls_log_header header;
133
134 int ret = svc.cls->timelog.info(dpp, oid, &header, null_yield);
135 if ((ret < 0) && (ret != -ENOENT))
136 return ret;
137
138 info->marker = header.max_marker;
139 info->last_update = header.max_time.to_real_time();
140
141 return 0;
142}
143
144static void _mdlog_info_completion(librados::completion_t cb, void *arg)
145{
146 auto infoc = static_cast<RGWMetadataLogInfoCompletion *>(arg);
147 infoc->finish(cb);
148 infoc->put(); // drop the ref from get_info_async()
149}
150
151RGWMetadataLogInfoCompletion::RGWMetadataLogInfoCompletion(info_callback_t cb)
152 : completion(librados::Rados::aio_create_completion((void *)this,
153 _mdlog_info_completion)),
154 callback(cb)
155{
156}
157
158RGWMetadataLogInfoCompletion::~RGWMetadataLogInfoCompletion()
159{
160 completion->release();
161}
162
163int RGWMetadataLog::get_info_async(const DoutPrefixProvider *dpp, int shard_id, RGWMetadataLogInfoCompletion *completion)
164{
165 string oid;
166 get_shard_oid(shard_id, oid);
167
168 completion->get(); // hold a ref until the completion fires
169
170 return svc.cls->timelog.info_async(dpp, completion->get_io_obj(), oid,
171 &completion->get_header(),
172 completion->get_completion());
173}
174
175int RGWMetadataLog::trim(const DoutPrefixProvider *dpp, int shard_id, const real_time& from_time, const real_time& end_time,
176 const string& start_marker, const string& end_marker)
177{
178 string oid;
179 get_shard_oid(shard_id, oid);
180
181 return svc.cls->timelog.trim(dpp, oid, from_time, end_time, start_marker,
182 end_marker, nullptr, null_yield);
183}
184
185int RGWMetadataLog::lock_exclusive(const DoutPrefixProvider *dpp, int shard_id, timespan duration, string& zone_id, string& owner_id) {
186 string oid;
187 get_shard_oid(shard_id, oid);
188
189 return svc.cls->lock.lock_exclusive(dpp, svc.zone->get_zone_params().log_pool, oid, duration, zone_id, owner_id);
190}
191
192int RGWMetadataLog::unlock(const DoutPrefixProvider *dpp, int shard_id, string& zone_id, string& owner_id) {
193 string oid;
194 get_shard_oid(shard_id, oid);
195
196 return svc.cls->lock.unlock(dpp, svc.zone->get_zone_params().log_pool, oid, zone_id, owner_id);
197}
198
199void RGWMetadataLog::mark_modified(int shard_id)
200{
201 lock.get_read();
202 if (modified_shards.find(shard_id) != modified_shards.end()) {
203 lock.unlock();
204 return;
205 }
206 lock.unlock();
207
208 std::unique_lock wl{lock};
209 modified_shards.insert(shard_id);
210}
211
212void RGWMetadataLog::read_clear_modified(set<int> &modified)
213{
214 std::unique_lock wl{lock};
215 modified.swap(modified_shards);
216 modified_shards.clear();
217}
218
219void RGWMetadataLogInfo::dump(Formatter *f) const
220{
221 encode_json("marker", marker, f);
222 utime_t ut(last_update);
223 encode_json("last_update", ut, f);
224}
225
226void RGWMetadataLogInfo::decode_json(JSONObj *obj)
227{
228 JSONDecoder::decode_json("marker", marker, obj);
229 utime_t ut;
230 JSONDecoder::decode_json("last_update", ut, obj);
231 last_update = ut.to_real_time();
232}
233