]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/services/svc_sys_obj_cache.cc
1 #include "svc_sys_obj_cache.h"
3 #include "svc_notify.h"
5 #include "rgw/rgw_zone.h"
6 #include "rgw/rgw_tools.h"
8 #define dout_subsys ceph_subsys_rgw
10 class RGWSI_SysObj_Cache_CB
: public RGWSI_Notify::CB
12 RGWSI_SysObj_Cache
*svc
;
14 RGWSI_SysObj_Cache_CB(RGWSI_SysObj_Cache
*_svc
) : svc(_svc
) {}
15 int watch_cb(uint64_t notify_id
,
19 return svc
->watch_cb(notify_id
, cookie
, notifier_id
, bl
);
22 void set_enabled(bool status
) {
23 svc
->set_enabled(status
);
27 int RGWSI_SysObj_Cache::do_start()
29 int r
= RGWSI_SysObj_Core::do_start();
34 r
= notify_svc
->start();
39 assert(notify_svc
->is_started());
41 cb
.reset(new RGWSI_SysObj_Cache_CB(this));
43 notify_svc
->register_watch_cb(cb
.get());
48 static string
normal_name(rgw_pool
& pool
, const std::string
& oid
) {
50 buf
.reserve(pool
.name
.size() + pool
.ns
.size() + oid
.size() + 2);
51 buf
.append(pool
.name
).append("+").append(pool
.ns
).append("+").append(oid
);
55 void RGWSI_SysObj_Cache::normalize_pool_and_obj(const rgw_pool
& src_pool
, const string
& src_obj
, rgw_pool
& dst_pool
, string
& dst_obj
)
61 dst_pool
= zone_svc
->get_zone_params().domain_root
;
62 dst_obj
= src_pool
.name
;
67 int RGWSI_SysObj_Cache::remove(RGWSysObjectCtxBase
& obj_ctx
,
68 RGWObjVersionTracker
*objv_tracker
,
69 const rgw_raw_obj
& obj
)
74 normalize_pool_and_obj(obj
.pool
, obj
.oid
, pool
, oid
);
76 string name
= normal_name(pool
, oid
);
80 int r
= distribute_cache(name
, obj
, info
, REMOVE_OBJ
);
82 ldout(cct
, 0) << "ERROR: " << __func__
<< "(): failed to distribute cache: r=" << r
<< dendl
;
85 return RGWSI_SysObj_Core::remove(obj_ctx
, objv_tracker
, obj
);
88 int RGWSI_SysObj_Cache::read(RGWSysObjectCtxBase
& obj_ctx
,
89 GetObjState
& read_state
,
90 RGWObjVersionTracker
*objv_tracker
,
91 const rgw_raw_obj
& obj
,
92 bufferlist
*obl
, off_t ofs
, off_t end
,
93 map
<string
, bufferlist
> *attrs
,
95 rgw_cache_entry_info
*cache_info
,
96 boost::optional
<obj_version
> refresh_version
)
101 return RGWSI_SysObj_Core::read(obj_ctx
, read_state
, objv_tracker
,
102 obj
, obl
, ofs
, end
, attrs
, raw_attrs
,
103 cache_info
, refresh_version
);
106 normalize_pool_and_obj(obj
.pool
, obj
.oid
, pool
, oid
);
107 string name
= normal_name(pool
, oid
);
109 ObjectCacheInfo info
;
111 uint32_t flags
= (end
!= 0 ? CACHE_FLAG_DATA
: 0);
113 flags
|= CACHE_FLAG_OBJV
;
115 flags
|= CACHE_FLAG_XATTRS
;
117 if ((cache
.get(name
, info
, flags
, cache_info
) == 0) &&
118 (!refresh_version
|| !info
.version
.compare(&(*refresh_version
)))) {
122 bufferlist
& bl
= info
.data
;
124 bufferlist::iterator i
= bl
.begin();
130 objv_tracker
->read_version
= info
.version
;
133 *attrs
= info
.xattrs
;
135 rgw_filter_attrset(info
.xattrs
, RGW_ATTR_PREFIX
, attrs
);
138 return obl
->length();
141 map
<string
, bufferlist
> unfiltered_attrset
;
142 int r
= RGWSI_SysObj_Core::read(obj_ctx
, read_state
, objv_tracker
,
144 (attrs
? &unfiltered_attrset
: nullptr),
145 true, /* cache unfiltered attrs */
149 if (r
== -ENOENT
) { // only update ENOENT, we'd rather retry other errors
151 cache
.put(name
, info
, cache_info
);
156 if (obl
->length() == end
+ 1) {
157 /* in this case, most likely object contains more data, we can't cache it */
158 flags
&= ~CACHE_FLAG_DATA
;
161 bufferlist
& bl
= info
.data
;
163 bufferlist::iterator o
= obl
->begin();
170 info
.version
= objv_tracker
->read_version
;
173 info
.xattrs
= std::move(unfiltered_attrset
);
175 *attrs
= info
.xattrs
;
177 rgw_filter_attrset(info
.xattrs
, RGW_ATTR_PREFIX
, attrs
);
180 cache
.put(name
, info
, cache_info
);
184 int RGWSI_SysObj_Cache::get_attr(const rgw_raw_obj
& obj
,
185 const char *attr_name
,
191 normalize_pool_and_obj(obj
.pool
, obj
.oid
, pool
, oid
);
192 string name
= normal_name(pool
, oid
);
194 ObjectCacheInfo info
;
196 uint32_t flags
= CACHE_FLAG_XATTRS
;
198 if (cache
.get(name
, info
, flags
, nullptr) == 0) {
202 auto iter
= info
.xattrs
.find(attr_name
);
203 if (iter
== info
.xattrs
.end()) {
207 *dest
= iter
->second
;
208 return dest
->length();
210 /* don't try to cache this one */
211 return RGWSI_SysObj_Core::get_attr(obj
, attr_name
, dest
);
214 int RGWSI_SysObj_Cache::set_attrs(const rgw_raw_obj
& obj
,
215 map
<string
, bufferlist
>& attrs
,
216 map
<string
, bufferlist
> *rmattrs
,
217 RGWObjVersionTracker
*objv_tracker
)
221 normalize_pool_and_obj(obj
.pool
, obj
.oid
, pool
, oid
);
222 ObjectCacheInfo info
;
225 info
.rm_xattrs
= *rmattrs
;
228 info
.flags
= CACHE_FLAG_MODIFY_XATTRS
;
230 info
.version
= objv_tracker
->write_version
;
231 info
.flags
|= CACHE_FLAG_OBJV
;
233 int ret
= RGWSI_SysObj_Core::set_attrs(obj
, attrs
, rmattrs
, objv_tracker
);
234 string name
= normal_name(pool
, oid
);
236 cache
.put(name
, info
, NULL
);
237 int r
= distribute_cache(name
, obj
, info
, UPDATE_OBJ
);
239 ldout(cct
, 0) << "ERROR: failed to distribute cache for " << obj
<< dendl
;
247 int RGWSI_SysObj_Cache::write(const rgw_raw_obj
& obj
,
249 map
<std::string
, bufferlist
>& attrs
,
251 const bufferlist
& data
,
252 RGWObjVersionTracker
*objv_tracker
,
257 normalize_pool_and_obj(obj
.pool
, obj
.oid
, pool
, oid
);
258 ObjectCacheInfo info
;
262 info
.flags
= CACHE_FLAG_XATTRS
| CACHE_FLAG_DATA
| CACHE_FLAG_META
;
264 info
.version
= objv_tracker
->write_version
;
265 info
.flags
|= CACHE_FLAG_OBJV
;
267 ceph::real_time result_mtime
;
268 int ret
= RGWSI_SysObj_Core::write(obj
, &result_mtime
, attrs
,
270 objv_tracker
, set_mtime
);
272 *pmtime
= result_mtime
;
274 info
.meta
.mtime
= result_mtime
;
275 info
.meta
.size
= data
.length();
276 string name
= normal_name(pool
, oid
);
278 cache
.put(name
, info
, NULL
);
279 // Only distribute the cache information if we did not just create
280 // the object with the exclusive flag. Note: PUT_OBJ_EXCL implies
281 // PUT_OBJ_CREATE. Generally speaking, when successfully creating
282 // a system object with the exclusive flag it is not necessary to
283 // call distribute_cache, as a) it's unclear whether other RGWs
284 // will need that system object in the near-term and b) it
285 // generates additional network traffic.
287 int r
= distribute_cache(name
, obj
, info
, UPDATE_OBJ
);
289 ldout(cct
, 0) << "ERROR: failed to distribute cache for " << obj
<< dendl
;
298 int RGWSI_SysObj_Cache::write_data(const rgw_raw_obj
& obj
,
299 const bufferlist
& data
,
301 RGWObjVersionTracker
*objv_tracker
)
305 normalize_pool_and_obj(obj
.pool
, obj
.oid
, pool
, oid
);
307 ObjectCacheInfo info
;
309 info
.meta
.size
= data
.length();
311 info
.flags
= CACHE_FLAG_DATA
;
314 info
.version
= objv_tracker
->write_version
;
315 info
.flags
|= CACHE_FLAG_OBJV
;
317 int ret
= RGWSI_SysObj_Core::write_data(obj
, data
, exclusive
, objv_tracker
);
318 string name
= normal_name(pool
, oid
);
320 cache
.put(name
, info
, NULL
);
321 int r
= distribute_cache(name
, obj
, info
, UPDATE_OBJ
);
323 ldout(cct
, 0) << "ERROR: failed to distribute cache for " << obj
<< dendl
;
331 int RGWSI_SysObj_Cache::raw_stat(const rgw_raw_obj
& obj
, uint64_t *psize
, real_time
*pmtime
, uint64_t *pepoch
,
332 map
<string
, bufferlist
> *attrs
, bufferlist
*first_chunk
,
333 RGWObjVersionTracker
*objv_tracker
)
337 normalize_pool_and_obj(obj
.pool
, obj
.oid
, pool
, oid
);
339 string name
= normal_name(pool
, oid
);
345 ObjectCacheInfo info
;
346 uint32_t flags
= CACHE_FLAG_META
| CACHE_FLAG_XATTRS
;
348 flags
|= CACHE_FLAG_OBJV
;
349 int r
= cache
.get(name
, info
, flags
, NULL
);
354 size
= info
.meta
.size
;
355 mtime
= info
.meta
.mtime
;
358 objv_tracker
->read_version
= info
.version
;
361 r
= RGWSI_SysObj_Core::raw_stat(obj
, &size
, &mtime
, &epoch
, &info
.xattrs
, first_chunk
, objv_tracker
);
365 cache
.put(name
, info
, NULL
);
371 info
.meta
.mtime
= mtime
;
372 info
.meta
.size
= size
;
373 info
.flags
= CACHE_FLAG_META
| CACHE_FLAG_XATTRS
;
375 info
.flags
|= CACHE_FLAG_OBJV
;
376 info
.version
= objv_tracker
->read_version
;
378 cache
.put(name
, info
, NULL
);
387 *attrs
= info
.xattrs
;
391 int RGWSI_SysObj_Cache::distribute_cache(const string
& normal_name
, const rgw_raw_obj
& obj
, ObjectCacheInfo
& obj_info
, int op
)
393 RGWCacheNotifyInfo info
;
397 info
.obj_info
= obj_info
;
401 return notify_svc
->distribute(normal_name
, bl
);
404 int RGWSI_SysObj_Cache::watch_cb(uint64_t notify_id
,
406 uint64_t notifier_id
,
409 RGWCacheNotifyInfo info
;
412 auto iter
= bl
.cbegin();
414 } catch (buffer::end_of_buffer
& err
) {
415 ldout(cct
, 0) << "ERROR: got bad notification" << dendl
;
417 } catch (buffer::error
& err
) {
418 ldout(cct
, 0) << "ERROR: buffer::error" << dendl
;
424 normalize_pool_and_obj(info
.obj
.pool
, info
.obj
.oid
, pool
, oid
);
425 string name
= normal_name(pool
, oid
);
429 cache
.put(name
, info
.obj_info
, NULL
);
435 ldout(cct
, 0) << "WARNING: got unknown notification op: " << info
.op
<< dendl
;
442 void RGWSI_SysObj_Cache::set_enabled(bool status
)
444 cache
.set_enabled(status
);
447 bool RGWSI_SysObj_Cache::chain_cache_entry(std::initializer_list
<rgw_cache_entry_info
*> cache_info_entries
,
448 RGWChainedCache::Entry
*chained_entry
)
450 return cache
.chain_cache_entry(cache_info_entries
, chained_entry
);
453 void RGWSI_SysObj_Cache::register_chained_cache(RGWChainedCache
*cc
)
455 cache
.chain_cache(cc
);
458 void RGWSI_SysObj_Cache::unregister_chained_cache(RGWChainedCache
*cc
)
460 cache
.unchain_cache(cc
);
463 static void cache_list_dump_helper(Formatter
* f
,
464 const std::string
& name
,
465 const ceph::real_time mtime
,
466 const std::uint64_t size
)
468 f
->dump_string("name", name
);
469 f
->dump_string("mtime", ceph::to_iso_8601(mtime
));
470 f
->dump_unsigned("size", size
);
473 void RGWSI_SysObj_Cache::call_list(const std::optional
<std::string
>& filter
, Formatter
* f
)
476 [this, &filter
, f
] (const string
& name
, const ObjectCacheEntry
& entry
) {
477 if (!filter
|| name
.find(*filter
) != name
.npos
) {
478 cache_list_dump_helper(f
, name
, entry
.info
.meta
.mtime
,
479 entry
.info
.meta
.size
);
484 int RGWSI_SysObj_Cache::call_inspect(const std::string
& target
, Formatter
* f
)
486 if (const auto entry
= cache
.get(target
)) {
487 f
->open_object_section("cache_entry");
488 f
->dump_string("name", target
.c_str());
497 int RGWSI_SysObj_Cache::call_erase(const std::string
& target
)
499 return cache
.remove(target
);
502 int RGWSI_SysObj_Cache::call_zap()
504 cache
.invalidate_all();