1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
#ifndef CEPH_RGW_SERVICES_SYS_OBJ_CORE_H
#define CEPH_RGW_SERVICES_SYS_OBJ_CORE_H
#include "rgw/rgw_service.h"
#include "svc_rados.h"
class RGWSI_Zone;
struct rgw_cache_entry_info;
struct RGWSysObjState {
rgw_raw_obj obj;
bool has_attrs{false};
bool exists{false};
uint64_t size{0};
ceph::real_time mtime;
uint64_t epoch{0};
bufferlist obj_tag;
bool has_data{false};
bufferlist data;
bool prefetch_data{false};
uint64_t pg_ver{0};
/* important! don't forget to update copy constructor */
RGWObjVersionTracker objv_tracker;
map<string, bufferlist> attrset;
RGWSysObjState() {}
RGWSysObjState(const RGWSysObjState& rhs) : obj (rhs.obj) {
has_attrs = rhs.has_attrs;
exists = rhs.exists;
size = rhs.size;
mtime = rhs.mtime;
epoch = rhs.epoch;
if (rhs.obj_tag.length()) {
obj_tag = rhs.obj_tag;
}
has_data = rhs.has_data;
if (rhs.data.length()) {
data = rhs.data;
}
prefetch_data = rhs.prefetch_data;
pg_ver = rhs.pg_ver;
objv_tracker = rhs.objv_tracker;
}
};
class RGWSysObjectCtxBase {
std::map<rgw_raw_obj, RGWSysObjState> objs_state;
RWLock lock;
public:
explicit RGWSysObjectCtxBase() : lock("RGWSysObjectCtxBase") {}
RGWSysObjectCtxBase(const RGWSysObjectCtxBase& rhs) : objs_state(rhs.objs_state),
lock("RGWSysObjectCtxBase") {}
RGWSysObjectCtxBase(const RGWSysObjectCtxBase&& rhs) : objs_state(std::move(rhs.objs_state)),
lock("RGWSysObjectCtxBase") {}
RGWSysObjState *get_state(const rgw_raw_obj& obj) {
RGWSysObjState *result;
std::map<rgw_raw_obj, RGWSysObjState>::iterator iter;
lock.get_read();
assert (!obj.empty());
iter = objs_state.find(obj);
if (iter != objs_state.end()) {
result = &iter->second;
lock.unlock();
} else {
lock.unlock();
lock.get_write();
result = &objs_state[obj];
lock.unlock();
}
return result;
}
void set_prefetch_data(rgw_raw_obj& obj) {
RWLock::WLocker wl(lock);
assert (!obj.empty());
objs_state[obj].prefetch_data = true;
}
void invalidate(rgw_raw_obj& obj) {
RWLock::WLocker wl(lock);
auto iter = objs_state.find(obj);
if (iter == objs_state.end()) {
return;
}
objs_state.erase(iter);
}
};
class RGWSI_SysObj_Core : public RGWServiceInstance
{
friend class RGWServices_Def;
friend class RGWSI_SysObj;
protected:
RGWSI_RADOS *rados_svc{nullptr};
RGWSI_Zone *zone_svc{nullptr};
struct GetObjState {
RGWSI_RADOS::Obj rados_obj;
bool has_rados_obj{false};
uint64_t last_ver{0};
GetObjState() {}
int get_rados_obj(RGWSI_RADOS *rados_svc,
RGWSI_Zone *zone_svc,
const rgw_raw_obj& obj,
RGWSI_RADOS::Obj **pobj);
};
void core_init(RGWSI_RADOS *_rados_svc,
RGWSI_Zone *_zone_svc) {
rados_svc = _rados_svc;
zone_svc = _zone_svc;
}
int get_rados_obj(RGWSI_Zone *zone_svc, const rgw_raw_obj& obj, RGWSI_RADOS::Obj *pobj);
virtual int raw_stat(const rgw_raw_obj& obj, uint64_t *psize, real_time *pmtime, uint64_t *epoch,
map<string, bufferlist> *attrs, bufferlist *first_chunk,
RGWObjVersionTracker *objv_tracker);
virtual int read(RGWSysObjectCtxBase& obj_ctx,
GetObjState& read_state,
RGWObjVersionTracker *objv_tracker,
const rgw_raw_obj& obj,
bufferlist *bl, off_t ofs, off_t end,
map<string, bufferlist> *attrs,
bool raw_attrs,
rgw_cache_entry_info *cache_info,
boost::optional<obj_version>);
virtual int remove(RGWSysObjectCtxBase& obj_ctx,
RGWObjVersionTracker *objv_tracker,
const rgw_raw_obj& obj);
virtual int write(const rgw_raw_obj& obj,
real_time *pmtime,
map<std::string, bufferlist>& attrs,
bool exclusive,
const bufferlist& data,
RGWObjVersionTracker *objv_tracker,
real_time set_mtime);
virtual int write_data(const rgw_raw_obj& obj,
const bufferlist& bl,
bool exclusive,
RGWObjVersionTracker *objv_tracker);
virtual int get_attr(const rgw_raw_obj& obj, const char *name, bufferlist *dest);
virtual int set_attrs(const rgw_raw_obj& obj,
map<string, bufferlist>& attrs,
map<string, bufferlist> *rmattrs,
RGWObjVersionTracker *objv_tracker);
virtual int omap_get_all(const rgw_raw_obj& obj, std::map<string, bufferlist> *m);
virtual int omap_get_vals(const rgw_raw_obj& obj,
const string& marker,
uint64_t count,
std::map<string, bufferlist> *m,
bool *pmore);
virtual int omap_set(const rgw_raw_obj& obj, const std::string& key, bufferlist& bl, bool must_exist = false);
virtual int omap_set(const rgw_raw_obj& obj, const map<std::string, bufferlist>& m, bool must_exist = false);
virtual int omap_del(const rgw_raw_obj& obj, const std::string& key);
virtual int notify(const rgw_raw_obj& obj,
bufferlist& bl,
uint64_t timeout_ms,
bufferlist *pbl);
/* wrappers */
int get_system_obj_state_impl(RGWSysObjectCtxBase *rctx, const rgw_raw_obj& obj, RGWSysObjState **state, RGWObjVersionTracker *objv_tracker);
int get_system_obj_state(RGWSysObjectCtxBase *rctx, const rgw_raw_obj& obj, RGWSysObjState **state, RGWObjVersionTracker *objv_tracker);
int stat(RGWSysObjectCtxBase& obj_ctx,
GetObjState& state,
const rgw_raw_obj& obj,
map<string, bufferlist> *attrs,
bool raw_attrs,
real_time *lastmod,
uint64_t *obj_size,
RGWObjVersionTracker *objv_tracker);
public:
RGWSI_SysObj_Core(CephContext *cct): RGWServiceInstance(cct) {}
RGWSI_Zone *get_zone_svc() {
return zone_svc;
}
};
#endif
|