Motr  M0
index_op.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2016-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 
30 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CLIENT
31 #include "lib/assert.h" /* M0_ASSERT */
32 #include "lib/memory.h" /* M0_ALLOC_ARR */
33 #include "lib/time.h" /* M0_TIME_NEVER */
34 #include "lib/errno.h"
35 #include "lib/trace.h" /* M0_ERR */
36 #include "index_op.h"
37 #include "motr/client.h"
38 #include "motr/idx.h"
39 #include "index.h"
40 #include "cas/cas.h" /* m0_dix_fid_type */
41 #include "fid/fid.h" /* m0_fid_tassume */
42 
43 static int per_item_rcs_analyse(int32_t *rcs, int cnt)
44 {
45  int i;
46  int rc = 0;
47 
48  for (i = 0; i < cnt; i++)
49  if (rcs[i] != 0) {
50  m0_console_printf("rcs[%d]: %d\n", i, rcs[i]);
51  rc = rcs[i];
52  }
53  return M0_RC(rc);
54 }
55 
56 static int index_op_tail(struct m0_entity *ce,
57  struct m0_op *op, int rc,
58  int *sm_rc)
59 {
60  if (rc == 0) {
61  m0_op_launch(&op, 1);
62  rc = m0_op_wait(op,
64  M0_OS_STABLE),
66  m0_console_printf("operation rc: %i\n", op->op_rc);
67  if (sm_rc != NULL)
68  /* Save retcodes. */
69  *sm_rc = op->op_rc;
70  } else
71  m0_console_printf("operation rc: %i\n", rc);
72  m0_op_fini(op);
73  m0_op_free(op);
74  m0_entity_fini(ce);
75  return M0_RC(rc);
76 }
77 
78 int index_create(struct m0_realm *parent, struct m0_fid_arr *fids)
79 {
80  int i;
81  int rc = 0;
82 
83  M0_PRE(fids != NULL && fids->af_count != 0);
84 
85  for(i = 0; rc == 0 && i < fids->af_count; ++i) {
86  struct m0_op *op = NULL;
87  struct m0_idx idx;
88 
89  m0_fid_tassume(&fids->af_elems[i], &m0_dix_fid_type);
90  m0_idx_init(&idx, parent,
91  (struct m0_uint128 *)&fids->af_elems[i]);
92  rc = m0_entity_create(NULL, &idx.in_entity, &op);
93  rc = index_op_tail(&idx.in_entity, op, rc, NULL);
94  }
95  return M0_RC(rc);
96 }
97 
98 int index_drop(struct m0_realm *parent, struct m0_fid_arr *fids)
99 {
100  int i;
101  int rc = 0;
102 
103  M0_PRE(fids != NULL && fids->af_count != 0);
104 
105  for(i = 0; rc == 0 && i < fids->af_count; ++i) {
106  struct m0_idx idx;
107  struct m0_op *op = NULL;
108 
109  m0_fid_tassume(&fids->af_elems[i], &m0_dix_fid_type);
110  m0_idx_init(&idx, parent,
111  (struct m0_uint128 *)&fids->af_elems[i]);
112  rc = m0_entity_open(&idx.in_entity, &op) ?:
113  m0_entity_delete(&idx.in_entity, &op) ?:
114  index_op_tail(&idx.in_entity, op, rc, NULL);
115  }
116  return M0_RC(rc);
117 }
118 
119 int index_list(struct m0_realm *parent,
120  struct m0_fid *fid,
121  int cnt,
122  struct m0_bufvec *keys)
123 {
124  struct m0_idx idx;
125  struct m0_op *op = NULL;
126  int32_t *rcs;
127  int rc;
128 
129  M0_PRE(cnt != 0);
130  M0_PRE(fid != NULL);
131  M0_ALLOC_ARR(rcs, cnt);
132  rc = m0_bufvec_alloc(keys, cnt, sizeof(struct m0_fid));
133  if (rc != 0 || rcs == NULL) {
134  m0_free(rcs);
135  return M0_ERR(rc);
136  }
138  m0_idx_init(&idx, parent, (struct m0_uint128 *)fid);
139  rc = m0_idx_op(&idx, M0_IC_LIST, keys, NULL,
140  rcs, 0, &op);
141  rc = index_op_tail(&idx.in_entity, op, rc, NULL);
142  m0_free(rcs);
143  return M0_RC(rc);
144 }
145 
146 int index_lookup(struct m0_realm *parent,
147  struct m0_fid_arr *fids,
148  struct m0_bufvec *rets)
149 {
150  int i;
151  int rc = 0;
152 
153  M0_PRE(fids != NULL);
154  M0_PRE(fids->af_count != 0);
155  M0_PRE(rets != NULL);
156  M0_PRE(rets->ov_vec.v_nr == 0);
157 
158  rc = m0_bufvec_alloc(rets, fids->af_count, sizeof(rc));
159  /* Check that indices exist. */
160  for(i = 0; rc == 0 && i < fids->af_count; ++i) {
161  struct m0_idx idx;
162  struct m0_op *op = NULL;
163 
164  m0_fid_tassume(&fids->af_elems[i], &m0_dix_fid_type);
165  m0_idx_init(&idx, parent,
166  (struct m0_uint128 *)&fids->af_elems[i]);
167  rc = m0_idx_op(&idx, M0_IC_LOOKUP, NULL, NULL,
168  NULL, 0, &op);
169  rc = index_op_tail(&idx.in_entity, op, rc,
170  (int *)rets->ov_buf[i]);
171  }
172  return M0_RC(rc);
173 }
174 
175 static int index_op(struct m0_realm *parent,
176  struct m0_fid *fid,
177  enum m0_idx_opcode opcode,
178  struct m0_bufvec *keys,
179  struct m0_bufvec *vals)
180 {
181  struct m0_idx idx;
182  struct m0_op *op = NULL;
183  int32_t *rcs;
184  int rc;
185 
186  M0_ASSERT(keys != NULL);
187  M0_ASSERT(keys->ov_vec.v_nr != 0);
188  M0_ALLOC_ARR(rcs, keys->ov_vec.v_nr);
189  if (rcs == NULL)
190  return M0_ERR(-ENOMEM);
191 
193  m0_idx_init(&idx, parent, (struct m0_uint128 *)fid);
194  rc = m0_idx_op(&idx, opcode, keys, vals, rcs,
196  &op);
197  rc = index_op_tail(&idx.in_entity, op, rc, NULL);
198  /*
199  * Don't analyse per-item codes for NEXT, because usually user gets
200  * -ENOENT in 'rcs' since he requests more entries than exist.
201  */
202  if (opcode != M0_IC_NEXT)
203  rc = per_item_rcs_analyse(rcs, keys->ov_vec.v_nr);
204  m0_free(rcs);
205  return M0_RC(rc);
206 }
207 
208 int index_put(struct m0_realm *parent,
209  struct m0_fid_arr *fids,
210  struct m0_bufvec *keys,
211  struct m0_bufvec *vals)
212 {
213  int rc = 0;
214  int i;
215 
216  M0_PRE(fids != NULL && fids->af_count != 0);
217  M0_PRE(keys != NULL);
218  M0_PRE(vals != NULL);
219 
220  for (i = 0; i < fids->af_count && rc == 0; i++)
221  rc = index_op(parent, &fids->af_elems[i],
222  M0_IC_PUT, keys, vals);
223 
224  return M0_RC(rc);
225 }
226 
227 int index_del(struct m0_realm *parent,
228  struct m0_fid_arr *fids,
229  struct m0_bufvec *keys)
230 {
231  int rc = 0;
232  int i;
233 
234  M0_PRE(fids != NULL && fids->af_count != 0);
235  M0_PRE(keys != NULL);
236 
237  for (i = 0; i < fids->af_count && rc == 0; i++)
238  rc = index_op(parent, &fids->af_elems[i],
239  M0_IC_DEL, keys, NULL);
240 
241  return M0_RC(rc);
242 }
243 
244 int index_get(struct m0_realm *parent,
245  struct m0_fid *fid,
246  struct m0_bufvec *keys,
247  struct m0_bufvec *vals)
248 {
249  int rc;
250  int keys_nr;
251 
252  M0_PRE(fid != NULL);
253  M0_PRE(keys != NULL);
254  M0_PRE(vals != NULL && vals->ov_vec.v_nr == 0);
255 
256  /* Allocate vals entity without buffers. */
257  keys_nr = keys->ov_vec.v_nr;
258  rc = m0_bufvec_empty_alloc(vals, keys_nr) ?:
259  index_op(parent, fid, M0_IC_GET, keys, vals) ?:
260  m0_exists(i, keys_nr, vals->ov_buf[i] == NULL) ?
261  M0_ERR(-ENODATA) : 0;
262 
263  return M0_RC(rc);
264 }
265 
266 int index_next(struct m0_realm *parent,
267  struct m0_fid *fid,
268  struct m0_bufvec *keys,
269  int cnt,
270  struct m0_bufvec *vals)
271 {
272  int rc;
273  void *startkey;
274  int startkey_size;
275 
276  M0_PRE(fid != NULL);
277  M0_PRE(cnt != 0);
278  M0_PRE(keys != NULL && keys->ov_vec.v_nr == 1);
279  M0_PRE(vals != NULL && vals->ov_vec.v_nr == 0);
280 
281  /* Allocate array for VALs. */
282  rc = m0_bufvec_empty_alloc(vals, cnt);
283  /* Allocate array for KEYs, reuse first buffer. */
284  if (rc == 0) {
285  startkey = m0_alloc(keys->ov_vec.v_count[0]);
286  if (startkey == NULL)
287  goto fail;
288  startkey_size = keys->ov_vec.v_count[0];
289  memcpy(startkey, keys->ov_buf[0], keys->ov_vec.v_count[0]);
290  m0_bufvec_free(keys);
291  rc = m0_bufvec_empty_alloc(keys, cnt);
292  if (rc != 0)
293  goto fail;
294  keys->ov_buf[0] = startkey;
295  keys->ov_vec.v_count[0] = startkey_size;
296  }
297  if (rc == 0)
298  rc = index_op(parent, fid, M0_IC_NEXT, keys, vals);
299 
300  return M0_RC(rc);
301 fail:
302  rc = M0_ERR(-ENOMEM);
303  m0_bufvec_free(vals);
304  m0_bufvec_free(keys);
305  m0_free(startkey);
306  return M0_ERR(rc);
307 }
308 
309 
310 #undef M0_TRACE_SUBSYSTEM
311 
314 /*
315  * Local variables:
316  * c-indentation-style: "K&R"
317  * c-basic-offset: 8
318  * tab-width: 8
319  * fill-column: 80
320  * scroll-step: 1
321  * End:
322  */
323 /*
324  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
325  */
int index_drop(struct m0_realm *parent, struct m0_fid_arr *fids)
Definition: index_op.c:98
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
Definition: client.h:835
void m0_entity_fini(struct m0_entity *entity)
Definition: client.c:438
#define NULL
Definition: misc.h:38
int index_del(struct m0_realm *parent, struct m0_fid_arr *fids, struct m0_bufvec *keys)
Definition: index_op.c:227
m0_idx_opcode
Definition: client.h:550
static int index_op(struct m0_realm *parent, struct m0_fid *fid, enum m0_idx_opcode opcode, struct m0_bufvec *keys, struct m0_bufvec *vals)
Definition: index_op.c:175
static int index_op_tail(struct m0_entity *ce, struct m0_op *op, int rc, int *sm_rc)
Definition: index_op.c:56
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
void m0_op_fini(struct m0_op *op)
Definition: client.c:847
void m0_console_printf(const char *fmt,...)
Definition: trace.c:801
struct m0_vec ov_vec
Definition: vec.h:147
int index_next(struct m0_realm *parent, struct m0_fid *fid, struct m0_bufvec *keys, int cnt, struct m0_bufvec *vals)
Definition: index_op.c:266
int index_create(struct m0_realm *parent, struct m0_fid_arr *fids)
Definition: index_op.c:78
#define m0_exists(var, nr,...)
Definition: misc.h:134
#define M0_BITS(...)
Definition: misc.h:236
int index_get(struct m0_realm *parent, struct m0_fid *fid, struct m0_bufvec *keys, struct m0_bufvec *vals)
Definition: index_op.c:244
void ** ov_buf
Definition: vec.h:149
struct m0_fid fid
Definition: di.c:46
M0_INTERNAL int m0_bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size)
Definition: vec.c:220
int32_t m0_op_wait(struct m0_op *op, uint64_t bits, m0_time_t to)
Definition: client.c:739
int m0_idx_op(struct m0_idx *idx, enum m0_idx_opcode opcode, struct m0_bufvec *keys, struct m0_bufvec *vals, int32_t *rcs, uint32_t flags, struct m0_op **op)
Definition: idx.c:554
return M0_RC(rc)
op
Definition: libdemo.c:64
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
struct m0_entity in_entity
Definition: client.h:836
int opcode
Definition: crate.c:301
int i
Definition: dir.c:1033
Definition: client.h:641
return M0_ERR(-EOPNOTSUPP)
Definition: cnt.h:36
M0_INTERNAL const struct m0_fid_type m0_dix_fid_type
Definition: cas.c:168
#define M0_ASSERT(cond)
void m0_op_launch(struct m0_op **op, uint32_t nr)
Definition: client.c:725
void * m0_alloc(size_t size)
Definition: memory.c:126
static int per_item_rcs_analyse(int32_t *rcs, int cnt)
Definition: index_op.c:43
int index_put(struct m0_realm *parent, struct m0_fid_arr *fids, struct m0_bufvec *keys, struct m0_bufvec *vals)
Definition: index_op.c:208
Definition: fid.h:43
uint32_t v_nr
Definition: vec.h:51
static const struct m0_fid fids[]
Definition: diter.c:76
m0_bcount_t * v_count
Definition: vec.h:53
int index_lookup(struct m0_realm *parent, struct m0_fid_arr *fids, struct m0_bufvec *rets)
Definition: index_op.c:146
int m0_entity_create(struct m0_fid *pool, struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:801
static uint8_t fail[DATA_UNIT_COUNT_MAX+PARITY_UNIT_COUNT_MAX]
Definition: fid.h:38
int index_list(struct m0_realm *parent, struct m0_fid *fid, int cnt, struct m0_bufvec *keys)
Definition: index_op.c:119
int m0_entity_delete(struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:824
void m0_op_free(struct m0_op *op)
Definition: client.c:885
int m0_entity_open(struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:885
void m0_free(void *data)
Definition: memory.c:146
int32_t rc
Definition: trigger_fop.h:47
void m0_idx_init(struct m0_idx *idx, struct m0_realm *parent, const struct m0_uint128 *id)
Definition: idx.c:626
Definition: vec.h:145
M0_INTERNAL int m0_bufvec_empty_alloc(struct m0_bufvec *bufvec, uint32_t num_segs)
Definition: vec.c:213
M0_INTERNAL void m0_fid_tassume(struct m0_fid *fid, const struct m0_fid_type *ft)
Definition: fid.c:146