]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/services/svc_sys_obj_core.cc
1 #include "svc_sys_obj_core.h"
5 #include "rgw/rgw_tools.h"
7 #define dout_subsys ceph_subsys_rgw
9 int RGWSI_SysObj_Core::GetObjState::get_rados_obj(RGWSI_RADOS
*rados_svc
,
11 const rgw_raw_obj
& obj
,
12 RGWSI_RADOS::Obj
**pobj
)
15 if (obj
.oid
.empty()) {
16 ldout(rados_svc
->ctx(), 0) << "ERROR: obj.oid is empty" << dendl
;
20 rados_obj
= rados_svc
->obj(obj
);
21 int r
= rados_obj
.open();
31 int RGWSI_SysObj_Core::get_rados_obj(RGWSI_Zone
*zone_svc
,
32 const rgw_raw_obj
& obj
,
33 RGWSI_RADOS::Obj
*pobj
)
35 if (obj
.oid
.empty()) {
36 ldout(rados_svc
->ctx(), 0) << "ERROR: obj.oid is empty" << dendl
;
40 *pobj
= std::move(rados_svc
->obj(obj
));
49 int RGWSI_SysObj_Core::get_system_obj_state_impl(RGWSysObjectCtxBase
*rctx
, const rgw_raw_obj
& obj
, RGWSysObjState
**state
, RGWObjVersionTracker
*objv_tracker
)
55 RGWSysObjState
*s
= rctx
->get_state(obj
);
56 ldout(cct
, 20) << "get_system_obj_state: rctx=" << (void *)rctx
<< " obj=" << obj
<< " state=" << (void *)s
<< " s->prefetch_data=" << s
->prefetch_data
<< dendl
;
64 int r
= raw_stat(obj
, &s
->size
, &s
->mtime
, &s
->epoch
, &s
->attrset
, (s
->prefetch_data
? &s
->data
: nullptr), objv_tracker
);
68 s
->mtime
= real_time();
76 s
->obj_tag
= s
->attrset
[RGW_ATTR_ID_TAG
];
78 if (s
->obj_tag
.length())
79 ldout(cct
, 20) << "get_system_obj_state: setting s->obj_tag to "
80 << s
->obj_tag
.c_str() << dendl
;
82 ldout(cct
, 20) << "get_system_obj_state: s->obj_tag was set empty" << dendl
;
87 int RGWSI_SysObj_Core::get_system_obj_state(RGWSysObjectCtxBase
*rctx
, const rgw_raw_obj
& obj
, RGWSysObjState
**state
, RGWObjVersionTracker
*objv_tracker
)
92 ret
= get_system_obj_state_impl(rctx
, obj
, state
, objv_tracker
);
93 } while (ret
== -EAGAIN
);
98 int RGWSI_SysObj_Core::raw_stat(const rgw_raw_obj
& obj
, uint64_t *psize
, real_time
*pmtime
, uint64_t *epoch
,
99 map
<string
, bufferlist
> *attrs
, bufferlist
*first_chunk
,
100 RGWObjVersionTracker
*objv_tracker
)
102 RGWSI_RADOS::Obj rados_obj
;
103 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
109 struct timespec mtime_ts
;
111 librados::ObjectReadOperation op
;
113 objv_tracker
->prepare_op_for_read(&op
);
115 op
.getxattrs(attrs
, nullptr);
116 if (psize
|| pmtime
) {
117 op
.stat2(&size
, &mtime_ts
, nullptr);
120 op
.read(0, cct
->_conf
->rgw_max_chunk_size
, first_chunk
, nullptr);
123 r
= rados_obj
.operate(&op
, &outbl
, null_yield
);
126 *epoch
= rados_obj
.get_last_version();
135 *pmtime
= ceph::real_clock::from_timespec(mtime_ts
);
140 int RGWSI_SysObj_Core::stat(RGWSysObjectCtxBase
& obj_ctx
,
142 const rgw_raw_obj
& obj
,
143 map
<string
, bufferlist
> *attrs
,
147 RGWObjVersionTracker
*objv_tracker
)
149 RGWSysObjState
*astate
= nullptr;
151 int r
= get_system_obj_state(&obj_ctx
, obj
, &astate
, objv_tracker
);
155 if (!astate
->exists
) {
161 *attrs
= astate
->attrset
;
163 rgw_filter_attrset(astate
->attrset
, RGW_ATTR_PREFIX
, attrs
);
165 if (cct
->_conf
->subsys
.should_gather
<ceph_subsys_rgw
, 20>()) {
166 map
<string
, bufferlist
>::iterator iter
;
167 for (iter
= attrs
->begin(); iter
!= attrs
->end(); ++iter
) {
168 ldout(cct
, 20) << "Read xattr: " << iter
->first
<< dendl
;
174 *obj_size
= astate
->size
;
176 *lastmod
= astate
->mtime
;
181 int RGWSI_SysObj_Core::read(RGWSysObjectCtxBase
& obj_ctx
,
182 GetObjState
& read_state
,
183 RGWObjVersionTracker
*objv_tracker
,
184 const rgw_raw_obj
& obj
,
185 bufferlist
*bl
, off_t ofs
, off_t end
,
186 map
<string
, bufferlist
> *attrs
,
188 rgw_cache_entry_info
*cache_info
,
189 boost::optional
<obj_version
>)
192 librados::ObjectReadOperation op
;
200 objv_tracker
->prepare_op_for_read(&op
);
203 ldout(cct
, 20) << "rados->read ofs=" << ofs
<< " len=" << len
<< dendl
;
204 op
.read(ofs
, len
, bl
, nullptr);
206 map
<string
, bufferlist
> unfiltered_attrset
;
210 op
.getxattrs(attrs
, nullptr);
212 op
.getxattrs(&unfiltered_attrset
, nullptr);
216 RGWSI_RADOS::Obj rados_obj
;
217 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
219 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
222 r
= rados_obj
.operate(&op
, nullptr, null_yield
);
224 ldout(cct
, 20) << "rados_obj.operate() r=" << r
<< " bl.length=" << bl
->length() << dendl
;
227 ldout(cct
, 20) << "rados_obj.operate() r=" << r
<< " bl.length=" << bl
->length() << dendl
;
229 uint64_t op_ver
= rados_obj
.get_last_version();
231 if (read_state
.last_ver
> 0 &&
232 read_state
.last_ver
!= op_ver
) {
233 ldout(cct
, 5) << "raced with an object write, abort" << dendl
;
237 if (attrs
&& !raw_attrs
) {
238 rgw_filter_attrset(unfiltered_attrset
, RGW_ATTR_PREFIX
, attrs
);
241 read_state
.last_ver
= op_ver
;
247 * Get an attribute for a system object.
248 * obj: the object to get attr
249 * name: name of the attr to retrieve
250 * dest: bufferlist to store the result in
251 * Returns: 0 on success, -ERR# otherwise.
253 int RGWSI_SysObj_Core::get_attr(const rgw_raw_obj
& obj
,
257 RGWSI_RADOS::Obj rados_obj
;
258 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
260 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
264 librados::ObjectReadOperation op
;
267 op
.getxattr(name
, dest
, &rval
);
269 r
= rados_obj
.operate(&op
, nullptr, null_yield
);
276 int RGWSI_SysObj_Core::set_attrs(const rgw_raw_obj
& obj
,
277 map
<string
, bufferlist
>& attrs
,
278 map
<string
, bufferlist
> *rmattrs
,
279 RGWObjVersionTracker
*objv_tracker
)
281 RGWSI_RADOS::Obj rados_obj
;
282 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
284 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
288 librados::ObjectWriteOperation op
;
291 objv_tracker
->prepare_op_for_write(&op
);
294 map
<string
, bufferlist
>::iterator iter
;
296 for (iter
= rmattrs
->begin(); iter
!= rmattrs
->end(); ++iter
) {
297 const string
& name
= iter
->first
;
298 op
.rmxattr(name
.c_str());
302 for (iter
= attrs
.begin(); iter
!= attrs
.end(); ++iter
) {
303 const string
& name
= iter
->first
;
304 bufferlist
& bl
= iter
->second
;
309 op
.setxattr(name
.c_str(), bl
);
317 r
= rados_obj
.operate(&op
, null_yield
);
324 int RGWSI_SysObj_Core::omap_get_vals(const rgw_raw_obj
& obj
,
325 const string
& marker
,
327 std::map
<string
, bufferlist
> *m
,
330 RGWSI_RADOS::Obj rados_obj
;
331 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
333 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
337 string start_after
= marker
;
341 librados::ObjectReadOperation op
;
343 std::map
<string
, bufferlist
> t
;
345 op
.omap_get_vals2(start_after
, count
, &t
, &more
, &rval
);
347 r
= rados_obj
.operate(&op
, nullptr, null_yield
);
355 start_after
= t
.rbegin()->first
;
356 m
->insert(t
.begin(), t
.end());
357 } while (more
&& count
> 0);
365 int RGWSI_SysObj_Core::omap_get_all(const rgw_raw_obj
& obj
, std::map
<string
, bufferlist
> *m
)
367 RGWSI_RADOS::Obj rados_obj
;
368 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
370 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
374 #define MAX_OMAP_GET_ENTRIES 1024
375 const int count
= MAX_OMAP_GET_ENTRIES
;
380 librados::ObjectReadOperation op
;
382 std::map
<string
, bufferlist
> t
;
384 op
.omap_get_vals2(start_after
, count
, &t
, &more
, &rval
);
386 r
= rados_obj
.operate(&op
, nullptr, null_yield
);
393 start_after
= t
.rbegin()->first
;
394 m
->insert(t
.begin(), t
.end());
399 int RGWSI_SysObj_Core::omap_set(const rgw_raw_obj
& obj
, const std::string
& key
, bufferlist
& bl
, bool must_exist
)
401 RGWSI_RADOS::Obj rados_obj
;
402 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
404 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
408 ldout(cct
, 15) << "omap_set obj=" << obj
<< " key=" << key
<< dendl
;
410 map
<string
, bufferlist
> m
;
412 librados::ObjectWriteOperation op
;
416 r
= rados_obj
.operate(&op
, null_yield
);
420 int RGWSI_SysObj_Core::omap_set(const rgw_raw_obj
& obj
, const std::map
<std::string
, bufferlist
>& m
, bool must_exist
)
422 RGWSI_RADOS::Obj rados_obj
;
423 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
425 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
429 librados::ObjectWriteOperation op
;
433 r
= rados_obj
.operate(&op
, null_yield
);
437 int RGWSI_SysObj_Core::omap_del(const rgw_raw_obj
& obj
, const std::string
& key
)
439 RGWSI_RADOS::Obj rados_obj
;
440 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
442 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
449 librados::ObjectWriteOperation op
;
453 r
= rados_obj
.operate(&op
, null_yield
);
457 int RGWSI_SysObj_Core::notify(const rgw_raw_obj
& obj
,
462 RGWSI_RADOS::Obj rados_obj
;
463 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
465 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
469 r
= rados_obj
.notify(bl
, timeout_ms
, pbl
);
473 int RGWSI_SysObj_Core::remove(RGWSysObjectCtxBase
& obj_ctx
,
474 RGWObjVersionTracker
*objv_tracker
,
475 const rgw_raw_obj
& obj
)
477 RGWSI_RADOS::Obj rados_obj
;
478 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
480 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
484 librados::ObjectWriteOperation op
;
487 objv_tracker
->prepare_op_for_write(&op
);
491 r
= rados_obj
.operate(&op
, null_yield
);
498 int RGWSI_SysObj_Core::write(const rgw_raw_obj
& obj
,
500 map
<std::string
, bufferlist
>& attrs
,
502 const bufferlist
& data
,
503 RGWObjVersionTracker
*objv_tracker
,
506 RGWSI_RADOS::Obj rados_obj
;
507 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
509 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
513 librados::ObjectWriteOperation op
;
516 op
.create(true); // exclusive create
519 op
.set_op_flags2(LIBRADOS_OP_FLAG_FAILOK
);
524 objv_tracker
->prepare_op_for_write(&op
);
527 if (real_clock::is_zero(set_mtime
)) {
528 set_mtime
= real_clock::now();
531 struct timespec mtime_ts
= real_clock::to_timespec(set_mtime
);
532 op
.mtime2(&mtime_ts
);
537 for (map
<string
, bufferlist
>::iterator iter
= attrs
.begin(); iter
!= attrs
.end(); ++iter
) {
538 const string
& name
= iter
->first
;
539 bufferlist
& bl
= iter
->second
;
544 op
.setxattr(name
.c_str(), bl
);
547 r
= rados_obj
.operate(&op
, null_yield
);
553 objv_tracker
->apply_write();
564 int RGWSI_SysObj_Core::write_data(const rgw_raw_obj
& obj
,
565 const bufferlist
& bl
,
567 RGWObjVersionTracker
*objv_tracker
)
569 RGWSI_RADOS::Obj rados_obj
;
570 int r
= get_rados_obj(zone_svc
, obj
, &rados_obj
);
572 ldout(cct
, 20) << "get_rados_obj() on obj=" << obj
<< " returned " << r
<< dendl
;
576 librados::ObjectWriteOperation op
;
583 objv_tracker
->prepare_op_for_write(&op
);
586 r
= rados_obj
.operate(&op
, null_yield
);
591 objv_tracker
->apply_write();