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 void set_enf_meta_flag(struct m0_idx *idx)
79 {
81  if (dix_pool_ver.f_container != 0) {
84  m0_console_printf("DIX pool version: "FID_F" \n",
85  FID_P(&idx->in_attr.idx_pver));
86  }
87 }
88 
89 int index_create(struct m0_realm *parent, struct m0_fid_arr *fids)
90 {
91  int i;
92  int rc = 0;
93 
94  M0_PRE(fids != NULL && fids->af_count != 0);
95 
96  for(i = 0; rc == 0 && i < fids->af_count; ++i) {
97  struct m0_op *op = NULL;
98  struct m0_idx idx;
99 
100  m0_fid_tassume(&fids->af_elems[i], &m0_dix_fid_type);
101  m0_idx_init(&idx, parent,
102  (struct m0_uint128 *)&fids->af_elems[i]);
103 
104  if (is_enf_meta)
105  set_enf_meta_flag(&idx);
106 
107  rc = m0_entity_create(NULL, &idx.in_entity, &op);
108  rc = index_op_tail(&idx.in_entity, op, rc, NULL);
109  if (rc == 0 && is_enf_meta)
110  m0_console_printf("DIX pool version: "FID_F" \n",
111  FID_P(&idx.in_attr.idx_pver));
112  }
113  return M0_RC(rc);
114 }
115 
116 int index_drop(struct m0_realm *parent, struct m0_fid_arr *fids)
117 {
118  int i;
119  int rc = 0;
120 
121  M0_PRE(fids != NULL && fids->af_count != 0);
122 
123  for(i = 0; rc == 0 && i < fids->af_count; ++i) {
124  struct m0_idx idx;
125  struct m0_op *op = NULL;
126 
127  m0_fid_tassume(&fids->af_elems[i], &m0_dix_fid_type);
128  m0_idx_init(&idx, parent,
129  (struct m0_uint128 *)&fids->af_elems[i]);
130  rc = m0_entity_open(&idx.in_entity, &op) ?:
131  m0_entity_delete(&idx.in_entity, &op) ?:
132  index_op_tail(&idx.in_entity, op, rc, NULL);
133  }
134  return M0_RC(rc);
135 }
136 
137 int index_list(struct m0_realm *parent,
138  struct m0_fid *fid,
139  int cnt,
140  struct m0_bufvec *keys)
141 {
142  struct m0_idx idx;
143  struct m0_op *op = NULL;
144  int32_t *rcs;
145  int rc;
146 
147  M0_PRE(cnt != 0);
148  M0_PRE(fid != NULL);
149  M0_ALLOC_ARR(rcs, cnt);
150  rc = m0_bufvec_alloc(keys, cnt, sizeof(struct m0_fid));
151  if (rc != 0 || rcs == NULL) {
152  m0_free(rcs);
153  return M0_ERR(rc);
154  }
156  m0_idx_init(&idx, parent, (struct m0_uint128 *)fid);
157  rc = m0_idx_op(&idx, M0_IC_LIST, keys, NULL,
158  rcs, 0, &op);
159  rc = index_op_tail(&idx.in_entity, op, rc, NULL);
160  m0_free(rcs);
161  return M0_RC(rc);
162 }
163 
164 int index_lookup(struct m0_realm *parent,
165  struct m0_fid_arr *fids,
166  struct m0_bufvec *rets)
167 {
168  int i;
169  int rc = 0;
170 
171  M0_PRE(fids != NULL);
172  M0_PRE(fids->af_count != 0);
173  M0_PRE(rets != NULL);
174  M0_PRE(rets->ov_vec.v_nr == 0);
175 
176  rc = m0_bufvec_alloc(rets, fids->af_count, sizeof(rc));
177  /* Check that indices exist. */
178  for(i = 0; rc == 0 && i < fids->af_count; ++i) {
179  struct m0_idx idx;
180  struct m0_op *op = NULL;
181 
182  m0_fid_tassume(&fids->af_elems[i], &m0_dix_fid_type);
183  m0_idx_init(&idx, parent,
184  (struct m0_uint128 *)&fids->af_elems[i]);
185  rc = m0_idx_op(&idx, M0_IC_LOOKUP, NULL, NULL,
186  NULL, 0, &op);
187  rc = index_op_tail(&idx.in_entity, op, rc,
188  (int *)rets->ov_buf[i]);
189  }
190  return M0_RC(rc);
191 }
192 
193 static int index_op(struct m0_realm *parent,
194  struct m0_fid *fid,
195  enum m0_idx_opcode opcode,
196  struct m0_bufvec *keys,
197  struct m0_bufvec *vals)
198 {
199  struct m0_idx idx = {};
200  struct m0_op *op = NULL;
201  int32_t *rcs;
202  int rc;
203 
204  M0_ASSERT(keys != NULL);
205  M0_ASSERT(keys->ov_vec.v_nr != 0);
206  M0_ALLOC_ARR(rcs, keys->ov_vec.v_nr);
207  if (rcs == NULL)
208  return M0_ERR(-ENOMEM);
209 
211  m0_idx_init(&idx, parent, (struct m0_uint128 *)fid);
212 
213  if (is_enf_meta) {
215  set_enf_meta_flag(&idx);
216  else
217  return M0_ERR(-EINVAL);
218  } else if (m0_fid_is_set(&dix_pool_ver)) {
219  return M0_ERR(-EINVAL);
220  }
221 
222  rc = m0_idx_op(&idx, opcode, keys, vals, rcs,
224  &op);
225  rc = index_op_tail(&idx.in_entity, op, rc, NULL);
226  /*
227  * Don't analyse per-item codes for NEXT, because usually user gets
228  * -ENOENT in 'rcs' since he requests more entries than exist.
229  */
230  if (opcode != M0_IC_NEXT)
231  rc = per_item_rcs_analyse(rcs, keys->ov_vec.v_nr);
232  m0_free(rcs);
233  return M0_RC(rc);
234 }
235 
236 int index_put(struct m0_realm *parent,
237  struct m0_fid_arr *fids,
238  struct m0_bufvec *keys,
239  struct m0_bufvec *vals)
240 {
241  int rc = 0;
242  int i;
243 
244  M0_PRE(fids != NULL && fids->af_count != 0);
245  M0_PRE(keys != NULL);
246  M0_PRE(vals != NULL);
247 
248  for (i = 0; i < fids->af_count && rc == 0; i++)
249  rc = index_op(parent, &fids->af_elems[i],
250  M0_IC_PUT, keys, vals);
251 
252  return M0_RC(rc);
253 }
254 
255 int index_del(struct m0_realm *parent,
256  struct m0_fid_arr *fids,
257  struct m0_bufvec *keys)
258 {
259  int rc = 0;
260  int i;
261 
262  M0_PRE(fids != NULL && fids->af_count != 0);
263  M0_PRE(keys != NULL);
264 
265  for (i = 0; i < fids->af_count && rc == 0; i++)
266  rc = index_op(parent, &fids->af_elems[i],
267  M0_IC_DEL, keys, NULL);
268 
269  return M0_RC(rc);
270 }
271 
272 int index_get(struct m0_realm *parent,
273  struct m0_fid *fid,
274  struct m0_bufvec *keys,
275  struct m0_bufvec *vals)
276 {
277  int rc;
278  int keys_nr;
279 
280  M0_PRE(fid != NULL);
281  M0_PRE(keys != NULL);
282  M0_PRE(vals != NULL && vals->ov_vec.v_nr == 0);
283 
284  /* Allocate vals entity without buffers. */
285  keys_nr = keys->ov_vec.v_nr;
286  rc = m0_bufvec_empty_alloc(vals, keys_nr) ?:
287  index_op(parent, fid, M0_IC_GET, keys, vals) ?:
288  m0_exists(i, keys_nr, vals->ov_buf[i] == NULL) ?
289  M0_ERR(-ENODATA) : 0;
290 
291  return M0_RC(rc);
292 }
293 
294 int index_next(struct m0_realm *parent,
295  struct m0_fid *fid,
296  struct m0_bufvec *keys,
297  int cnt,
298  struct m0_bufvec *vals)
299 {
300  int rc;
301  void *startkey;
302  int startkey_size;
303 
304  M0_PRE(fid != NULL);
305  M0_PRE(cnt != 0);
306  M0_PRE(keys != NULL && keys->ov_vec.v_nr == 1);
307  M0_PRE(vals != NULL && vals->ov_vec.v_nr == 0);
308 
309  /* Allocate array for VALs. */
310  rc = m0_bufvec_empty_alloc(vals, cnt);
311  /* Allocate array for KEYs, reuse first buffer. */
312  if (rc == 0) {
313  startkey = m0_alloc(keys->ov_vec.v_count[0]);
314  if (startkey == NULL)
315  goto fail;
316  startkey_size = keys->ov_vec.v_count[0];
317  memcpy(startkey, keys->ov_buf[0], keys->ov_vec.v_count[0]);
318  m0_bufvec_free(keys);
319  rc = m0_bufvec_empty_alloc(keys, cnt);
320  if (rc != 0)
321  goto fail;
322  keys->ov_buf[0] = startkey;
323  keys->ov_vec.v_count[0] = startkey_size;
324  }
325  if (rc == 0)
326  rc = index_op(parent, fid, M0_IC_NEXT, keys, vals);
327 
328  return M0_RC(rc);
329 fail:
330  rc = M0_ERR(-ENOMEM);
331  m0_bufvec_free(vals);
332  m0_bufvec_free(keys);
333  m0_free(startkey);
334  return M0_ERR(rc);
335 }
336 
337 
338 #undef M0_TRACE_SUBSYSTEM
339 
342 /*
343  * Local variables:
344  * c-indentation-style: "K&R"
345  * c-basic-offset: 8
346  * tab-width: 8
347  * fill-column: 80
348  * scroll-step: 1
349  * End:
350  */
351 /*
352  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
353  */
int index_drop(struct m0_realm *parent, struct m0_fid_arr *fids)
Definition: index_op.c:116
struct m0_fid idx_pver
Definition: client.h:821
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
Definition: client.h:841
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:255
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:193
uint32_t idx_layout_type
Definition: client.h:819
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:848
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:294
int index_create(struct m0_realm *parent, struct m0_fid_arr *fids)
Definition: index_op.c:89
#define m0_exists(var, nr,...)
Definition: misc.h:134
#define M0_BITS(...)
Definition: misc.h:236
struct m0_idx_attr in_attr
Definition: client.h:843
int index_get(struct m0_realm *parent, struct m0_fid *fid, struct m0_bufvec *keys, struct m0_bufvec *vals)
Definition: index_op.c:272
void set_enf_meta_flag(struct m0_idx *idx)
Definition: index_op.c:78
M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
Definition: fid.c:106
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:738
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:555
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:842
int opcode
Definition: crate.c:301
int i
Definition: dir.c:1033
Definition: client.h:647
return M0_ERR(-EOPNOTSUPP)
Definition: cnt.h:36
bool is_enf_meta
Definition: cmd_main.c:65
M0_INTERNAL const struct m0_fid_type m0_dix_fid_type
Definition: cas.c:169
#define M0_ASSERT(cond)
void m0_op_launch(struct m0_op **op, uint32_t nr)
Definition: client.c:724
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:236
Definition: fid.h:43
uint64_t f_container
Definition: fid.h:39
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:164
#define FID_P(f)
Definition: fid.h:77
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:137
int m0_entity_delete(struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:824
uint32_t en_flags
Definition: client.h:744
void m0_op_free(struct m0_op *op)
Definition: client.c:886
int m0_entity_open(struct m0_entity *entity, struct m0_op **op)
Definition: obj.c:885
M0_INTERNAL bool m0_fid_is_valid(const struct m0_fid *fid)
Definition: fid.c:96
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:627
struct m0_fid dix_pool_ver
Definition: crate_index.c:31
#define FID_F
Definition: fid.h:75
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