1 // -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
6 #include "objclass/objclass.h"
7 #include "cls_cas_ops.h"
9 #include "include/compat.h"
10 #include "osd/osd_types.h"
15 struct chunk_obj_refcount
;
17 static int chunk_read_refcount(cls_method_context_t hctx
, chunk_obj_refcount
*objr
)
21 int ret
= cls_cxx_getxattr(hctx
, CHUNK_REFCOUNT_ATTR
, &bl
);
22 if (ret
== -ENODATA
) {
29 auto iter
= bl
.cbegin();
31 } catch (buffer::error
& err
) {
32 CLS_LOG(0, "ERROR: chunk_read_refcount(): failed to decode refcount entry\n");
39 static int chunk_set_refcount(cls_method_context_t hctx
, const struct chunk_obj_refcount
& objr
)
45 int ret
= cls_cxx_setxattr(hctx
, CHUNK_REFCOUNT_ATTR
, &bl
);
52 static int cls_rc_chunk_refcount_get(cls_method_context_t hctx
, bufferlist
*in
, bufferlist
*out
)
54 auto in_iter
= in
->cbegin();
56 cls_chunk_refcount_get_op op
;
59 } catch (buffer::error
& err
) {
60 CLS_LOG(1, "ERROR: cls_rc_refcount_get(): failed to decode entry\n");
64 chunk_obj_refcount objr
;
65 int ret
= chunk_read_refcount(hctx
, &objr
);
69 CLS_LOG(10, "cls_rc_chunk_refcount_get() oid=%s\n", op
.source
.oid
.name
.c_str());
71 objr
.refs
.insert(op
.source
);
73 ret
= chunk_set_refcount(hctx
, objr
);
80 static int cls_rc_chunk_refcount_put(cls_method_context_t hctx
, bufferlist
*in
, bufferlist
*out
)
82 auto in_iter
= in
->cbegin();
84 cls_chunk_refcount_put_op op
;
87 } catch (buffer::error
& err
) {
88 CLS_LOG(1, "ERROR: cls_rc_chunk_refcount_put(): failed to decode entry\n");
92 chunk_obj_refcount objr
;
93 int ret
= chunk_read_refcount(hctx
, &objr
);
97 if (objr
.refs
.empty()) {// shouldn't happen!
98 CLS_LOG(0, "ERROR: cls_rc_chunk_refcount_put() was called without any references!\n");
102 CLS_LOG(10, "cls_rc_chunk_refcount_put() oid=%s\n", op
.source
.oid
.name
.c_str());
105 for (auto &p
: objr
.refs
) {
106 if (p
== op
.source
) {
116 auto p
= objr
.refs
.find(op
.source
);
119 if (objr
.refs
.empty()) {
120 return cls_cxx_remove(hctx
);
123 ret
= chunk_set_refcount(hctx
, objr
);
130 static int cls_rc_chunk_refcount_set(cls_method_context_t hctx
, bufferlist
*in
, bufferlist
*out
)
132 auto in_iter
= in
->cbegin();
134 cls_chunk_refcount_set_op op
;
137 } catch (buffer::error
& err
) {
138 CLS_LOG(1, "ERROR: cls_chunk_refcount_set(): failed to decode entry\n");
142 if (!op
.refs
.size()) {
143 return cls_cxx_remove(hctx
);
146 chunk_obj_refcount objr
;
149 int ret
= chunk_set_refcount(hctx
, objr
);
156 static int cls_rc_chunk_refcount_read(cls_method_context_t hctx
, bufferlist
*in
, bufferlist
*out
)
158 chunk_obj_refcount objr
;
160 cls_chunk_refcount_read_ret read_ret
;
161 int ret
= chunk_read_refcount(hctx
, &objr
);
165 for (auto &p
: objr
.refs
) {
166 read_ret
.refs
.insert(p
);
169 encode(read_ret
, *out
);
174 static int cls_rc_write_or_get(cls_method_context_t hctx
, bufferlist
*in
, bufferlist
*out
)
176 auto in_iter
= in
->cbegin();
178 bufferlist indata
, outdata
;
181 decode (op
, in_iter
);
182 decode(src_obj
, in_iter
);
183 in_iter
.copy(op
.extent
.length
, indata
);
185 catch (buffer::error
& e
) {
189 CLS_LOG(10, " offset: %llu length: %llu \n",
190 static_cast<long long unsigned>(op
.extent
.offset
),
191 static_cast<long long unsigned>(op
.extent
.length
));
192 chunk_obj_refcount objr
;
193 int ret
= chunk_read_refcount(hctx
, &objr
);
194 if (ret
== -ENOENT
) {
195 objr
.refs
.insert(src_obj
);
197 encode(objr
, set_bl
);
198 ret
= cls_cxx_chunk_write_and_set(hctx
, op
.extent
.offset
, op
.extent
.length
, &indata
, op
.flags
,
199 &set_bl
, set_bl
.length());
206 objr
.refs
.insert(src_obj
);
207 ret
= chunk_set_refcount(hctx
, objr
);
215 static int cls_rc_has_chunk(cls_method_context_t hctx
, bufferlist
*in
, bufferlist
*out
)
217 auto in_iter
= in
->cbegin();
219 bufferlist indata
, outdata
;
221 decode (fp_oid
, in_iter
);
223 catch (buffer::error
& e
) {
226 CLS_LOG(10, " fp_oid: %s \n", fp_oid
.c_str());
228 bool ret
= cls_has_chunk(hctx
, fp_oid
);
237 CLS_LOG(1, "Loaded cas class!");
239 cls_handle_t h_class
;
240 cls_method_handle_t h_cas_write_or_get
;
241 cls_method_handle_t h_chunk_refcount_get
;
242 cls_method_handle_t h_chunk_refcount_put
;
243 cls_method_handle_t h_chunk_refcount_set
;
244 cls_method_handle_t h_chunk_refcount_read
;
245 cls_method_handle_t h_chunk_has_chunk
;
247 cls_register("cas", &h_class
);
250 cls_register_cxx_method(h_class
, "chunk_get", CLS_METHOD_RD
| CLS_METHOD_WR
, cls_rc_chunk_refcount_get
,
251 &h_chunk_refcount_get
);
252 cls_register_cxx_method(h_class
, "chunk_put", CLS_METHOD_RD
| CLS_METHOD_WR
, cls_rc_chunk_refcount_put
,
253 &h_chunk_refcount_put
);
254 cls_register_cxx_method(h_class
, "chunk_set", CLS_METHOD_RD
| CLS_METHOD_WR
, cls_rc_chunk_refcount_set
,
255 &h_chunk_refcount_set
);
256 cls_register_cxx_method(h_class
, "chunk_read", CLS_METHOD_RD
, cls_rc_chunk_refcount_read
,
257 &h_chunk_refcount_read
);
258 cls_register_cxx_method(h_class
, "cas_write_or_get", CLS_METHOD_RD
| CLS_METHOD_WR
, cls_rc_write_or_get
,
259 &h_cas_write_or_get
);
260 cls_register_cxx_method(h_class
, "has_chunk", CLS_METHOD_RD
, cls_rc_has_chunk
,