]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/services/svc_sys_obj_cache.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / rgw / services / svc_sys_obj_cache.h
CommitLineData
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
11fdf7f2 3
9f95a23c 4#pragma once
11fdf7f2 5
20effc67 6#include "common/RWLock.h"
11fdf7f2
TL
7#include "rgw/rgw_service.h"
8#include "rgw/rgw_cache.h"
9
10#include "svc_sys_obj_core.h"
11
12class RGWSI_Notify;
13
14class RGWSI_SysObj_Cache_CB;
9f95a23c 15class RGWSI_SysObj_Cache_ASocketHook;
11fdf7f2
TL
16
17class RGWSI_SysObj_Cache : public RGWSI_SysObj_Core
18{
19 friend class RGWSI_SysObj_Cache_CB;
20 friend class RGWServices_Def;
9f95a23c 21 friend class ASocketHandler;
11fdf7f2
TL
22
23 RGWSI_Notify *notify_svc{nullptr};
24 ObjectCache cache;
25
26 std::shared_ptr<RGWSI_SysObj_Cache_CB> cb;
27
20effc67 28 void normalize_pool_and_obj(const rgw_pool& src_pool, const std::string& src_obj, rgw_pool& dst_pool, std::string& dst_obj);
11fdf7f2
TL
29protected:
30 void init(RGWSI_RADOS *_rados_svc,
31 RGWSI_Zone *_zone_svc,
32 RGWSI_Notify *_notify_svc) {
33 core_init(_rados_svc, _zone_svc);
34 notify_svc = _notify_svc;
35 }
36
b3b6e05e 37 int do_start(optional_yield, const DoutPrefixProvider *dpp) override;
9f95a23c 38 void shutdown() override;
11fdf7f2 39
b3b6e05e 40 int raw_stat(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, uint64_t *psize, real_time *pmtime, uint64_t *epoch,
20effc67 41 std::map<std::string, bufferlist> *attrs, bufferlist *first_chunk,
9f95a23c
TL
42 RGWObjVersionTracker *objv_tracker,
43 optional_yield y) override;
11fdf7f2 44
b3b6e05e
TL
45 int read(const DoutPrefixProvider *dpp,
46 RGWSysObjectCtxBase& obj_ctx,
9f95a23c 47 RGWSI_SysObj_Obj_GetObjState& read_state,
11fdf7f2
TL
48 RGWObjVersionTracker *objv_tracker,
49 const rgw_raw_obj& obj,
50 bufferlist *bl, off_t ofs, off_t end,
20effc67 51 std::map<std::string, bufferlist> *attrs,
11fdf7f2
TL
52 bool raw_attrs,
53 rgw_cache_entry_info *cache_info,
9f95a23c
TL
54 boost::optional<obj_version>,
55 optional_yield y) override;
11fdf7f2 56
b3b6e05e 57 int get_attr(const DoutPrefixProvider *dpp, const rgw_raw_obj& obj, const char *name, bufferlist *dest,
9f95a23c 58 optional_yield y) override;
11fdf7f2 59
b3b6e05e
TL
60 int set_attrs(const DoutPrefixProvider *dpp,
61 const rgw_raw_obj& obj,
20effc67
TL
62 std::map<std::string, bufferlist>& attrs,
63 std::map<std::string, bufferlist> *rmattrs,
9f95a23c
TL
64 RGWObjVersionTracker *objv_tracker,
65 optional_yield y);
11fdf7f2 66
b3b6e05e
TL
67 int remove(const DoutPrefixProvider *dpp,
68 RGWSysObjectCtxBase& obj_ctx,
11fdf7f2 69 RGWObjVersionTracker *objv_tracker,
9f95a23c
TL
70 const rgw_raw_obj& obj,
71 optional_yield y) override;
11fdf7f2 72
b3b6e05e
TL
73 int write(const DoutPrefixProvider *dpp,
74 const rgw_raw_obj& obj,
11fdf7f2 75 real_time *pmtime,
20effc67 76 std::map<std::string, bufferlist>& attrs,
11fdf7f2
TL
77 bool exclusive,
78 const bufferlist& data,
79 RGWObjVersionTracker *objv_tracker,
9f95a23c
TL
80 real_time set_mtime,
81 optional_yield y) override;
11fdf7f2 82
b3b6e05e
TL
83 int write_data(const DoutPrefixProvider *dpp,
84 const rgw_raw_obj& obj,
11fdf7f2
TL
85 const bufferlist& bl,
86 bool exclusive,
9f95a23c
TL
87 RGWObjVersionTracker *objv_tracker,
88 optional_yield y);
11fdf7f2 89
20effc67 90 int distribute_cache(const DoutPrefixProvider *dpp, const std::string& normal_name, const rgw_raw_obj& obj,
9f95a23c
TL
91 ObjectCacheInfo& obj_info, int op,
92 optional_yield y);
11fdf7f2 93
b3b6e05e
TL
94 int watch_cb(const DoutPrefixProvider *dpp,
95 uint64_t notify_id,
11fdf7f2
TL
96 uint64_t cookie,
97 uint64_t notifier_id,
98 bufferlist& bl);
99
100 void set_enabled(bool status);
101
102public:
b3b6e05e 103 RGWSI_SysObj_Cache(const DoutPrefixProvider *dpp, CephContext *cct) : RGWSI_SysObj_Core(cct), asocket(dpp, this) {
11fdf7f2
TL
104 cache.set_ctx(cct);
105 }
106
b3b6e05e
TL
107 bool chain_cache_entry(const DoutPrefixProvider *dpp,
108 std::initializer_list<rgw_cache_entry_info *> cache_info_entries,
11fdf7f2
TL
109 RGWChainedCache::Entry *chained_entry);
110 void register_chained_cache(RGWChainedCache *cc);
111 void unregister_chained_cache(RGWChainedCache *cc);
112
9f95a23c 113 class ASocketHandler {
b3b6e05e 114 const DoutPrefixProvider *dpp;
9f95a23c
TL
115 RGWSI_SysObj_Cache *svc;
116
117 std::unique_ptr<RGWSI_SysObj_Cache_ASocketHook> hook;
118
119 public:
b3b6e05e 120 ASocketHandler(const DoutPrefixProvider *dpp, RGWSI_SysObj_Cache *_svc);
9f95a23c
TL
121 ~ASocketHandler();
122
123 int start();
124 void shutdown();
125
126 // `call_list` must iterate over all cache entries and call
127 // `cache_list_dump_helper` with the supplied Formatter on any that
20effc67 128 // include `filter` as a substd::string.
9f95a23c
TL
129 //
130 void call_list(const std::optional<std::string>& filter, Formatter* f);
131
132 // `call_inspect` must look up the requested target and, if found,
133 // dump it to the supplied Formatter and return true. If not found,
134 // it must return false.
135 //
136 int call_inspect(const std::string& target, Formatter* f);
137
138 // `call_erase` must erase the requested target and return true. If
139 // the requested target does not exist, it should return false.
140 int call_erase(const std::string& target);
141
142 // `call_zap` must erase the cache.
143 int call_zap();
144 } asocket;
11fdf7f2
TL
145};
146
147template <class T>
148class RGWChainedCacheImpl : public RGWChainedCache {
149 RGWSI_SysObj_Cache *svc{nullptr};
150 ceph::timespan expiry;
151 RWLock lock;
152
153 std::unordered_map<std::string, std::pair<T, ceph::coarse_mono_time>> entries;
154
155public:
156 RGWChainedCacheImpl() : lock("RGWChainedCacheImpl::lock") {}
157 ~RGWChainedCacheImpl() {
158 if (!svc) {
159 return;
160 }
161 svc->unregister_chained_cache(this);
162 }
163
164 void unregistered() override {
165 svc = nullptr;
166 }
167
168 void init(RGWSI_SysObj_Cache *_svc) {
169 if (!_svc) {
170 return;
171 }
172 svc = _svc;
173 svc->register_chained_cache(this);
174 expiry = std::chrono::seconds(svc->ctx()->_conf.get_val<uint64_t>(
175 "rgw_cache_expiry_interval"));
176 }
177
20effc67 178 boost::optional<T> find(const std::string& key) {
9f95a23c 179 std::shared_lock rl{lock};
11fdf7f2
TL
180 auto iter = entries.find(key);
181 if (iter == entries.end()) {
182 return boost::none;
183 }
184 if (expiry.count() &&
185 (ceph::coarse_mono_clock::now() - iter->second.second) > expiry) {
186 return boost::none;
187 }
188
189 return iter->second.first;
190 }
191
20effc67 192 bool put(const DoutPrefixProvider *dpp, RGWSI_SysObj_Cache *svc, const std::string& key, T *entry,
11fdf7f2
TL
193 std::initializer_list<rgw_cache_entry_info *> cache_info_entries) {
194 if (!svc) {
195 return false;
196 }
197
198 Entry chain_entry(this, key, entry);
199
200 /* we need the svc cache to call us under its lock to maintain lock ordering */
b3b6e05e 201 return svc->chain_cache_entry(dpp, cache_info_entries, &chain_entry);
11fdf7f2
TL
202 }
203
20effc67 204 void chain_cb(const std::string& key, void *data) override {
11fdf7f2 205 T *entry = static_cast<T *>(data);
9f95a23c 206 std::unique_lock wl{lock};
11fdf7f2
TL
207 entries[key].first = *entry;
208 if (expiry.count() > 0) {
209 entries[key].second = ceph::coarse_mono_clock::now();
210 }
211 }
212
20effc67 213 void invalidate(const std::string& key) override {
9f95a23c 214 std::unique_lock wl{lock};
11fdf7f2
TL
215 entries.erase(key);
216 }
217
218 void invalidate_all() override {
9f95a23c 219 std::unique_lock wl{lock};
11fdf7f2
TL
220 entries.clear();
221 }
222}; /* RGWChainedCacheImpl */