]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_cache.h
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / rgw / rgw_cache.h
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 #pragma once
5
6 #include <string>
7 #include <map>
8 #include <unordered_map>
9 #include "include/types.h"
10 #include "include/utime.h"
11 #include "include/ceph_assert.h"
12 #include "common/ceph_mutex.h"
13
14 #include "cls/version/cls_version_types.h"
15 #include "rgw_common.h"
16
17 enum {
18 UPDATE_OBJ,
19 INVALIDATE_OBJ,
20 };
21
22 #define CACHE_FLAG_DATA 0x01
23 #define CACHE_FLAG_XATTRS 0x02
24 #define CACHE_FLAG_META 0x04
25 #define CACHE_FLAG_MODIFY_XATTRS 0x08
26 #define CACHE_FLAG_OBJV 0x10
27
28 struct ObjectMetaInfo {
29 uint64_t size;
30 real_time mtime;
31
32 ObjectMetaInfo() : size(0) {}
33
34 void encode(bufferlist& bl) const {
35 ENCODE_START(2, 2, bl);
36 encode(size, bl);
37 encode(mtime, bl);
38 ENCODE_FINISH(bl);
39 }
40 void decode(bufferlist::const_iterator& bl) {
41 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl);
42 decode(size, bl);
43 decode(mtime, bl);
44 DECODE_FINISH(bl);
45 }
46 void dump(Formatter *f) const;
47 static void generate_test_instances(std::list<ObjectMetaInfo*>& o);
48 };
49 WRITE_CLASS_ENCODER(ObjectMetaInfo)
50
51 struct ObjectCacheInfo {
52 int status = 0;
53 uint32_t flags = 0;
54 uint64_t epoch = 0;
55 bufferlist data;
56 std::map<std::string, bufferlist> xattrs;
57 std::map<std::string, bufferlist> rm_xattrs;
58 ObjectMetaInfo meta;
59 obj_version version = {};
60 ceph::coarse_mono_time time_added;
61
62 ObjectCacheInfo() = default;
63
64 void encode(bufferlist& bl) const {
65 ENCODE_START(5, 3, bl);
66 encode(status, bl);
67 encode(flags, bl);
68 encode(data, bl);
69 encode(xattrs, bl);
70 encode(meta, bl);
71 encode(rm_xattrs, bl);
72 encode(epoch, bl);
73 encode(version, bl);
74 ENCODE_FINISH(bl);
75 }
76 void decode(bufferlist::const_iterator& bl) {
77 DECODE_START_LEGACY_COMPAT_LEN(5, 3, 3, bl);
78 decode(status, bl);
79 decode(flags, bl);
80 decode(data, bl);
81 decode(xattrs, bl);
82 decode(meta, bl);
83 if (struct_v >= 2)
84 decode(rm_xattrs, bl);
85 if (struct_v >= 4)
86 decode(epoch, bl);
87 if (struct_v >= 5)
88 decode(version, bl);
89 DECODE_FINISH(bl);
90 }
91 void dump(Formatter *f) const;
92 static void generate_test_instances(std::list<ObjectCacheInfo*>& o);
93 };
94 WRITE_CLASS_ENCODER(ObjectCacheInfo)
95
96 struct RGWCacheNotifyInfo {
97 uint32_t op;
98 rgw_raw_obj obj;
99 ObjectCacheInfo obj_info;
100 off_t ofs;
101 std::string ns;
102
103 RGWCacheNotifyInfo() : op(0), ofs(0) {}
104
105 void encode(bufferlist& obl) const {
106 ENCODE_START(2, 2, obl);
107 encode(op, obl);
108 encode(obj, obl);
109 encode(obj_info, obl);
110 encode(ofs, obl);
111 encode(ns, obl);
112 ENCODE_FINISH(obl);
113 }
114 void decode(bufferlist::const_iterator& ibl) {
115 DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, ibl);
116 decode(op, ibl);
117 decode(obj, ibl);
118 decode(obj_info, ibl);
119 decode(ofs, ibl);
120 decode(ns, ibl);
121 DECODE_FINISH(ibl);
122 }
123 void dump(Formatter *f) const;
124 static void generate_test_instances(std::list<RGWCacheNotifyInfo*>& o);
125 };
126 WRITE_CLASS_ENCODER(RGWCacheNotifyInfo)
127 inline std::ostream& operator <<(std::ostream& m, const RGWCacheNotifyInfo& cni) {
128 return m << "[op: " << cni.op << ", obj: " << cni.obj
129 << ", ofs" << cni.ofs << ", ns" << cni.ns << "]";
130 }
131
132
133 class RGWChainedCache {
134 public:
135 virtual ~RGWChainedCache() {}
136 virtual void chain_cb(const std::string& key, void *data) = 0;
137 virtual void invalidate(const std::string& key) = 0;
138 virtual void invalidate_all() = 0;
139 virtual void unregistered() {}
140
141 struct Entry {
142 RGWChainedCache *cache;
143 const std::string& key;
144 void *data;
145
146 Entry(RGWChainedCache *_c, const std::string& _k, void *_d) : cache(_c), key(_k), data(_d) {}
147 };
148 };
149
150
151 struct ObjectCacheEntry {
152 ObjectCacheInfo info;
153 std::list<std::string>::iterator lru_iter;
154 uint64_t lru_promotion_ts;
155 uint64_t gen;
156 std::vector<std::pair<RGWChainedCache *, std::string> > chained_entries;
157
158 ObjectCacheEntry() : lru_promotion_ts(0), gen(0) {}
159 };
160
161 class ObjectCache {
162 std::unordered_map<std::string, ObjectCacheEntry> cache_map;
163 std::list<std::string> lru;
164 unsigned long lru_size;
165 unsigned long lru_counter;
166 unsigned long lru_window;
167 ceph::shared_mutex lock = ceph::make_shared_mutex("ObjectCache");
168 CephContext *cct;
169
170 std::vector<RGWChainedCache *> chained_cache;
171
172 bool enabled;
173 ceph::timespan expiry;
174
175 void touch_lru(const DoutPrefixProvider *dpp, const std::string& name, ObjectCacheEntry& entry,
176 std::list<std::string>::iterator& lru_iter);
177 void remove_lru(const std::string& name, std::list<std::string>::iterator& lru_iter);
178 void invalidate_lru(ObjectCacheEntry& entry);
179
180 void do_invalidate_all();
181
182 public:
183 ObjectCache() : lru_size(0), lru_counter(0), lru_window(0), cct(NULL), enabled(false) { }
184 ~ObjectCache();
185 int get(const DoutPrefixProvider *dpp, const std::string& name, ObjectCacheInfo& bl, uint32_t mask, rgw_cache_entry_info *cache_info);
186 std::optional<ObjectCacheInfo> get(const DoutPrefixProvider *dpp, const std::string& name) {
187 std::optional<ObjectCacheInfo> info{std::in_place};
188 auto r = get(dpp, name, *info, 0, nullptr);
189 return r < 0 ? std::nullopt : info;
190 }
191
192 template<typename F>
193 void for_each(const F& f) {
194 std::shared_lock l{lock};
195 if (enabled) {
196 auto now = ceph::coarse_mono_clock::now();
197 for (const auto& [name, entry] : cache_map) {
198 if (expiry.count() && (now - entry.info.time_added) < expiry) {
199 f(name, entry);
200 }
201 }
202 }
203 }
204
205 void put(const DoutPrefixProvider *dpp, const std::string& name, ObjectCacheInfo& bl, rgw_cache_entry_info *cache_info);
206 bool invalidate_remove(const DoutPrefixProvider *dpp, const std::string& name);
207 void set_ctx(CephContext *_cct) {
208 cct = _cct;
209 lru_window = cct->_conf->rgw_cache_lru_size / 2;
210 expiry = std::chrono::seconds(cct->_conf.get_val<uint64_t>(
211 "rgw_cache_expiry_interval"));
212 }
213 bool chain_cache_entry(const DoutPrefixProvider *dpp,
214 std::initializer_list<rgw_cache_entry_info*> cache_info_entries,
215 RGWChainedCache::Entry *chained_entry);
216
217 void set_enabled(bool status);
218
219 void chain_cache(RGWChainedCache *cache);
220 void unchain_cache(RGWChainedCache *cache);
221 void invalidate_all();
222 };