]>
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 | |
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 | ||
12 | class RGWSI_Notify; | |
13 | ||
14 | class RGWSI_SysObj_Cache_CB; | |
9f95a23c | 15 | class RGWSI_SysObj_Cache_ASocketHook; |
11fdf7f2 TL |
16 | |
17 | class 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 |
29 | protected: |
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 | ||
102 | public: | |
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 | ||
147 | template <class T> | |
148 | class 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 | ||
155 | public: | |
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 */ |