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