]> git.proxmox.com Git - ceph.git/blob - ceph/src/osd/objclass.cc
1cc63fbb1451d9292cadc9d4ed44c54a6e35a946
[ceph.git] / ceph / src / osd / objclass.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include <cstdarg>
5 #include "common/ceph_context.h"
6 #include "common/ceph_releases.h"
7 #include "common/config.h"
8 #include "common/debug.h"
9
10 #include "objclass/objclass.h"
11 #include "osd/PrimaryLogPG.h"
12
13 #include "osd/ClassHandler.h"
14
15 #include "auth/Crypto.h"
16 #include "common/armor.h"
17
18 #define dout_context ClassHandler::get_instance().cct
19
20
21 int cls_call(cls_method_context_t hctx, const char *cls, const char *method,
22 char *indata, int datalen,
23 char **outdata, int *outdatalen)
24 {
25 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
26 bufferlist idata;
27 vector<OSDOp> nops(1);
28 OSDOp& op = nops[0];
29 int r;
30
31 op.op.op = CEPH_OSD_OP_CALL;
32 op.op.cls.class_len = strlen(cls);
33 op.op.cls.method_len = strlen(method);
34 op.op.cls.indata_len = datalen;
35 op.indata.append(cls, op.op.cls.class_len);
36 op.indata.append(method, op.op.cls.method_len);
37 op.indata.append(indata, datalen);
38 r = (*pctx)->pg->do_osd_ops(*pctx, nops);
39 if (r < 0)
40 return r;
41
42 *outdata = (char *)malloc(op.outdata.length());
43 if (!*outdata)
44 return -ENOMEM;
45 memcpy(*outdata, op.outdata.c_str(), op.outdata.length());
46 *outdatalen = op.outdata.length();
47
48 return r;
49 }
50
51 int cls_getxattr(cls_method_context_t hctx, const char *name,
52 char **outdata, int *outdatalen)
53 {
54 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
55 vector<OSDOp> nops(1);
56 OSDOp& op = nops[0];
57 int r;
58
59 op.op.op = CEPH_OSD_OP_GETXATTR;
60 op.op.xattr.name_len = strlen(name);
61 op.indata.append(name, op.op.xattr.name_len);
62 r = (*pctx)->pg->do_osd_ops(*pctx, nops);
63 if (r < 0)
64 return r;
65
66 *outdata = (char *)malloc(op.outdata.length());
67 if (!*outdata)
68 return -ENOMEM;
69 memcpy(*outdata, op.outdata.c_str(), op.outdata.length());
70 *outdatalen = op.outdata.length();
71
72 return r;
73 }
74
75 int cls_setxattr(cls_method_context_t hctx, const char *name,
76 const char *value, int val_len)
77 {
78 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
79 vector<OSDOp> nops(1);
80 OSDOp& op = nops[0];
81 int r;
82
83 op.op.op = CEPH_OSD_OP_SETXATTR;
84 op.op.xattr.name_len = strlen(name);
85 op.op.xattr.value_len = val_len;
86 op.indata.append(name, op.op.xattr.name_len);
87 op.indata.append(value, val_len);
88 r = (*pctx)->pg->do_osd_ops(*pctx, nops);
89
90 return r;
91 }
92
93 int cls_read(cls_method_context_t hctx, int ofs, int len,
94 char **outdata, int *outdatalen)
95 {
96 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
97 vector<OSDOp> ops(1);
98 ops[0].op.op = CEPH_OSD_OP_SYNC_READ;
99 ops[0].op.extent.offset = ofs;
100 ops[0].op.extent.length = len;
101 int r = (*pctx)->pg->do_osd_ops(*pctx, ops);
102 if (r < 0)
103 return r;
104
105 *outdata = (char *)malloc(ops[0].outdata.length());
106 if (!*outdata)
107 return -ENOMEM;
108 memcpy(*outdata, ops[0].outdata.c_str(), ops[0].outdata.length());
109 *outdatalen = ops[0].outdata.length();
110
111 return *outdatalen;
112 }
113
114 int cls_get_request_origin(cls_method_context_t hctx, entity_inst_t *origin)
115 {
116 PrimaryLogPG::OpContext **pctx = static_cast<PrimaryLogPG::OpContext **>(hctx);
117 *origin = (*pctx)->op->get_req()->get_orig_source_inst();
118 return 0;
119 }
120
121 int cls_cxx_create(cls_method_context_t hctx, bool exclusive)
122 {
123 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
124 vector<OSDOp> ops(1);
125 ops[0].op.op = CEPH_OSD_OP_CREATE;
126 ops[0].op.flags = (exclusive ? CEPH_OSD_OP_FLAG_EXCL : 0);
127 return (*pctx)->pg->do_osd_ops(*pctx, ops);
128 }
129
130 int cls_cxx_remove(cls_method_context_t hctx)
131 {
132 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
133 vector<OSDOp> ops(1);
134 ops[0].op.op = CEPH_OSD_OP_DELETE;
135 return (*pctx)->pg->do_osd_ops(*pctx, ops);
136 }
137
138 int cls_cxx_stat(cls_method_context_t hctx, uint64_t *size, time_t *mtime)
139 {
140 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
141 vector<OSDOp> ops(1);
142 int ret;
143 ops[0].op.op = CEPH_OSD_OP_STAT;
144 ret = (*pctx)->pg->do_osd_ops(*pctx, ops);
145 if (ret < 0)
146 return ret;
147 auto iter = ops[0].outdata.cbegin();
148 utime_t ut;
149 uint64_t s;
150 try {
151 decode(s, iter);
152 decode(ut, iter);
153 } catch (buffer::error& err) {
154 return -EIO;
155 }
156 if (size)
157 *size = s;
158 if (mtime)
159 *mtime = ut.sec();
160 return 0;
161 }
162
163 int cls_cxx_stat2(cls_method_context_t hctx, uint64_t *size, ceph::real_time *mtime)
164 {
165 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
166 vector<OSDOp> ops(1);
167 int ret;
168 ops[0].op.op = CEPH_OSD_OP_STAT;
169 ret = (*pctx)->pg->do_osd_ops(*pctx, ops);
170 if (ret < 0)
171 return ret;
172 auto iter = ops[0].outdata.cbegin();
173 real_time ut;
174 uint64_t s;
175 try {
176 decode(s, iter);
177 decode(ut, iter);
178 } catch (buffer::error& err) {
179 return -EIO;
180 }
181 if (size)
182 *size = s;
183 if (mtime)
184 *mtime = ut;
185 return 0;
186 }
187
188 int cls_cxx_read2(cls_method_context_t hctx, int ofs, int len,
189 bufferlist *outbl, uint32_t op_flags)
190 {
191 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
192 vector<OSDOp> ops(1);
193 int ret;
194 ops[0].op.op = CEPH_OSD_OP_SYNC_READ;
195 ops[0].op.extent.offset = ofs;
196 ops[0].op.extent.length = len;
197 ops[0].op.flags = op_flags;
198 ret = (*pctx)->pg->do_osd_ops(*pctx, ops);
199 if (ret < 0)
200 return ret;
201 outbl->claim(ops[0].outdata);
202 return outbl->length();
203 }
204
205 int cls_cxx_write2(cls_method_context_t hctx, int ofs, int len,
206 bufferlist *inbl, uint32_t op_flags)
207 {
208 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
209 vector<OSDOp> ops(1);
210 ops[0].op.op = CEPH_OSD_OP_WRITE;
211 ops[0].op.extent.offset = ofs;
212 ops[0].op.extent.length = len;
213 ops[0].op.flags = op_flags;
214 ops[0].indata = *inbl;
215 return (*pctx)->pg->do_osd_ops(*pctx, ops);
216 }
217
218 int cls_cxx_write_full(cls_method_context_t hctx, bufferlist *inbl)
219 {
220 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
221 vector<OSDOp> ops(1);
222 ops[0].op.op = CEPH_OSD_OP_WRITEFULL;
223 ops[0].op.extent.offset = 0;
224 ops[0].op.extent.length = inbl->length();
225 ops[0].indata = *inbl;
226 return (*pctx)->pg->do_osd_ops(*pctx, ops);
227 }
228
229 int cls_cxx_replace(cls_method_context_t hctx, int ofs, int len, bufferlist *inbl)
230 {
231 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
232 vector<OSDOp> ops(2);
233 ops[0].op.op = CEPH_OSD_OP_TRUNCATE;
234 ops[0].op.extent.offset = 0;
235 ops[0].op.extent.length = 0;
236 ops[1].op.op = CEPH_OSD_OP_WRITE;
237 ops[1].op.extent.offset = ofs;
238 ops[1].op.extent.length = len;
239 ops[1].indata = *inbl;
240 return (*pctx)->pg->do_osd_ops(*pctx, ops);
241 }
242
243 int cls_cxx_truncate(cls_method_context_t hctx, int ofs)
244 {
245 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
246 vector<OSDOp> ops(1);
247 ops[0].op.op = CEPH_OSD_OP_TRUNCATE;
248 ops[0].op.extent.offset = ofs;
249 ops[0].op.extent.length = 0;
250 return (*pctx)->pg->do_osd_ops(*pctx, ops);
251 }
252
253 int cls_cxx_write_zero(cls_method_context_t hctx, int ofs, int len)
254 {
255 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
256 vector<OSDOp> ops(1);
257 ops[0].op.op = CEPH_OSD_OP_ZERO;
258 ops[0].op.extent.offset = ofs;
259 ops[0].op.extent.length = len;
260 return (*pctx)->pg->do_osd_ops(*pctx, ops);
261 }
262
263 int cls_cxx_getxattr(cls_method_context_t hctx, const char *name,
264 bufferlist *outbl)
265 {
266 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
267 vector<OSDOp> nops(1);
268 OSDOp& op = nops[0];
269 int r;
270
271 op.op.op = CEPH_OSD_OP_GETXATTR;
272 op.op.xattr.name_len = strlen(name);
273 op.indata.append(name, op.op.xattr.name_len);
274 r = (*pctx)->pg->do_osd_ops(*pctx, nops);
275 if (r < 0)
276 return r;
277
278 outbl->claim(op.outdata);
279 return outbl->length();
280 }
281
282 int cls_cxx_getxattrs(cls_method_context_t hctx, map<string, bufferlist> *attrset)
283 {
284 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
285 vector<OSDOp> nops(1);
286 OSDOp& op = nops[0];
287 int r;
288
289 op.op.op = CEPH_OSD_OP_GETXATTRS;
290 r = (*pctx)->pg->do_osd_ops(*pctx, nops);
291 if (r < 0)
292 return r;
293
294 auto iter = op.outdata.cbegin();
295 try {
296 decode(*attrset, iter);
297 } catch (buffer::error& err) {
298 return -EIO;
299 }
300 return 0;
301 }
302
303 int cls_cxx_setxattr(cls_method_context_t hctx, const char *name,
304 bufferlist *inbl)
305 {
306 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
307 vector<OSDOp> nops(1);
308 OSDOp& op = nops[0];
309 int r;
310
311 op.op.op = CEPH_OSD_OP_SETXATTR;
312 op.op.xattr.name_len = strlen(name);
313 op.op.xattr.value_len = inbl->length();
314 op.indata.append(name, op.op.xattr.name_len);
315 op.indata.append(*inbl);
316 r = (*pctx)->pg->do_osd_ops(*pctx, nops);
317
318 return r;
319 }
320
321 int cls_cxx_snap_revert(cls_method_context_t hctx, snapid_t snapid)
322 {
323 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
324 vector<OSDOp> ops(1);
325 ops[0].op.op = CEPH_OSD_OP_ROLLBACK;
326 ops[0].op.snap.snapid = snapid;
327 return (*pctx)->pg->do_osd_ops(*pctx, ops);
328 }
329
330 int cls_cxx_map_get_all_vals(cls_method_context_t hctx, map<string, bufferlist>* vals,
331 bool *more)
332 {
333 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
334 vector<OSDOp> ops(1);
335 OSDOp& op = ops[0];
336 int ret;
337
338 string start_after;
339 string filter_prefix;
340 uint64_t max = (uint64_t)-1;
341
342 encode(start_after, op.indata);
343 encode(max, op.indata);
344 encode(filter_prefix, op.indata);
345
346 op.op.op = CEPH_OSD_OP_OMAPGETVALS;
347
348 ret = (*pctx)->pg->do_osd_ops(*pctx, ops);
349 if (ret < 0)
350 return ret;
351
352 auto iter = op.outdata.cbegin();
353 try {
354 decode(*vals, iter);
355 decode(*more, iter);
356 } catch (buffer::error& err) {
357 return -EIO;
358 }
359 return vals->size();
360 }
361
362 int cls_cxx_map_get_keys(cls_method_context_t hctx, const string &start_obj,
363 uint64_t max_to_get, set<string> *keys,
364 bool *more)
365 {
366 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
367 vector<OSDOp> ops(1);
368 OSDOp& op = ops[0];
369 int ret;
370
371 encode(start_obj, op.indata);
372 encode(max_to_get, op.indata);
373
374 op.op.op = CEPH_OSD_OP_OMAPGETKEYS;
375
376 ret = (*pctx)->pg->do_osd_ops(*pctx, ops);
377 if (ret < 0)
378 return ret;
379
380 auto iter = op.outdata.cbegin();
381 try {
382 decode(*keys, iter);
383 decode(*more, iter);
384 } catch (buffer::error& err) {
385 return -EIO;
386 }
387 return keys->size();
388 }
389
390 int cls_cxx_map_get_vals(cls_method_context_t hctx, const string &start_obj,
391 const string &filter_prefix, uint64_t max_to_get,
392 map<string, bufferlist> *vals, bool *more)
393 {
394 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
395 vector<OSDOp> ops(1);
396 OSDOp& op = ops[0];
397 int ret;
398
399 encode(start_obj, op.indata);
400 encode(max_to_get, op.indata);
401 encode(filter_prefix, op.indata);
402
403 op.op.op = CEPH_OSD_OP_OMAPGETVALS;
404
405 ret = (*pctx)->pg->do_osd_ops(*pctx, ops);
406 if (ret < 0)
407 return ret;
408
409 auto iter = op.outdata.cbegin();
410 try {
411 decode(*vals, iter);
412 decode(*more, iter);
413 } catch (buffer::error& err) {
414 return -EIO;
415 }
416 return vals->size();
417 }
418
419 int cls_cxx_map_read_header(cls_method_context_t hctx, bufferlist *outbl)
420 {
421 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
422 vector<OSDOp> ops(1);
423 OSDOp& op = ops[0];
424 int ret;
425 op.op.op = CEPH_OSD_OP_OMAPGETHEADER;
426 ret = (*pctx)->pg->do_osd_ops(*pctx, ops);
427 if (ret < 0)
428 return ret;
429
430 outbl->claim(op.outdata);
431
432 return 0;
433 }
434
435 int cls_cxx_map_get_val(cls_method_context_t hctx, const string &key,
436 bufferlist *outbl)
437 {
438 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
439 vector<OSDOp> ops(1);
440 OSDOp& op = ops[0];
441 int ret;
442
443 set<string> k;
444 k.insert(key);
445 encode(k, op.indata);
446
447 op.op.op = CEPH_OSD_OP_OMAPGETVALSBYKEYS;
448 ret = (*pctx)->pg->do_osd_ops(*pctx, ops);
449 if (ret < 0)
450 return ret;
451
452 auto iter = op.outdata.cbegin();
453 try {
454 map<string, bufferlist> m;
455
456 decode(m, iter);
457 map<string, bufferlist>::iterator iter = m.begin();
458 if (iter == m.end())
459 return -ENOENT;
460
461 *outbl = iter->second;
462 } catch (buffer::error& e) {
463 return -EIO;
464 }
465 return 0;
466 }
467
468 int cls_cxx_map_set_val(cls_method_context_t hctx, const string &key,
469 bufferlist *inbl)
470 {
471 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
472 vector<OSDOp> ops(1);
473 OSDOp& op = ops[0];
474 bufferlist& update_bl = op.indata;
475 map<string, bufferlist> m;
476 m[key] = *inbl;
477 encode(m, update_bl);
478
479 op.op.op = CEPH_OSD_OP_OMAPSETVALS;
480
481 return (*pctx)->pg->do_osd_ops(*pctx, ops);
482 }
483
484 int cls_cxx_map_set_vals(cls_method_context_t hctx,
485 const std::map<string, bufferlist> *map)
486 {
487 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
488 vector<OSDOp> ops(1);
489 OSDOp& op = ops[0];
490 bufferlist& update_bl = op.indata;
491 encode(*map, update_bl);
492
493 op.op.op = CEPH_OSD_OP_OMAPSETVALS;
494
495 return (*pctx)->pg->do_osd_ops(*pctx, ops);
496 }
497
498 int cls_cxx_map_clear(cls_method_context_t hctx)
499 {
500 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
501 vector<OSDOp> ops(1);
502 OSDOp& op = ops[0];
503
504 op.op.op = CEPH_OSD_OP_OMAPCLEAR;
505
506 return (*pctx)->pg->do_osd_ops(*pctx, ops);
507 }
508
509 int cls_cxx_map_write_header(cls_method_context_t hctx, bufferlist *inbl)
510 {
511 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
512 vector<OSDOp> ops(1);
513 OSDOp& op = ops[0];
514 op.indata.claim(*inbl);
515
516 op.op.op = CEPH_OSD_OP_OMAPSETHEADER;
517
518 return (*pctx)->pg->do_osd_ops(*pctx, ops);
519 }
520
521 int cls_cxx_map_remove_range(cls_method_context_t hctx,
522 const std::string& key_begin,
523 const std::string& key_end)
524 {
525 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
526 vector<OSDOp> ops(1);
527 OSDOp& op = ops[0];
528 bufferlist& update_bl = op.indata;
529
530 ::encode(key_begin, update_bl);
531 ::encode(key_end, update_bl);
532
533 op.op.op = CEPH_OSD_OP_OMAPRMKEYRANGE;
534
535 return (*pctx)->pg->do_osd_ops(*pctx, ops);
536 }
537
538 int cls_cxx_map_remove_key(cls_method_context_t hctx, const string &key)
539 {
540 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
541 vector<OSDOp> ops(1);
542 OSDOp& op = ops[0];
543 bufferlist& update_bl = op.indata;
544 set<string> to_rm;
545 to_rm.insert(key);
546
547 encode(to_rm, update_bl);
548
549 op.op.op = CEPH_OSD_OP_OMAPRMKEYS;
550
551 return (*pctx)->pg->do_osd_ops(*pctx, ops);
552 }
553
554 int cls_cxx_list_watchers(cls_method_context_t hctx,
555 obj_list_watch_response_t *watchers)
556 {
557 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
558 vector<OSDOp> nops(1);
559 OSDOp& op = nops[0];
560 int r;
561
562 op.op.op = CEPH_OSD_OP_LIST_WATCHERS;
563 r = (*pctx)->pg->do_osd_ops(*pctx, nops);
564 if (r < 0)
565 return r;
566
567 auto iter = op.outdata.cbegin();
568 try {
569 decode(*watchers, iter);
570 } catch (buffer::error& err) {
571 return -EIO;
572 }
573 return 0;
574 }
575
576 uint64_t cls_current_version(cls_method_context_t hctx)
577 {
578 PrimaryLogPG::OpContext *ctx = *(PrimaryLogPG::OpContext **)hctx;
579
580 return ctx->pg->get_last_user_version();
581 }
582
583
584 int cls_current_subop_num(cls_method_context_t hctx)
585 {
586 PrimaryLogPG::OpContext *ctx = *(PrimaryLogPG::OpContext **)hctx;
587
588 return ctx->processed_subop_count;
589 }
590
591 uint64_t cls_get_features(cls_method_context_t hctx)
592 {
593 PrimaryLogPG::OpContext *ctx = *(PrimaryLogPG::OpContext **)hctx;
594 return ctx->pg->get_osdmap()->get_up_osd_features();
595 }
596
597 uint64_t cls_get_client_features(cls_method_context_t hctx)
598 {
599 PrimaryLogPG::OpContext *ctx = *(PrimaryLogPG::OpContext **)hctx;
600 return ctx->op->get_req()->get_connection()->get_features();
601 }
602
603 ceph_release_t cls_get_required_osd_release(cls_method_context_t hctx)
604 {
605 PrimaryLogPG::OpContext *ctx = *(PrimaryLogPG::OpContext **)hctx;
606 return ctx->pg->get_osdmap()->require_osd_release;
607 }
608
609 ceph_release_t cls_get_min_compatible_client(cls_method_context_t hctx)
610 {
611 PrimaryLogPG::OpContext *ctx = *(PrimaryLogPG::OpContext **)hctx;
612 return ctx->pg->get_osdmap()->get_require_min_compat_client();
613 }
614
615 int cls_get_snapset_seq(cls_method_context_t hctx, uint64_t *snap_seq) {
616 PrimaryLogPG::OpContext *ctx = *(PrimaryLogPG::OpContext **)hctx;
617 if (!ctx->new_obs.exists || (ctx->new_obs.oi.is_whiteout() &&
618 ctx->obc->ssc->snapset.clones.empty())) {
619 return -ENOENT;
620 }
621 *snap_seq = ctx->obc->ssc->snapset.seq;
622 return 0;
623 }
624
625 int cls_cxx_chunk_write_and_set(cls_method_context_t hctx, int ofs, int len,
626 bufferlist *write_inbl, uint32_t op_flags, bufferlist *set_inbl,
627 int set_len)
628 {
629 PrimaryLogPG::OpContext **pctx = (PrimaryLogPG::OpContext **)hctx;
630 char cname[] = "cas";
631 char method[] = "chunk_set";
632
633 vector<OSDOp> ops(2);
634 ops[0].op.op = CEPH_OSD_OP_WRITE;
635 ops[0].op.extent.offset = ofs;
636 ops[0].op.extent.length = len;
637 ops[0].op.flags = op_flags;
638 ops[0].indata = *write_inbl;
639
640 ops[1].op.op = CEPH_OSD_OP_CALL;
641 ops[1].op.cls.class_len = strlen(cname);
642 ops[1].op.cls.method_len = strlen(method);
643 ops[1].op.cls.indata_len = set_len;
644 ops[1].indata.append(cname, ops[1].op.cls.class_len);
645 ops[1].indata.append(method, ops[1].op.cls.method_len);
646 ops[1].indata.append(*set_inbl);
647
648 return (*pctx)->pg->do_osd_ops(*pctx, ops);
649 }
650
651 bool cls_has_chunk(cls_method_context_t hctx, string fp_oid)
652 {
653 PrimaryLogPG::OpContext *ctx = *(PrimaryLogPG::OpContext **)hctx;
654 if (!ctx->obc->obs.oi.has_manifest()) {
655 return false;
656 }
657
658 for (auto &p : ctx->obc->obs.oi.manifest.chunk_map) {
659 if (p.second.oid.oid.name == fp_oid) {
660 return true;
661 }
662 }
663
664 return false;
665 }
666
667 uint64_t cls_get_osd_min_alloc_size(cls_method_context_t hctx) {
668 PrimaryLogPG::OpContext *ctx = *(PrimaryLogPG::OpContext **)hctx;
669
670 return ctx->pg->get_min_alloc_size();
671 }