]> git.proxmox.com Git - ceph.git/blame - ceph/src/cls/numops/cls_numops.cc
bump version to 18.2.4-pve3
[ceph.git] / ceph / src / cls / numops / cls_numops.cc
CommitLineData
f67539c2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
7c673cae
FG
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2015 CERN
7 *
8 * Author: Joaquim Rocha <joaquim.rocha@cern.ch>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 */
16
17/** \file
18 *
19 * This is an OSD class that implements methods for object numeric options on
20 * its omap values.
21 *
22 */
23
24#include "objclass/objclass.h"
25#include <errno.h>
7c673cae
FG
26#include <string>
27#include <sstream>
28#include <cstdio>
29#include <include/compat.h>
30
31#define DECIMAL_PRECISION 10
32
9f95a23c
TL
33using ceph::bufferlist;
34using std::string;
35using ceph::decode;
36using ceph::encode;
37
7c673cae
FG
38CLS_VER(1,0)
39CLS_NAME(numops)
40
41static int add(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
42{
43 string key, diff_str;
44
11fdf7f2 45 auto iter = in->cbegin();
7c673cae 46 try {
11fdf7f2
TL
47 decode(key, iter);
48 decode(diff_str, iter);
f67539c2 49 } catch (const ceph::buffer::error &err) {
7c673cae
FG
50 CLS_LOG(20, "add: invalid decode of input");
51 return -EINVAL;
52 }
53
54 char *end_ptr = 0;
55 double difference = strtod(diff_str.c_str(), &end_ptr);
56
57 if (end_ptr && *end_ptr != '\0') {
58 CLS_ERR("add: invalid input value: %s", diff_str.c_str());
59 return -EINVAL;
60 }
61
62 bufferlist bl;
63 int ret = cls_cxx_map_get_val(hctx, key, &bl);
64
65 double value;
66
67 if (ret == -ENODATA || bl.length() == 0) {
68 value = 0;
69 } else if (ret < 0) {
70 if (ret != -ENOENT) {
71 CLS_ERR("add: error reading omap key %s: %d", key.c_str(), ret);
72 }
73 return ret;
74 } else {
75 std::string stored_value(bl.c_str(), bl.length());
76 end_ptr = 0;
77 value = strtod(stored_value.c_str(), &end_ptr);
78
79 if (end_ptr && *end_ptr != '\0') {
80 CLS_ERR("add: invalid stored value: %s", stored_value.c_str());
81 return -EBADMSG;
82 }
83 }
84
85 value += difference;
86
87 std::stringstream stream;
88 stream << std::setprecision(DECIMAL_PRECISION) << value;
89
90 bufferlist new_value;
91 new_value.append(stream.str());
92
93 return cls_cxx_map_set_val(hctx, key, &new_value);
94}
95
96static int mul(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
97{
98 string key, diff_str;
99
11fdf7f2 100 auto iter = in->cbegin();
7c673cae 101 try {
11fdf7f2
TL
102 decode(key, iter);
103 decode(diff_str, iter);
f67539c2 104 } catch (const ceph::buffer::error &err) {
11fdf7f2 105 CLS_LOG(20, "mul: invalid decode of input");
7c673cae
FG
106 return -EINVAL;
107 }
108
109 char *end_ptr = 0;
110 double difference = strtod(diff_str.c_str(), &end_ptr);
111
112 if (end_ptr && *end_ptr != '\0') {
11fdf7f2 113 CLS_ERR("mul: invalid input value: %s", diff_str.c_str());
7c673cae
FG
114 return -EINVAL;
115 }
116
117 bufferlist bl;
118 int ret = cls_cxx_map_get_val(hctx, key, &bl);
119
120 double value;
121
122 if (ret == -ENODATA || bl.length() == 0) {
123 value = 0;
124 } else if (ret < 0) {
125 if (ret != -ENOENT) {
11fdf7f2 126 CLS_ERR("mul: error reading omap key %s: %d", key.c_str(), ret);
7c673cae
FG
127 }
128 return ret;
129 } else {
130 std::string stored_value(bl.c_str(), bl.length());
131 end_ptr = 0;
132 value = strtod(stored_value.c_str(), &end_ptr);
133
134 if (end_ptr && *end_ptr != '\0') {
11fdf7f2 135 CLS_ERR("mul: invalid stored value: %s", stored_value.c_str());
7c673cae
FG
136 return -EBADMSG;
137 }
138 }
139
140 value *= difference;
141
142 std::stringstream stream;
143 stream << std::setprecision(DECIMAL_PRECISION) << value;
144
145 bufferlist new_value;
146 new_value.append(stream.str());
147
148 return cls_cxx_map_set_val(hctx, key, &new_value);
149}
150
151CLS_INIT(numops)
152{
153 CLS_LOG(20, "loading cls_numops");
154
155 cls_handle_t h_class;
156 cls_method_handle_t h_add;
157 cls_method_handle_t h_mul;
158
159 cls_register("numops", &h_class);
160
161 cls_register_cxx_method(h_class, "add",
162 CLS_METHOD_RD | CLS_METHOD_WR,
163 add, &h_add);
164
165 cls_register_cxx_method(h_class, "mul",
166 CLS_METHOD_RD | CLS_METHOD_WR,
167 mul, &h_mul);
168}