Motr  M0
list_enum.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  *
19  */
20 
21 
30 #include "lib/errno.h"
31 #include "lib/vec.h"
32 #include "lib/memory.h"
33 #include "lib/misc.h" /* m0_forall() */
34 #include "lib/bob.h"
35 #include "lib/finject.h"
36 
37 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_LAYOUT
38 #include "lib/trace.h"
39 
40 #include "motr/magic.h"
41 #include "fid/fid.h" /* m0_fid_is_valid() */
42 #include "layout/layout_internal.h"
43 #include "layout/list_enum.h"
44 
45 static const struct m0_bob_type list_bob = {
46  .bt_name = "list_enum",
47  .bt_magix_offset = offsetof(struct m0_layout_list_enum, lle_magic),
48  .bt_magix = M0_LAYOUT_LIST_ENUM_MAGIC,
49  .bt_check = NULL
50 };
51 
53 
56  struct m0_table lsd_cob_lists;
57 };
58 
64 struct cob_lists_key {
66  uint64_t clk_lid;
67 
69  uint32_t clk_cob_index;
70 
72  uint32_t clk_pad;
73 };
74 
75 struct cob_lists_rec {
78 };
79 
84 static int lcl_key_cmp(struct m0_table *table,
85  const void *key0, const void *key1)
86 {
87  const struct cob_lists_key *k0 = key0;
88  const struct cob_lists_key *k1 = key1;
89 
90  return M0_3WAY(k0->clk_lid, k1->clk_lid) ?:
91  M0_3WAY(k0->clk_cob_index, k1->clk_cob_index);
92 }
93 
95 static const struct m0_table_ops cob_lists_table_ops = {
96  .to = {
97  [TO_KEY] = {
98  .max_size = sizeof(struct cob_lists_key)
99  },
100  [TO_REC] = {
101  .max_size = sizeof(struct cob_lists_rec)
102  }
103  },
104  .key_cmp = lcl_key_cmp
105 };
106 
107 static bool list_allocated_invariant(const struct m0_layout_list_enum *le)
108 {
109  return
110  m0_layout_list_enum_bob_check(le) &&
111  le->lle_nr == 0 &&
112  le->lle_list_of_cobs == NULL;
113 }
114 
115 static bool list_invariant(const struct m0_layout_list_enum *le)
116 {
117  return
118  m0_layout_list_enum_bob_check(le) &&
119  le->lle_nr != 0 &&
120  le->lle_list_of_cobs != NULL &&
121  m0_forall(i, le->lle_nr,
124 }
125 
126 static const struct m0_layout_enum_ops list_enum_ops;
127 
129 static int list_allocate(struct m0_layout_domain *dom,
130  struct m0_layout_enum **out)
131 {
132  struct m0_layout_list_enum *list_enum;
133 
135  M0_PRE(out != NULL);
136 
137  M0_ENTRY();
138 
139  if (M0_FI_ENABLED("mem_err")) { list_enum = NULL; goto err1_injected; }
140  M0_ALLOC_PTR(list_enum);
141 err1_injected:
142  if (list_enum == NULL) {
143  m0_layout__log("list_allocate", "M0_ALLOC_PTR() failed",
144  LID_NONE, -ENOMEM);
145  return M0_ERR(-ENOMEM);
146  }
147  m0_layout__enum_init(dom, &list_enum->lle_base,
149  m0_layout_list_enum_bob_init(list_enum);
150  M0_POST(list_allocated_invariant(list_enum));
151  *out = &list_enum->lle_base;
152  M0_LEAVE("list enum pointer %p", list_enum);
153  return 0;
154 }
155 
157 static void list_delete(struct m0_layout_enum *e)
158 {
159  struct m0_layout_list_enum *list_enum;
160 
161  list_enum = bob_of(e, struct m0_layout_list_enum,
162  lle_base, &list_bob);
163  M0_PRE(list_allocated_invariant(list_enum));
164 
165  M0_ENTRY("enum_pointer %p", e);
166  m0_layout_list_enum_bob_fini(list_enum);
167  m0_layout__enum_fini(&list_enum->lle_base);
168  m0_free(list_enum);
169  M0_LEAVE();
170 }
171 
172 /* Populates the allocated list enum object using the supplied arguemnts. */
173 static int list_populate(struct m0_layout_list_enum *list_enum,
174  struct m0_fid *cob_list, uint32_t nr)
175 {
176  M0_PRE(list_allocated_invariant(list_enum));
177  M0_PRE(cob_list != NULL);
178 
179  if (nr == 0) {
181  "list_enum %p, Invalid attributes (nr = 0), rc %d",
182  list_enum, -EPROTO);
183  return M0_ERR(-EPROTO);
184  }
185  list_enum->lle_nr = nr;
186  list_enum->lle_list_of_cobs = cob_list;
187  M0_POST(list_invariant(list_enum));
188  return 0;
189 }
190 
191 M0_INTERNAL int m0_list_enum_build(struct m0_layout_domain *dom,
192  struct m0_fid *cob_list, uint32_t nr,
193  struct m0_layout_list_enum **out)
194 {
195  struct m0_layout_enum *e;
196  struct m0_layout_list_enum *list_enum;
197  uint32_t i;
198  int rc;
199 
200  M0_PRE(out != NULL);
201 
202  M0_ENTRY("domain %p", dom);
203  if (M0_FI_ENABLED("fid_invalid_err")) { goto err1_injected; }
204  for (i = 0; i < nr; ++i) {
205  if (!m0_fid_is_valid(&cob_list[i])) {
206 err1_injected:
207  m0_layout__log("m0_list_enum_build", "fid invalid",
208  LID_NONE, -EPROTO);
209  return M0_ERR(-EPROTO);
210  }
211  }
212 
213  rc = list_allocate(dom, &e);
214  if (rc == 0) {
215  list_enum = bob_of(e, struct m0_layout_list_enum,
216  lle_base, &list_bob);
217  rc = list_populate(list_enum, cob_list, nr);
218  if (rc == 0)
219  *out = list_enum;
220  else
221  list_delete(e);
222  }
223  M0_POST(ergo(rc == 0, list_invariant(*out)));
224  M0_LEAVE("domain %p, rc %d", dom, rc);
225  return M0_RC(rc);
226 }
227 
228 static struct m0_layout_list_enum
230 {
231  struct m0_layout_list_enum *list_enum;
232 
233  list_enum = bob_of(e, struct m0_layout_list_enum,
234  lle_base, &list_bob);
235  M0_ASSERT(list_invariant(list_enum));
236  return list_enum;
237 }
238 
240 static void list_fini(struct m0_layout_enum *e)
241 {
242  struct m0_layout_list_enum *list_enum;
243  uint64_t lid;
244 
246 
247  lid = e->le_sl_is_set ? e->le_sl->sl_base.l_id : 0;
248  M0_ENTRY("lid %llu, enum_pointer %p", (unsigned long long)lid, e);
249  list_enum = enum_to_list_enum(e);
250  m0_layout_list_enum_bob_fini(list_enum);
251  m0_layout__enum_fini(&list_enum->lle_base);
252  m0_free(list_enum->lle_list_of_cobs);
253  m0_free(list_enum);
254  M0_LEAVE();
255 }
256 
258 static int list_register(struct m0_layout_domain *dom,
259  const struct m0_layout_enum_type *et)
260 {
261  struct list_schema_data *lsd;
262  int rc;
263 
265  M0_PRE(et != NULL);
266  M0_PRE(IS_IN_ARRAY(et->let_id, dom->ld_enum));
267  M0_PRE(dom->ld_type_data[et->let_id] == NULL);
268 
269  M0_ENTRY("Enum_type_id %lu", (unsigned long)et->let_id);
270 
271  if (M0_FI_ENABLED("mem_err")) { lsd = NULL; goto err1_injected; }
272  M0_ALLOC_PTR(lsd);
273 err1_injected:
274  if (lsd == NULL) {
275  m0_layout__log("list_register", "M0_ALLOC_PTR() failed",
276  LID_NONE, -ENOMEM);
277  return M0_ERR(-ENOMEM);
278  }
279 
280  if (M0_FI_ENABLED("table_init_err"))
281  { rc = -EEXIST; goto err2_injected; }
282  rc = m0_table_init(&lsd->lsd_cob_lists, dom->ld_dbenv,
283  "cob_lists", DEFAULT_DB_FLAG, &cob_lists_table_ops);
284 err2_injected:
285  if (rc == 0)
286  dom->ld_type_data[et->let_id] = lsd;
287  else {
288  m0_layout__log("list_register", "m0_table_init() failed",
289  LID_NONE, rc);
290  m0_free(lsd);
291  }
292  M0_LEAVE("Enum_type_id %lu, rc %d", (unsigned long)et->let_id, rc);
293  return M0_RC(rc);
294 }
295 
298  const struct m0_layout_enum_type *et)
299 {
300  struct list_schema_data *lsd;
301 
303  M0_PRE(et != NULL);
304 
305  M0_ENTRY("Enum_type_id %lu", (unsigned long)et->let_id);
306  lsd = dom->ld_type_data[et->let_id];
307  m0_table_fini(&lsd->lsd_cob_lists);
308  dom->ld_type_data[et->let_id] = NULL;
309  m0_free(lsd);
310  M0_LEAVE("Enum_type_id %lu", (unsigned long)et->let_id);
311 }
312 
315 {
316  return sizeof(struct cob_entries_header) +
317  LDB_MAX_INLINE_COB_ENTRIES *sizeof(struct m0_fid);
318 }
319 
320 static int noninline_read(struct m0_fid *cob_list,
321  struct m0_striped_layout *stl,
322  struct m0_db_tx *tx,
323  uint32_t idx_start,
324  uint32_t idx_end)
325 {
326  struct list_schema_data *lsd;
327  struct cob_lists_key key;
328  struct cob_lists_rec rec;
329  struct m0_db_pair pair;
330  struct m0_db_cursor cursor;
331  uint32_t i;
332  int rc;
333 
334  M0_ENTRY("lid %llu, idx_start %lu, idx_end %lu",
335  (unsigned long long)stl->sl_base.l_id,
336  (unsigned long)idx_start,
337  (unsigned long)idx_end);
339  M0_ASSERT(lsd != NULL);
340 
341  if (M0_FI_ENABLED("cursor_init_err"))
342  { rc = -ENOENT; goto err1_injected; }
343  rc = m0_db_cursor_init(&cursor, &lsd->lsd_cob_lists, tx, 0);
344 err1_injected:
345  if (rc != 0) {
346  m0_layout__log("noninline_read",
347  "m0_db_cursor_init() failed",
348  stl->sl_base.l_id, rc);
349  return M0_RC(rc);
350  }
351 
352  key.clk_lid = stl->sl_base.l_id;
353  key.clk_cob_index = idx_start;
354  m0_db_pair_setup(&pair, &lsd->lsd_cob_lists,
355  &key, sizeof key, &rec, sizeof rec);
356  for (i = idx_start; i < idx_end; ++i) {
357  if (M0_FI_ENABLED("cursor_get_err"))
358  { rc = -ENOMEM; goto err2_injected; }
359  if (i == idx_start)
360  rc = m0_db_cursor_get(&cursor, &pair);
361  else
362  rc = m0_db_cursor_next(&cursor, &pair);
363 err2_injected:
364  if (rc != 0) {
365  m0_layout__log("noninline_read",
366  "m0_db_cursor_get() failed",
367  key.clk_lid, rc);
368  goto out;
369  }
370 
371  if (M0_FI_ENABLED("invalid_fid_err")) { goto err3_injected; }
372  if (!m0_fid_is_valid(&rec.clr_cob_id)) {
373 err3_injected:
374  rc = -EPROTO;
375  m0_layout__log("noninline_read",
376  "fid invalid", key.clk_lid, rc);
377  goto out;
378  }
379  cob_list[i] = rec.clr_cob_id;
380  }
381 out:
382  m0_db_pair_fini(&pair);
383  m0_db_cursor_fini(&cursor);
384  M0_LEAVE("lid %llu, rc %d", (unsigned long long)stl->sl_base.l_id, rc);
385  return M0_RC(rc);
386 }
387 
389 static int list_decode(struct m0_layout_enum *e,
390  struct m0_bufvec_cursor *cur,
391  enum m0_layout_xcode_op op,
392  struct m0_db_tx *tx,
393  struct m0_striped_layout *stl)
394 {
395  uint64_t lid;
396  struct m0_layout_list_enum *list_enum;
397  struct cob_entries_header *ce_header;
398  /* Number of cobs to be read from the buffer. */
399  uint32_t num_inline;
400  struct m0_fid *cob_id;
401  struct m0_fid *cob_list;
402  uint32_t i;
403  int rc;
404 
405  M0_PRE(e != NULL);
406  M0_PRE(cur != NULL);
407  M0_PRE(m0_bufvec_cursor_step(cur) >= sizeof *ce_header);
409  M0_PRE(ergo(op == M0_LXO_DB_LOOKUP, tx != NULL));
411 
412  lid = stl->sl_base.l_id;
413  ce_header = m0_bufvec_cursor_addr(cur);
414  m0_bufvec_cursor_move(cur, sizeof *ce_header);
415  M0_ENTRY("lid %llu, nr %lu", (unsigned long long)lid,
416  (unsigned long)ce_header->ces_nr);
417  list_enum = bob_of(e, struct m0_layout_list_enum,
418  lle_base, &list_bob);
420 
421  if (M0_FI_ENABLED("mem_err")) { cob_list = NULL; goto err1_injected; }
422  M0_ALLOC_ARR(cob_list, ce_header->ces_nr);
423 err1_injected:
424  if (cob_list == NULL) {
425  rc = -ENOMEM;
426  m0_layout__log("list_decode", "M0_ALLOC_ARR() failed",
427  lid, rc);
428  goto out;
429  }
430  rc = 0;
431  num_inline = op == M0_LXO_BUFFER_OP ? ce_header->ces_nr :
432  min_check(ce_header->ces_nr,
433  (uint32_t)LDB_MAX_INLINE_COB_ENTRIES);
434  M0_ASSERT(m0_bufvec_cursor_step(cur) >= num_inline * sizeof *cob_id);
435 
436  M0_LOG(M0_DEBUG, "lid %llu, nr %lu, Start reading inline entries",
437  (unsigned long long)lid, (unsigned long)ce_header->ces_nr);
438  for (i = 0; i < num_inline; ++i) {
439  cob_id = m0_bufvec_cursor_addr(cur);
440  m0_bufvec_cursor_move(cur, sizeof *cob_id);
441 
442  if (M0_FI_ENABLED("fid_invalid_err")) { goto err2_injected; }
443  if (!m0_fid_is_valid(cob_id)) {
444 err2_injected:
445  rc = -EPROTO;
446  M0_LOG(M0_WARN, "fid invalid, i %lu", (unsigned long)i);
447  goto out;
448  }
449  cob_list[i] = *cob_id;
450  }
451 
452  if (ce_header->ces_nr > num_inline) {
455  "lid %llu, nr %lu, Start reading noninline entries",
456  (unsigned long long)lid,
457  (unsigned long)ce_header->ces_nr);
458  rc = noninline_read(cob_list, stl, tx, i, ce_header->ces_nr);
459  if (rc != 0) {
460  M0_LOG(M0_ERROR, "noninline_read() failed");
461  goto out;
462  }
463  }
464 
465  if (M0_FI_ENABLED("attr_err")) { ce_header->ces_nr = 0; }
466  rc = list_populate(list_enum, cob_list, ce_header->ces_nr);
467  if (rc != 0)
468  M0_LOG(M0_ERROR, "list_populate() failed");
469 out:
470  if (rc != 0)
471  m0_free(cob_list);
472  M0_POST(ergo(rc == 0, list_invariant(list_enum)));
473  M0_POST(ergo(rc != 0, list_allocated_invariant(list_enum)));
474  M0_LEAVE("lid %llu, rc %d", (unsigned long long)lid, rc);
475  return M0_RC(rc);
476 }
477 
478 static int noninline_write(const struct m0_layout_enum *e,
479  struct m0_db_tx *tx,
480  enum m0_layout_xcode_op op,
481  uint32_t idx_start)
482 {
483  struct m0_layout_list_enum *list_enum;
484  struct m0_fid *cob_list;
485  struct list_schema_data *lsd;
486  struct m0_db_cursor cursor;
487  struct cob_lists_key key;
488  struct cob_lists_rec rec;
489  struct m0_db_pair pair;
490  uint32_t i;
491  int rc;
492 
494 
495  list_enum = enum_to_list_enum(e);
496  M0_ENTRY("lid %llu, idx_start %lu, idx_end %lu",
497  (unsigned long long)e->le_sl->sl_base.l_id,
498  (unsigned long)idx_start,
499  (unsigned long)list_enum->lle_nr);
500  cob_list = list_enum->lle_list_of_cobs;
502  M0_ASSERT(lsd != NULL);
503 
504  if (M0_FI_ENABLED("cursor_init_err"))
505  { rc = -ENOENT; goto err1_injected; }
506  rc = m0_db_cursor_init(&cursor, &lsd->lsd_cob_lists, tx,
507  M0_DB_CURSOR_RMW);
508 err1_injected:
509  if (rc != 0) {
510  m0_layout__log("noninline_write",
511  "m0_db_cursor_init() failed",
512  (unsigned long long)e->le_sl->sl_base.l_id, rc);
513  return M0_RC(rc);
514  }
515 
516  key.clk_lid = e->le_sl->sl_base.l_id;
517  for (i = idx_start; i < list_enum->lle_nr; ++i) {
518  M0_ASSERT(m0_fid_is_valid(&cob_list[i]));
519  key.clk_cob_index = i;
520  m0_db_pair_setup(&pair, &lsd->lsd_cob_lists,
521  &key, sizeof key, &rec, sizeof rec);
522 
523  if (op == M0_LXO_DB_ADD) {
524  rec.clr_cob_id = cob_list[i];
525 
526  if (M0_FI_ENABLED("cursor_add_err"))
527  { rc = -ENOENT; goto err2_injected; }
528  rc = m0_db_cursor_add(&cursor, &pair);
529 err2_injected:
530  if (rc != 0) {
531  m0_layout__log("noninline_write",
532  "m0_db_cursor_add() failed",
533  key.clk_lid, rc);
534  goto out;
535  }
536  } else if (op == M0_LXO_DB_DELETE) {
537  if (M0_FI_ENABLED("cursor_get_err"))
538  { rc = -ENOENT; goto err3_injected; }
539  if (i == idx_start)
540  rc = m0_db_cursor_get(&cursor, &pair);
541  else
542  rc = m0_db_cursor_next(&cursor, &pair);
543 err3_injected:
544  if (rc != 0) {
545  m0_layout__log("noninline_write",
546  "m0_db_cursor_get() failed",
547  key.clk_lid, rc);
548  goto out;
549  }
550  M0_ASSERT(m0_fid_eq(&rec.clr_cob_id, &cob_list[i]));
551 
552  if (M0_FI_ENABLED("cursor_del_err"))
553  { rc = -ENOMEM; goto err4_injected; }
554  rc = m0_db_cursor_del(&cursor);
555 err4_injected:
556  if (rc != 0) {
557  m0_layout__log("noninline_write",
558  "m0_db_cursor_del() failed",
559  key.clk_lid, rc);
560  goto out;
561  }
562  }
563  }
564 out:
565  m0_db_pair_fini(&pair);
566  m0_db_cursor_fini(&cursor);
567  M0_LEAVE("lid %llu, rc %d",
568  (unsigned long long)e->le_sl->sl_base.l_id, rc);
569  return M0_RC(rc);
570 }
571 
573 static int list_encode(const struct m0_layout_enum *e,
574  enum m0_layout_xcode_op op,
575  struct m0_db_tx *tx,
576  struct m0_bufvec_cursor *out)
577 {
578  struct m0_layout_list_enum *list_enum;
579  /* Number of cobs to be written to the buffer. */
580  uint32_t num_inline;
581  struct cob_entries_header ce_header;
582  m0_bcount_t nbytes;
583  uint64_t lid;
584  uint32_t i;
585  int rc;
586 
587  M0_PRE(e != NULL);
590  M0_PRE(ergo(op != M0_LXO_BUFFER_OP, tx != NULL));
591  M0_PRE(out != NULL);
592  M0_PRE(m0_bufvec_cursor_step(out) >= sizeof ce_header);
593 
594  list_enum = enum_to_list_enum(e);
595  lid = e->le_sl->sl_base.l_id;
596  M0_ENTRY("lid %llu, nr %lu", (unsigned long long)lid,
597  (unsigned long)list_enum->lle_nr);
598 
599  ce_header.ces_nr = list_enum->lle_nr;
600  nbytes = m0_bufvec_cursor_copyto(out, &ce_header, sizeof ce_header);
601  M0_ASSERT(nbytes == sizeof ce_header);
602 
603  num_inline = op == M0_LXO_BUFFER_OP ? list_enum->lle_nr :
604  min_check(list_enum->lle_nr,
605  (uint32_t)LDB_MAX_INLINE_COB_ENTRIES);
606 
607  M0_ASSERT(m0_bufvec_cursor_step(out) >= num_inline *
608  sizeof list_enum->lle_list_of_cobs[0]);
609 
610  M0_LOG(M0_DEBUG, "lid %llu, nr %lu, Start accepting inline entries",
611  (unsigned long long)lid, (unsigned long)list_enum->lle_nr);
612  for (i = 0; i < num_inline; ++i) {
613  nbytes = m0_bufvec_cursor_copyto(out,
614  &list_enum->lle_list_of_cobs[i],
615  sizeof list_enum->lle_list_of_cobs[i]);
616  M0_ASSERT(nbytes == sizeof list_enum->lle_list_of_cobs[i]);
617  }
618 
619  rc = 0;
620  /*
621  * The auxiliary table viz. cob_lists is not to be modified for an
622  * update operation.
623  */
624  if (list_enum->lle_nr > num_inline && op != M0_LXO_DB_UPDATE) {
627  "lid %llu, nr %lu, Start writing noninline entries",
628  (unsigned long long)lid,
629  (unsigned long)list_enum->lle_nr);
630  rc = noninline_write(e, tx, op, i);
631  if (rc != 0)
632  M0_LOG(M0_ERROR, "noninline_write() failed");
633  }
634 
635  M0_LEAVE("lid %llu, rc %d", (unsigned long long)lid, rc);
636  return M0_RC(rc);
637 }
638 
640 static uint32_t list_nr(const struct m0_layout_enum *e)
641 {
642  struct m0_layout_list_enum *list_enum;
643 
644  M0_PRE(e != NULL);
645 
646  M0_ENTRY("lid %llu, enum_pointer %p",
647  (unsigned long long)e->le_sl->sl_base.l_id, e);
648  list_enum = enum_to_list_enum(e);
649  M0_LEAVE("lid %llu, enum_pointer %p, nr %lu",
650  (unsigned long long)e->le_sl->sl_base.l_id, e,
651  (unsigned long)list_enum->lle_nr);
652  return list_enum->lle_nr;
653 }
654 
656 static void list_get(const struct m0_layout_enum *e, uint32_t idx,
657  const struct m0_fid *gfid, struct m0_fid *out)
658 {
659  struct m0_layout_list_enum *list_enum;
660 
661  M0_PRE(e != NULL);
662  /* gfid is ignored for the list enumeration type. */
663  M0_PRE(out != NULL);
664 
665  M0_ENTRY("lid %llu, enum_pointer %p",
666  (unsigned long long)e->le_sl->sl_base.l_id, e);
667  list_enum = enum_to_list_enum(e);
668  M0_PRE(idx < list_enum->lle_nr);
669  M0_ASSERT(m0_fid_is_valid(&list_enum->lle_list_of_cobs[idx]));
670  *out = list_enum->lle_list_of_cobs[idx];
671  M0_LEAVE("lid %llu, enum_pointer %p, fid_pointer %p",
672  (unsigned long long)e->le_sl->sl_base.l_id, e, out);
673 }
674 
677 {
678  struct m0_layout_list_enum *list_enum;
679 
680  M0_PRE(e != NULL);
681 
682  list_enum = enum_to_list_enum(e);
683  return sizeof(struct cob_entries_header) +
685  list_enum->lle_nr) *
686  sizeof(struct m0_fid);
687 }
688 
689 static const struct m0_layout_enum_ops list_enum_ops = {
690  .leo_nr = list_nr,
691  .leo_get = list_get,
692  .leo_recsize = list_recsize,
693  .leo_fini = list_fini,
694  .leo_delete = list_delete,
695  .leo_decode = list_decode,
696  .leo_encode = list_encode
697 };
698 
699 static const struct m0_layout_enum_type_ops list_type_ops = {
701  .leto_unregister = list_unregister,
702  .leto_max_recsize = list_max_recsize,
703  .leto_allocate = list_allocate
704 };
705 
707  .let_name = "list",
708  .let_id = 0,
709  .let_ref_count = 0,
710  .let_ops = &list_type_ops
711 };
712 
713 #undef M0_TRACE_SUBSYSTEM
714 
717 /*
718  * Local variables:
719  * c-indentation-style: "K&R"
720  * c-basic-offset: 8
721  * tab-width: 8
722  * fill-column: 80
723  * scroll-step: 1
724  * End:
725  */
int(* leto_register)(struct m0_layout_domain *dom, const struct m0_layout_enum_type *et)
Definition: layout.h:548
static size_t nr
Definition: dump.c:1505
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
static struct m0_layout_list_enum * enum_to_list_enum(const struct m0_layout_enum *e)
Definition: list_enum.c:229
static int list_encode(const struct m0_layout_enum *e, enum m0_layout_xcode_op op, struct m0_db_tx *tx, struct m0_bufvec_cursor *out)
Definition: list_enum.c:573
static int lcl_key_cmp(struct m0_table *table, const void *key0, const void *key1)
Definition: list_enum.c:84
static const uint64_t k1
Definition: hash_fnc.c:34
static void list_fini(struct m0_layout_enum *e)
Definition: list_enum.c:240
#define NULL
Definition: misc.h:38
struct m0_table lsd_cob_lists
Definition: list_enum.c:56
static struct buffer * cur(struct m0_addb2_mach *mach, m0_bcount_t space)
Definition: addb2.c:791
static int noninline_write(const struct m0_layout_enum *e, struct m0_db_tx *tx, enum m0_layout_xcode_op op, uint32_t idx_start)
Definition: list_enum.c:478
#define ergo(a, b)
Definition: misc.h:293
#define M0_3WAY(v0, v1)
Definition: arith.h:199
static int noninline_read(struct m0_fid *cob_list, struct m0_striped_layout *stl, struct m0_db_tx *tx, uint32_t idx_start, uint32_t idx_end)
Definition: list_enum.c:320
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
#define min_check(a, b)
Definition: arith.h:88
static void list_unregister(struct m0_layout_domain *dom, const struct m0_layout_enum_type *et)
Definition: list_enum.c:297
struct m0_layout_enum lle_base
Definition: list_enum.h:48
uint32_t clk_pad
Definition: list_enum.c:72
static int list_populate(struct m0_layout_list_enum *list_enum, struct m0_fid *cob_list, uint32_t nr)
Definition: list_enum.c:173
M0_INTERNAL void * m0_bufvec_cursor_addr(struct m0_bufvec_cursor *cur)
Definition: vec.c:597
uint64_t m0_bcount_t
Definition: types.h:77
M0_INTERNAL bool m0_layout__striped_allocated_invariant(const struct m0_striped_layout *stl)
Definition: layout.c:181
const char * bt_name
Definition: bob.h:73
static const struct m0_layout_enum_type_ops list_type_ops
Definition: list_enum.c:699
return M0_RC(rc)
op
Definition: libdemo.c:64
uint32_t clk_cob_index
Definition: list_enum.c:69
#define M0_ENTRY(...)
Definition: trace.h:170
static const uint64_t k0
Definition: hash_fnc.c:33
M0_INTERNAL bool m0_layout__enum_invariant(const struct m0_layout_enum *e)
Definition: layout.c:170
static int list_allocate(struct m0_layout_domain *dom, struct m0_layout_enum **out)
Definition: list_enum.c:129
M0_INTERNAL bool m0_bufvec_cursor_move(struct m0_bufvec_cursor *cur, m0_bcount_t count)
Definition: vec.c:574
int i
Definition: dir.c:1033
static void list_delete(struct m0_layout_enum *e)
Definition: list_enum.c:157
M0_INTERNAL void m0_layout__enum_fini(struct m0_layout_enum *le)
Definition: layout.c:507
return M0_ERR(-EOPNOTSUPP)
static bool list_invariant(const struct m0_layout_list_enum *le)
Definition: list_enum.c:115
static int list_register(struct m0_layout_domain *dom, const struct m0_layout_enum_type *et)
Definition: list_enum.c:258
static m0_bcount_t list_max_recsize(void)
Definition: list_enum.c:314
static int list_decode(struct m0_layout_enum *e, struct m0_bufvec_cursor *cur, enum m0_layout_xcode_op op, struct m0_db_tx *tx, struct m0_striped_layout *stl)
Definition: list_enum.c:389
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_step(const struct m0_bufvec_cursor *cur)
Definition: vec.c:581
#define M0_ASSERT(cond)
static const struct m0_layout_enum_ops list_enum_ops
Definition: list_enum.c:126
M0_INTERNAL void m0_layout__enum_init(struct m0_layout_domain *dom, struct m0_layout_enum *le, struct m0_layout_enum_type *let, const struct m0_layout_enum_ops *ops)
Definition: layout.c:480
#define bob_of(ptr, type, field, bt)
Definition: bob.h:140
static int key0
Definition: locality.c:282
static struct m0_stob_domain * dom
Definition: storage.c:38
M0_BOB_DEFINE(static, &list_bob, m0_layout_list_enum)
#define M0_POST(cond)
static uint32_t list_nr(const struct m0_layout_enum *e)
Definition: list_enum.c:640
M0_INTERNAL bool m0_layout__domain_invariant(const struct m0_layout_domain *dom)
Definition: layout.c:131
M0_INTERNAL int m0_list_enum_build(struct m0_layout_domain *dom, struct m0_fid *cob_list, uint32_t nr, struct m0_layout_list_enum **out)
Definition: list_enum.c:191
M0_INTERNAL void m0_layout__log(const char *fn_name, const char *err_msg, uint64_t lid, int rc)
Definition: layout.c:586
static const struct m0_table_ops cob_lists_table_ops
Definition: list_enum.c:95
uint32_t ces_nr
Definition: list_enum.h:98
const char * let_name
Definition: layout.h:527
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
#define m0_forall(var, nr,...)
Definition: misc.h:112
struct m0_fid clr_cob_id
Definition: list_enum.c:77
bool le_sl_is_set
Definition: layout.h:417
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
Definition: fid.h:38
uint64_t clk_lid
Definition: list_enum.c:66
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
static m0_bcount_t list_recsize(struct m0_layout_enum *e)
Definition: list_enum.c:676
static bool list_allocated_invariant(const struct m0_layout_list_enum *le)
Definition: list_enum.c:107
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_copyto(struct m0_bufvec_cursor *dcur, void *sdata, m0_bcount_t num_bytes)
Definition: vec.c:677
struct m0_layout sl_base
Definition: layout.h:574
Definition: xcode.c:1194
struct m0_striped_layout * le_sl
Definition: layout.h:420
#define IS_IN_ARRAY(idx, array)
Definition: misc.h:311
static void list_get(const struct m0_layout_enum *e, uint32_t idx, const struct m0_fid *gfid, struct m0_fid *out)
Definition: list_enum.c:656
void * ld_type_data[M0_LAYOUT_TYPE_MAX]
Definition: layout.h:205
struct m0_fid * lle_list_of_cobs
Definition: list_enum.h:61
uint32_t(* leo_nr)(const struct m0_layout_enum *e)
Definition: layout.h:431
#define out(...)
Definition: gen.c:41
struct m0_fid gfid
Definition: dir.c:626
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
struct m0_layout_domain * l_dom
Definition: layout.h:231
int32_t rc
Definition: trigger_fop.h:47
static const struct m0_bob_type list_bob
Definition: list_enum.c:45
#define offsetof(typ, memb)
Definition: misc.h:29
m0_layout_xcode_op
Definition: layout.h:161
Definition: trace.h:478
uint32_t let_id
Definition: layout.h:530
Definition: idx_mock.c:47
struct m0_layout_enum_type m0_list_enum_type
Definition: list_enum.c:706
uint64_t l_id
Definition: layout.h:225