Motr  M0
layout.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 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 #include "ut/ut.h" /* M0_UT_ASSERT */
24 #include "motr/ut/client.h"
25 
26 #include "lib/finject.h"
27 /*
28  * Including the c files so we can replace the M0_PRE asserts
29  * in order to test them.
30  */
31 #include "motr/layout.c"
32 #include "motr/composite_layout.c"
33 
34 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CLIENT
35 #include "lib/trace.h" /* M0_LOG */
36 
38 
39 static struct m0_client *dummy_instance;
40 
42 {
43  struct m0_op_layout *ol;
44 
45  M0_ALLOC_PTR(ol);
46  M0_UT_ASSERT(ol != NULL);
47  M0_SET0(ol);
48 
49  ol->ol_oc.oc_op.op_size = sizeof *ol;
50  m0_op_layout_bob_init(ol);
51  m0_ast_rc_bob_init(&ol->ol_ar);
52  m0_op_common_bob_init(&ol->ol_oc);
53  ol->ol_ops = (struct m0_op_layout_ops *)0x80000000;
54 
55  return ol;
56 }
57 
58 static void ut_m0_op_layout_free(struct m0_op_layout *ol)
59 {
60  m0_free(ol);
61 }
62 
63 static void ut_layout_op_invariant(void)
64 {
65  bool rc;
66  struct m0_op_layout *ol;
67 
68  /* Base cases. */
69  ol = ut_m0_op_layout_alloc();
70  rc = layout_op_invariant(ol);
71  M0_UT_ASSERT(rc == true);
72 
74  M0_UT_ASSERT(rc == false);
75 
76  ol->ol_oc.oc_op.op_size = sizeof *ol - 1;
77  rc = layout_op_invariant(ol);
78  M0_UT_ASSERT(rc == false);
79 
81 }
82 
83 static void ut_layout_op_init(void)
84 {
85  int rc = 0; /* required */
86  struct m0_realm realm;
87  struct m0_obj obj;
88  struct m0_client_layout layout;
89  struct m0_op *op = NULL;
90  struct m0_client *instance = NULL;
91  struct m0_uint128 id;
92 
93  /* initialise */
95  ut_realm_entity_setup(&realm, &obj.ob_entity, instance);
96  id = M0_ID_APP;
97  id.u_lo++;
98  obj.ob_entity.en_id = id;
99 
100  op = m0_alloc(sizeof(struct m0_op_layout));
101  op->op_size = sizeof(struct m0_op_layout);
102 
103  /* ADD FI here */
104  m0_fi_enable_once("m0_op_init", "fail_op_init");
105  rc = layout_op_init(&obj, &layout, M0_EO_LAYOUT_GET, op);
106  M0_UT_ASSERT(rc != 0);
107 
108  layout.ml_type = M0_LT_PDCLUST;
109  rc = layout_op_init(&obj, &layout, M0_EO_LAYOUT_GET, op);
110  M0_UT_ASSERT(rc == 0);
111  M0_UT_ASSERT(op->op_code == M0_EO_LAYOUT_GET);
112  m0_free(op);
113 
114  /* finalise */
115  m0_entity_fini(&obj.ob_entity);
116 }
117 
118 static int dummy_op_rc = 0;
119 
120 static int op_layout_dummy_launch(struct m0_op_layout *ol)
121 {
122  return dummy_op_rc;
123 }
124 
127  .olo_copy_to_app = NULL,
128  .olo_copy_from_app = NULL,
129 };
130 
131 static void ut_layout_op_cb_launch(void)
132 {
133  int op_code;
134  struct m0_client *instance = NULL;
135  struct m0_realm realm;
136  struct m0_sm_group *op_grp;
137  struct m0_sm_group *en_grp;
138  struct m0_sm_group locality_grp;
139  struct m0_entity ent;
140  struct m0_op_layout *ol;
141 
142  /* Initialise client */
143  M0_SET0(&ent);
146 
147  ol = ut_m0_op_layout_alloc();
148  ol->ol_oc.oc_op.op_entity = &ent;
150  m0_op_bob_init(&ol->ol_oc.oc_op);
151 
152  op_grp = &ol->ol_oc.oc_op.op_sm_group;
153  en_grp = &ent.en_sm_group;
154  m0_sm_group_init(op_grp);
155  m0_sm_group_init(en_grp);
156  m0_sm_group_init(&locality_grp);
157  ol->ol_sm_grp = &locality_grp;
159 
160  for (op_code = M0_EO_LAYOUT_GET;
161  op_code <= M0_EO_LAYOUT_SET; op_code++) {
162  dummy_op_rc = 0;
163  ol->ol_oc.oc_op.op_code = op_code;
165  M0_OS_INITIALISED, op_grp);
166 
167  m0_sm_group_lock(op_grp);
171  m0_sm_fini(&ol->ol_oc.oc_op.op_sm);
172  m0_sm_group_unlock(op_grp);
173  }
174 
175  /* finalise */
176  m0_sm_group_fini(&locality_grp);
177  m0_sm_group_fini(op_grp);
178 
181 }
182 
183 static void ut_layout_op_cb_free(void)
184 {
185  struct m0_op_layout *ol;
186  struct m0_realm realm;
187  struct m0_entity ent;
188  struct m0_client *instance = NULL;
189 
190  /* init */
191  M0_SET0(&ent);
194 
195  /* base cases */
196  ol = ut_m0_op_layout_alloc();
197  ol->ol_oc.oc_op.op_entity = &ent;
198  layout_op_cb_free(&ol->ol_oc);
199 
200  /* fini */
202 }
203 
204 static void ut_layout_op_cb_fini(void)
205 {
206  struct m0_op_layout *ol;
207  struct m0_realm realm;
208  struct m0_entity ent;
209  struct m0_client *instance = NULL;
210 
211  /* init */
212  M0_SET0(&ent);
215 
216  /* base cases */
217  ol = ut_m0_op_layout_alloc();
218  ol->ol_oc.oc_op.op_entity = &ent;
219  layout_op_cb_fini(&ol->ol_oc);
220 
221  /* fini */
224 }
225 
226 static void ut_m0_layout_op(void)
227 {
228  int rc = 0;
229  struct m0_op *op = NULL;
230  struct m0_obj obj;
231  struct m0_client_layout *layout;
232  struct m0_uint128 id;
233  struct m0_client *instance = NULL;
234  struct m0_realm realm;
235 
237  ut_realm_entity_setup(&realm, &obj.ob_entity, instance);
238  id = M0_ID_APP;
239  id.u_lo++;
240  obj.ob_entity.en_id = id;
241 
242  /* Base case: GET op. */
244  M0_UT_ASSERT(layout != NULL);
246  M0_UT_ASSERT(rc == 0);
247  M0_UT_ASSERT(op != NULL);
248  m0_free(op);
249  op = NULL;
250 
251  /* Base case: SET op. */
253  M0_UT_ASSERT(rc == 0);
254  M0_UT_ASSERT(op != NULL);
255  m0_free(op);
256 
257  m0_entity_fini(&obj.ob_entity);
258 }
259 
260 static void ut_m0_client_layout_alloc(void)
261 {
262  struct m0_client_layout *layout;
263 
265  M0_UT_ASSERT(layout != NULL);
266  M0_UT_ASSERT(layout->ml_type == M0_LT_PDCLUST);
268  m0_client_layout_free(layout);
269 
271  M0_UT_ASSERT(layout != NULL);
272  M0_UT_ASSERT(layout->ml_type == M0_LT_CAPTURE);
274  m0_client_layout_free(layout);
275 
277  M0_UT_ASSERT(layout != NULL);
280  m0_client_layout_free(layout);
281 }
282 
283 static void ut_m0_layout_capture(void)
284 {
285  int rc = 0;
286  struct m0_obj obj;
287  struct m0_client_layout *layout;
288  struct m0_client_layout *orig_layout;
289  struct m0_client_pdclust_layout *pdlayout;
290  struct m0_capture_layout *cap_layout;
291  struct m0_uint128 id;
292  struct m0_client *instance = NULL;
293  struct m0_realm realm;
294 
296  ut_realm_entity_setup(&realm, &obj.ob_entity, instance);
297  id = M0_ID_APP;
298  id.u_lo++;
299  obj.ob_entity.en_id = id;
300  obj.ob_attr.oa_layout_id = 12;
301  obj.ob_attr.oa_pver = (struct m0_fid){.f_container = 24, .f_key = 36};
302 
303  orig_layout = m0_client_layout_alloc(M0_LT_PDCLUST);
304  M0_UT_ASSERT(orig_layout != NULL);
305  pdlayout = M0_AMB(pdlayout, orig_layout, pl_layout);
306  pdlayout->pl_pver = obj.ob_attr.oa_pver;
307  pdlayout->pl_lid = obj.ob_attr.oa_layout_id;
308 
309  rc = m0_client_layout_capture(orig_layout, &obj, &layout);
310  M0_UT_ASSERT(rc == 0);
311  M0_UT_ASSERT(layout != NULL);
312  cap_layout = M0_AMB(cap_layout, layout, cl_layout);
313  M0_UT_ASSERT(m0_fid_eq(&cap_layout->cl_pver, &pdlayout->pl_pver));
314  M0_UT_ASSERT(cap_layout->cl_lid == pdlayout->pl_lid);
315  M0_UT_ASSERT(m0_uint128_eq(&cap_layout->cl_orig_id, &obj.ob_entity.en_id));
316 
317  m0_client_layout_free(orig_layout);
318  m0_client_layout_free(layout);
319  m0_entity_fini(&obj.ob_entity);
320 }
321 
326 {
327  int i;
328  int rc;
329  int nr_subobjs;
330  struct m0_op *op;
331  struct m0_op_composite_io *oci;
332  struct composite_sub_io *sio_arr;
333  struct composite_sub_io_ext *sio_ext;
334  struct m0_obj obj;
335  struct m0_uint128 id;
337  struct m0_realm realm;
338 
339  ut_realm_entity_setup(&realm, &obj.ob_entity, instance);
340  id = M0_ID_APP;
341  id.u_lo++;
342  obj.ob_entity.en_id = id;
343  obj.ob_attr.oa_pver = (struct m0_fid){.f_container = 24, .f_key = 36};
344 
345  M0_ALLOC_PTR(oci);
346  M0_UT_ASSERT(oci != NULL);
347  M0_SET0(oci);
348  op = &oci->oci_oo.oo_oc.oc_op;
349 
350  oci->oci_oo.oo_oc.oc_op.op_size = sizeof *oci;
351  m0_op_common_bob_init(&oci->oci_oo.oo_oc);
352  m0_op_obj_bob_init(&oci->oci_oo);
353  m0_op_composite_io_bob_init(oci);
355 
356  m0_sm_group_init(&op->op_sm_group);
357  m0_sm_init(&op->op_sm, &m0_op_conf,
358  M0_OS_INITIALISED, &op->op_sm_group);
359 
360  nr_subobjs = 3;
361  M0_ALLOC_ARR(sio_arr, nr_subobjs);
362  for (i = 0; i < nr_subobjs; i++) {
363  id.u_lo++;
364  sio_arr[i].si_id = id;
365  sio_arr[i].si_lid = 1;
366  sio_arr[i].si_nr_exts = 1;
367  sio_ext_tlist_init(&sio_arr[i].si_exts);
368 
369  M0_ALLOC_PTR(sio_ext);
370  M0_UT_ASSERT(sio_ext != NULL);
371  sio_ext->sie_off = i * 4096;
372  sio_ext->sie_len = 4096;
373  sio_ext_tlink_init_at(sio_ext, &sio_arr[i].si_exts);
374  }
375 
376  m0_fi_enable("m0__obj_attr_get_sync", "obj_attr_get_ok");
377  m0_fi_enable("m0_obj_op", "fake_op");
378  rc = composite_sub_io_ops_build(&obj, op, sio_arr, nr_subobjs);
379  M0_UT_ASSERT(rc == 0);
380  M0_UT_ASSERT(oci->oci_sub_ops != NULL);
381  M0_UT_ASSERT(oci->oci_nr_sub_ops == nr_subobjs);
382  m0_fi_disable("m0__obj_attr_get_sync", "obj_attr_get_ok");
383  m0_fi_disable("m0_obj_op", "fake_op");
384 
385  /* Free sio array. */
386  composite_sub_io_destroy(sio_arr, nr_subobjs);
387 
388  return oci;
389 }
390 
392 {
394  m0_free(oci->oci_sub_ops);
395  m0_free(oci);
396 }
397 
399 {
400  struct m0_realm realm;
401  struct m0_client *instance = NULL;
402  struct m0_sm_group *op_grp;
403  struct m0_sm_group *en_grp;
404  struct m0_sm_group locality_grp;
405  struct m0_op_composite_io *oci;
406  struct m0_entity ent;
407 
408  /* Initialise client */
409  M0_SET0(&ent);
412 
413  m0_fi_enable("m0_op_failed", "skip_ongoing_io_ref");
414  oci = ut_composite_io_op_alloc();
415  m0_fi_disable("m0_op_failed", "skip_ongoing_io_ref");
416  oci->oci_oo.oo_oc.oc_op.op_entity = &ent;
418  m0_op_bob_init(&oci->oci_oo.oo_oc.oc_op);
419 
420  en_grp = &ent.en_sm_group;
421  m0_sm_group_init(en_grp);
422  m0_sm_group_init(&locality_grp);
423  oci->oci_oo.oo_sm_grp = &locality_grp;
424 
425  m0_fi_enable("composite_io_op_cb_launch", "no_subobj_ops_launched");
426  op_grp = &oci->oci_oo.oo_oc.oc_op.op_sm_group;
427  m0_fi_enable_once("m0_op_stable", "skip_ongoing_io_ref");
428  m0_sm_group_lock(op_grp);
433  m0_sm_group_unlock(op_grp);
434  m0_fi_disable("composite_io_op_cb_launch", "no_subobj_ops_launched");
435  /*
436  * XXX This "once" injection is not triggered. It may be redundant
437  * or the test expects call of the function and it doesn't happen.
438  */
439  m0_fi_disable("m0_op_stable", "skip_ongoing_io_ref");
440 
441  /* finalise */
442  m0_sm_group_fini(&locality_grp);
443 
446 }
447 
448 static void ut_composite_io_op_cb_free(void)
449 {
450  struct m0_op_composite_io *oci;
451  struct m0_realm realm;
452  struct m0_entity ent;
453  struct m0_client *instance;
454 
455  /* init */
456  M0_SET0(&ent);
459 
460  /* base cases */
461  m0_fi_enable("m0_op_failed", "skip_ongoing_io_ref");
462  oci = ut_composite_io_op_alloc();
463  m0_fi_disable("m0_op_failed", "skip_ongoing_io_ref");
464  oci->oci_oo.oo_oc.oc_op.op_entity = &ent;
465  m0_fi_enable("composite_io_op_cb_free", "skip_free_sub_io_op");
467  m0_fi_disable("composite_io_op_cb_free", "skip_free_sub_io_op");
468 
469  /* fini */
471 }
472 
473 static void ut_composite_io_op_cb_fini(void)
474 {
475  struct m0_op_composite_io *oci;
476  struct m0_realm realm;
477  struct m0_entity ent;
478  struct m0_client *instance;
479 
480  /* init */
481  M0_SET0(&ent);
484 
485  /* base cases */
486  m0_fi_enable("m0_op_failed", "skip_ongoing_io_ref");
487  oci = ut_composite_io_op_alloc();
488  m0_fi_disable("m0_op_failed", "skip_ongoing_io_ref");
489  oci->oci_oo.oo_oc.oc_op.op_entity = &ent;
490  m0_fi_enable("composite_io_op_cb_fini", "skip_fini_sub_io_op");
492  m0_fi_disable("composite_io_op_cb_fini", "skip_fini_sub_io_op");
493 
494  /* fini */
497 }
498 
499 static void ut_m0_composite_layer_add(void)
500 {
501  int rc;
502  struct m0_client_layout *layout;
503  struct m0_client_composite_layout *clayout;
504  struct m0_obj obj;
505  struct m0_composite_layer *found;
506  struct m0_uint128 id;
507  struct m0_realm realm;
508  struct m0_client *instance;
509 
511  ut_realm_entity_setup(&realm, &obj.ob_entity, instance);
512  id = M0_ID_APP;
513  id.u_lo++;
514  obj.ob_entity.en_id = id;
515  obj.ob_attr.oa_layout_id = 12;
516  obj.ob_attr.oa_pver = (struct m0_fid){.f_container = 24, .f_key = 36};
517 
519  M0_UT_ASSERT(layout != NULL);
520  clayout = M0_AMB(clayout, layout, ccl_layout);
521 
522  /* Add a layer. */
523  m0_fi_enable("m0__obj_attr_get_sync", "obj_attr_get_ok");
524  rc = m0_composite_layer_add(layout, &obj, 0);
525  M0_UT_ASSERT(rc == 0);
526  M0_UT_ASSERT(clayout->ccl_nr_layers == 1);
527  found = m0_tl_find(clayer, found, &clayout->ccl_layers,
528  found->ccr_priority == 0);
529  M0_UT_ASSERT(found != NULL);
530  m0_fi_disable("m0__obj_attr_get_sync", "obj_attr_get_ok");
531 
532  /* Add again. */
533  rc = m0_composite_layer_add(layout, &obj, 0);
534  M0_UT_ASSERT(rc == 0);
535  M0_UT_ASSERT(clayout->ccl_nr_layers == 1);
536 }
537 
538 static void ut_m0_composite_layer_del(void)
539 {
540  int rc;
541  struct m0_client_layout *layout;
542  struct m0_client_composite_layout *clayout;
543  struct m0_obj obj;
544  struct m0_composite_layer *found;
545  struct m0_uint128 id;
546  struct m0_realm realm;
547  struct m0_client *instance;
548 
550  ut_realm_entity_setup(&realm, &obj.ob_entity, instance);
551  id = M0_ID_APP;
552  id.u_lo++;
553  obj.ob_entity.en_id = id;
554  obj.ob_attr.oa_layout_id = 12;
555  obj.ob_attr.oa_pver = (struct m0_fid){.f_container = 24, .f_key = 36};
556 
558  M0_UT_ASSERT(layout != NULL);
559  clayout = M0_AMB(clayout, layout, ccl_layout);
560 
561  /* Add layers. */
562  m0_fi_enable("m0__obj_attr_get_sync", "obj_attr_get_ok");
563  rc = m0_composite_layer_add(layout, &obj, 0);
564  M0_UT_ASSERT(rc == 0);
565  obj.ob_entity.en_id.u_lo++;
566  rc = m0_composite_layer_add(layout, &obj, 1);
567  M0_UT_ASSERT(rc == 0);
568  M0_UT_ASSERT(clayout->ccl_nr_layers == 2);
569  m0_fi_disable("m0__obj_attr_get_sync", "obj_attr_get_ok");
570 
571  /* Delete an existing layer. */
572  m0_composite_layer_del(layout, obj.ob_entity.en_id);
573  M0_UT_ASSERT(clayout->ccl_nr_layers == 1);
574  found = m0_tl_find(clayer, found, &clayout->ccl_layers,
575  m0_uint128_eq(&found->ccr_subobj,
576  &obj.ob_entity.en_id));
577  M0_UT_ASSERT(found == NULL);
578 
579  m0_composite_layer_del(layout, obj.ob_entity.en_id);
580  M0_UT_ASSERT(clayout->ccl_nr_layers == 1);
581 }
582 
584 {
585  int i;
586  int rc = 0;
587  int nr_subobjs;
588  struct composite_sub_io *sio_arr;
589  struct composite_sub_io_ext *sio_ext;
590  struct m0_obj obj;
591  struct m0_uint128 id;
592  struct m0_client *instance;
593  struct m0_realm realm;
594  struct m0_op *op = NULL;
595  struct m0_op_common *oc;
596  struct m0_op_obj *oo;
597  struct m0_op_composite_io *oci;
598 
600  ut_realm_entity_setup(&realm, &obj.ob_entity, instance);
601  id = M0_ID_APP;
602  id.u_lo++;
603  obj.ob_entity.en_id = id;
604 
605  rc = m0_op_get(&op, sizeof(struct m0_op_composite_io));
606  M0_UT_ASSERT(rc == 0);
607  M0_UT_ASSERT(op != NULL);
608  op->op_code = M0_OC_READ;
609  oc = M0_AMB(oc, op, oc_op);
610  oo = M0_AMB(oo, oc, oo_oc);
611  oci = M0_AMB(oci, oo, oci_oo);
612 
613  nr_subobjs = 3;
614  M0_ALLOC_ARR(sio_arr, nr_subobjs);
615  for (i = 0; i < nr_subobjs; i++) {
616  id.u_lo++;
617  sio_arr[i].si_id = id;
618  sio_arr[i].si_lid = 1;
619  sio_arr[i].si_nr_exts = 1;
620  sio_ext_tlist_init(&sio_arr[i].si_exts);
621 
622  M0_ALLOC_PTR(sio_ext);
623  M0_UT_ASSERT(sio_ext != NULL);
624  sio_ext->sie_off = i * 4096;
625  sio_ext->sie_len = 4096;
626  sio_ext_tlink_init_at(sio_ext, &sio_arr[i].si_exts);
627  }
628 
629  m0_fi_enable("m0__obj_attr_get_sync", "obj_attr_get_ok");
630  m0_fi_enable("m0_obj_op", "fake_op");
631  m0_fi_enable("m0_op_failed", "skip_ongoing_io_ref");
632  rc = composite_sub_io_ops_build(&obj, op, sio_arr, nr_subobjs);
633  m0_fi_disable("m0_op_failed", "skip_ongoing_io_ref");
634  M0_UT_ASSERT(rc == 0);
635  M0_UT_ASSERT(oci->oci_sub_ops != NULL);
636  M0_UT_ASSERT(oci->oci_nr_sub_ops == nr_subobjs);
637  /*
638  * if layout is not found in m0__obj_layout_instance_build(),
639  * then the op is set to NULL
640  */
641  for (i = 0; i < oci->oci_nr_sub_ops; i++) {
642  M0_UT_ASSERT(oci->oci_sub_ops[i] == NULL);
643  }
644  m0_fi_disable("m0__obj_attr_get_sync", "obj_attr_get_ok");
645  m0_fi_disable("m0_obj_op", "fake_op");
646 
647  m0_free(op);
648  m0_free(sio_arr);
649  m0_entity_fini(&obj.ob_entity);
650 }
651 
653  int nr_layers,
654  struct m0_uint128 *layer_ids)
655 {
656  int i;
657  int j;
658  int rc = 0;
659  struct m0_obj obj;
660  struct m0_uint128 id;
661  struct m0_realm realm;
662  struct m0_client *instance;
663 
665  ut_realm_entity_setup(&realm, &obj.ob_entity, instance);
666  id = M0_ID_APP;
667 
668  m0_fi_enable("m0__obj_attr_get_sync", "obj_attr_get_ok");
669  for (i = 0; i < nr_layers; i++) {
670  id.u_lo++;
671  obj.ob_entity.en_id = id;
672  obj.ob_attr.oa_layout_id = 12;
673  obj.ob_attr.oa_pver = (struct m0_fid){.f_container = 24, .f_key = 36};
674  rc = m0_composite_layer_add(layout, &obj, i);
675  layer_ids[i] = id;
676  }
677  if (rc != 0) {
678  for (j = 0; j < i; j++)
679  m0_composite_layer_del(layout, layer_ids[j]);
680  }
681  m0_fi_disable("m0__obj_attr_get_sync", "obj_attr_get_ok");
682 
683  return rc;
684 }
685 
686 struct io_seg {
689 };
690 
692  int nr_io_segs, struct io_seg *io_segs,
693  struct composite_sub_io **sio_arr,
694  int *nr_subobjs)
695 {
696  int i;
697  int rc;
698  struct m0_indexvec ext;
699  struct m0_bufvec data;
700 
701  /* Prepare bufvec and indexvec. */
702  rc = m0_bufvec_empty_alloc(&data, nr_io_segs);
703  if (rc != 0)
704  return rc;
705 
706  for (i = 0; i < nr_io_segs; i++) {
707  data.ov_vec.v_count[i] = io_segs[i].is_len;
708  data.ov_buf[i] = m0_alloc(io_segs[i].is_len);
709  if (data.ov_buf[i] == NULL)
710  goto free;
711  }
712 
713  rc = m0_indexvec_alloc(&ext, nr_io_segs);
714  if (rc != 0)
715  goto free;
716  for (i = 0; i < nr_io_segs; i++) {
717  ext.iv_index[i] = io_segs[i].is_off;
718  ext.iv_vec.v_count[i] = io_segs[i].is_len;
719  }
720 
721  rc = composite_io_divide(clayout, M0_OC_READ,
722  &ext, &data, sio_arr, nr_subobjs);
723 
724 free:
726  m0_indexvec_free(&ext);
727  return rc;
728 }
729 
730 static void ut_composite_io_divide(void)
731 {
732  int i = 0;
733  int rc = 0;
734  int unit_size = 4096;
735  int nr_layers;
736  int nr_io_segs;
737  struct m0_uint128 *layer_ids;
738  m0_bindex_t off;
739  m0_bcount_t len;
740  struct m0_client_layout *layout;
741  struct m0_client_composite_layout *clayout;
742  struct m0_composite_layer *layer;
743  struct m0_composite_extent *ext;
744  struct m0_tl *ext_list = NULL;
745  struct composite_sub_io *sio;
746  struct composite_sub_io *sio_arr;
747  struct composite_sub_io_ext *sio_ext;
748  int nr_sios = 0;
749  struct io_seg *io_segs;
750 
751  /* Create a composite layout with layers. */
753  M0_UT_ASSERT(layout != NULL);
754  clayout = M0_AMB(clayout, layout, ccl_layout);
755  M0_UT_ASSERT(clayout != NULL);
756 
757  nr_layers = 3;
758  M0_ALLOC_ARR(layer_ids, nr_layers);
759  M0_UT_ASSERT(layer_ids != NULL);
760  rc = composite_layout_add_layers(layout, nr_layers, layer_ids);
761  M0_UT_ASSERT(rc == 0);
762 
763  /* Case 1: multiple layers, non-overlapping extents. */
764  i = 0;
765  off = 0;
766  m0_tl_for(clayer, &clayout->ccl_layers, layer) {
767  /* Set key and value. */
768  off = i * 16 * unit_size;
769  len = 16 * unit_size;
770  M0_ALLOC_PTR(ext);
771  M0_UT_ASSERT(ext != NULL);
772  ext->ce_id = layer_ids[i];
773  ext->ce_off = off;
774  ext->ce_len = len;
775  ext_list = &layer->ccr_rd_exts;
776  cext_tlink_init_at_tail(ext, ext_list);
777  i++;
778  } m0_tl_endfor;
779 
780  /* Write to the newly created object above.*/
781  nr_io_segs= 3;
782  M0_ALLOC_ARR(io_segs, nr_io_segs);
783  M0_UT_ASSERT(io_segs != NULL);
784  for (i = 0; i < nr_io_segs; i++) {
785  io_segs[i].is_off = i * 16 * unit_size;
786  io_segs[i].is_len = 16 * unit_size;
787  }
788  rc = do_composite_io_divide(clayout, nr_io_segs, io_segs,
789  &sio_arr, &nr_sios);
790  M0_UT_ASSERT(rc == 0);
791  M0_UT_ASSERT(nr_sios == nr_layers);
792 
793  /* Verify. */
794  off = 0;
795  for (i = 0; i < nr_sios; i++) {
796  off = i * 16 * unit_size;
797  len = 16 * unit_size;
798 
799  sio = &sio_arr[i];
800  M0_UT_ASSERT(sio->si_nr_exts == 1);
801  sio_ext = sio_ext_tlist_head(&sio->si_exts);
802  M0_UT_ASSERT(sio_ext->sie_off == off);
803  M0_UT_ASSERT(sio_ext->sie_len == len);
804  }
805 
806  /* Finalise and free. */
807  m0_tl_teardown(clayer, &clayout->ccl_layers, layer) {
808  m0_tl_teardown(cext, &layer->ccr_rd_exts, ext)
809  m0_free(ext);
810  m0_tl_teardown(cext, &layer->ccr_wr_exts, ext)
811  m0_free(ext);
812  m0_free0(&layer);
813  }
814  m0_client_layout_free(layout);
815  m0_free(layer_ids);
816  m0_free(io_segs);
817 }
818 
820 {
821  int i;
822  int rc;
823  int *rcs;
824  int nr_kvp;
825  struct m0_tl *ext_list;
826  struct m0_bufvec keys;
827  struct m0_bufvec vals;
828  struct m0_composite_layer layer;
829  struct m0_composite_layer_idx_key max_key;
832 
833  layer.ccr_subobj = M0_ID_APP;
834  layer.ccr_subobj.u_lo++;
835  cext_tlist_init(&layer.ccr_rd_exts);
836  ext_list = &layer.ccr_rd_exts;
837 
838  /* Allocate bufvec's for keys and vals. */
840  rc = m0_bufvec_empty_alloc(&keys, nr_kvp)?:
841  m0_bufvec_empty_alloc(&vals, nr_kvp);
842  M0_UT_ASSERT(rc == 0);
843  M0_ALLOC_ARR(rcs, nr_kvp);
844  M0_UT_ASSERT(rcs != NULL);
845 
846  /* Case 1: no key/value pairs returned. */
847  rc = composite_layer_idx_extents_extract(&layer, &keys, &vals, rcs,
848  ext_list, &max_key);
849  M0_UT_ASSERT(rc == 0);
850 
851  /* Case 2: every key/value pair in bufvec. */
852  for (i = 0; i < nr_kvp; i++) {
853  /* Set key and value. */
854  key.cek_layer_id = layer.ccr_subobj;
855  key.cek_off = i * 4096;
856  val.cev_len = 4096;
858  &key, &keys.ov_buf[i], &keys.ov_vec.v_count[i])?:
860  &val, &vals.ov_buf[i], &vals.ov_vec.v_count[i]);
861  M0_UT_ASSERT(rc == 0);
862  }
863 
864  rc = composite_layer_idx_extents_extract(&layer, &keys, &vals, rcs,
865  ext_list, &max_key);
866  M0_UT_ASSERT(rc == nr_kvp);
867  M0_UT_ASSERT(max_key.cek_off == (i - 1) * 4096);
868 
869  for (i = 0; i < nr_kvp; i++) {
870  m0_free(keys.ov_buf[i]);
871  keys.ov_buf[i] = NULL;
872  keys.ov_vec.v_count[i] = 0;
873  m0_free(vals.ov_buf[i]);
874  vals.ov_buf[i] = NULL;
875  vals.ov_vec.v_count[i] = 0;
876  }
877 
878  /* Case 3: less than nr_kvp key/value pairs returned*/
879  for (i = 0; i < nr_kvp; i++) {
880  /* Set key and value. */
881  key.cek_layer_id = layer.ccr_subobj;
882  if (i >= 2)
883  key.cek_layer_id.u_lo++;
884  key.cek_off = i * 4096;
885  val.cev_len = 4096;
887  &key, &keys.ov_buf[i], &keys.ov_vec.v_count[i])?:
889  &val, &vals.ov_buf[i], &vals.ov_vec.v_count[i]);
890  M0_UT_ASSERT(rc == 0);
891  }
892 
893  rc = composite_layer_idx_extents_extract(&layer, &keys, &vals, rcs,
894  ext_list, &max_key);
895  M0_UT_ASSERT(rc == 2);
896  M0_UT_ASSERT(max_key.cek_off == 4096);
897 }
898 
900 {
901 
902 }
903 
904 M0_INTERNAL int ut_suite_layout_init(void)
905 {
906  int rc;
907 
909  M0_UT_ASSERT(rc == 0);
910 
911  return 0;
912 }
913 
914 M0_INTERNAL int ut_suite_layout_fini(void)
915 {
917 
918  return 0;
919 }
920 
921 struct m0_ut_suite ut_suite_layout = {
922  .ts_name = "layout-ut",
923  .ts_init = ut_suite_layout_init,
924  .ts_fini = ut_suite_layout_fini,
925  .ts_tests = {
926  { "layout_op_invariant",
928  { "layout_op_init",
930  { "layout_op_cb_launch",
932  { "layout_op_cb_free",
934  { "layout_op_cb_fini",
936  { "m0_layout_op",
937  &ut_m0_layout_op},
938  { "m0_client_layout_alloc",
940  { "m0_layout_capture",
942  { "composite_io_op_cb_launch",
944  { "composite_io_op_cb_free",
946  { "composite_io_op_cb_fini",
948  { "m0_composite_layer_add",
950  { "m0_composite_layer_del",
952  { "composite_sub_io_ops_build",
954  { "composite_io_divide",
956  { "composite_layer_idx_extents_extract",
958  { "composite_layer_idx_scan",
960  { NULL, NULL },
961  }
962 };
963 
964 #undef M0_TRACE_SUBSYSTEM
965 
966 /*
967  * Local variables:
968  * c-indentation-style: "K&R"
969  * c-basic-offset: 8
970  * tab-width: 8
971  * fill-column: 80
972  * scroll-step: 1
973  * End:
974  */
const struct m0_client_layout_ops layout_composite_ops
uint64_t id
Definition: cob.h:2380
m0_bindex_t is_off
Definition: layout.c:578
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
static void ut_m0_layout_op(void)
Definition: layout.c:226
static void ut_composite_layer_idx_extents_extract(void)
Definition: layout.c:819
void m0_entity_fini(struct m0_entity *entity)
Definition: client.c:438
Definition: layout.c:577
M0_INTERNAL int m0_op_get(struct m0_op **op, size_t size)
Definition: client.c:568
Definition: client.h:788
static int composite_io_divide(struct m0_client_composite_layout *clayout, enum m0_obj_opcode opcode, struct m0_indexvec *ext, struct m0_bufvec *data, struct composite_sub_io **out, int *out_nr_sios)
static void ut_layout_op_init(void)
Definition: layout.c:83
M0_INTERNAL int m0_indexvec_alloc(struct m0_indexvec *ivec, uint32_t len)
Definition: vec.c:532
static void layout_op_cb_free(struct m0_op_common *oc)
Definition: layout.c:337
struct m0_sm_group * ol_sm_grp
Definition: layout.h:178
#define NULL
Definition: misc.h:38
Definition: idx_mock.c:52
static struct m0_client * dummy_instance
Definition: layout.c:39
M0_INTERNAL bool m0_uint128_eq(const struct m0_uint128 *u0, const struct m0_uint128 *u1)
Definition: misc.c:39
static struct m0_op_layout * ut_m0_op_layout_alloc()
Definition: layout.c:41
static void ut_composite_io_op_cb_free(void)
Definition: layout.c:448
struct m0_sm_group * oo_sm_grp
struct m0_vec ov_vec
Definition: vec.h:147
struct m0_bufvec data
Definition: di.c:40
static void ut_layout_op_invariant(void)
Definition: layout.c:63
struct m0_op oc_op
M0_INTERNAL void m0_indexvec_free(struct m0_indexvec *ivec)
Definition: vec.c:553
uint64_t m0_bindex_t
Definition: types.h:80
M0_INTERNAL int ut_suite_layout_fini(void)
Definition: layout.c:914
uint64_t m0_bcount_t
Definition: types.h:77
#define M0_SET0(obj)
Definition: misc.h:64
static const struct m0_client_layout_ops layout_pdclust_ops
Definition: layout.c:46
Definition: ut.h:77
static void composite_io_op_cb_fini(struct m0_op_common *oc)
uint64_t cl_lid
Definition: layout.h:121
M0_INTERNAL int ut_m0_client_init(struct m0_client **instance)
Definition: client.c:265
static int op_layout_dummy_launch(struct m0_op_layout *ol)
Definition: layout.c:120
void ** ov_buf
Definition: vec.h:149
M0_INTERNAL void m0_sm_group_fini(struct m0_sm_group *grp)
Definition: sm.c:65
static struct foo * obj
Definition: tlist.c:302
static const struct m0_client_layout_ops layout_capture_ops
Definition: layout.c:47
struct m0_fid pl_pver
Definition: layout.h:126
const struct m0_uint128 M0_ID_APP
Definition: client.c:92
#define m0_tl_endfor
Definition: tlist.h:700
struct m0_vec iv_vec
Definition: vec.h:139
op
Definition: libdemo.c:64
static void composite_sub_io_destroy(struct composite_sub_io *sio_arr, int nr_subobjs)
unsigned int op_code
Definition: client.h:650
int(* olo_launch)(struct m0_op_layout *ol)
Definition: layout.h:167
static uint32_t unit_size
Definition: layout.c:53
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
M0_INTERNAL void m0_sm_group_unlock(struct m0_sm_group *grp)
Definition: sm.c:96
m0_bindex_t * iv_index
Definition: vec.h:141
static void ut_layout_op_cb_launch(void)
Definition: layout.c:131
enum m0_client_layout_type ml_type
Definition: client.h:798
int i
Definition: dir.c:1033
size_t op_size
Definition: client.h:664
static void ut_composite_layer_idx_scan(void)
Definition: layout.c:899
static void ut_composite_io_divide(void)
Definition: layout.c:730
static void ut_m0_composite_layer_add(void)
Definition: layout.c:499
Definition: client.h:641
M0_INTERNAL void ut_realm_entity_setup(struct m0_realm *realm, struct m0_entity *ent, struct m0_client *cinst)
Definition: client.c:60
static void ut_composite_io_op_cb_launch(void)
Definition: layout.c:398
struct m0_client_layout * m0_client_layout_alloc(enum m0_client_layout_type type)
Definition: layout.c:473
struct m0_uint128 cl_orig_id
Definition: layout.h:119
struct m0_sm op_sm
Definition: client.h:656
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
#define m0_tl_teardown(name, head, obj)
Definition: tlist.h:708
M0_INTERNAL void m0_fi_disable(const char *fp_func, const char *fp_tag)
Definition: finject.c:485
static void m0_fi_enable(const char *func, const char *tag)
Definition: finject.h:276
#define m0_free0(pptr)
Definition: memory.h:77
static void layout_op_cb_launch(struct m0_op_common *oc)
Definition: layout.c:356
void m0_client_layout_free(struct m0_client_layout *layout)
Definition: layout.c:504
M0_INTERNAL void ut_m0_client_fini(struct m0_client **instance)
Definition: client.c:354
M0_INTERNAL void m0_sm_group_init(struct m0_sm_group *grp)
Definition: sm.c:53
int m0_composite_layer_idx_key_to_buf(struct m0_composite_layer_idx_key *key, void **out_kbuf, m0_bcount_t *out_klen)
static int composite_sub_io_ops_build(struct m0_obj *cobj, struct m0_op *cop, struct composite_sub_io *sio_arr, int nr_subobjs)
Definition: tlist.h:251
struct m0_fid cl_pver
Definition: layout.h:120
static void ut_m0_layout_capture(void)
Definition: layout.c:283
static void ut_layout_op_cb_fini(void)
Definition: layout.c:204
struct m0_op_common ol_oc
Definition: layout.h:175
void * m0_alloc(size_t size)
Definition: memory.c:126
static void ut_m0_composite_layer_del(void)
Definition: layout.c:538
void m0_composite_layer_del(struct m0_client_layout *layout, struct m0_uint128 subobj_id)
static struct m0_op_composite_io * ut_composite_io_op_alloc()
Definition: layout.c:325
struct m0_uint128 ce_id
Definition: layout.h:132
static void ut_m0_op_layout_free(struct m0_op_layout *ol)
Definition: layout.c:58
static void ut_m0_client_layout_alloc(void)
Definition: layout.c:260
m0_bcount_t * v_count
Definition: vec.h:53
struct m0_op_common oo_oc
static int composite_layer_idx_extents_extract(struct m0_composite_layer *layer, struct m0_bufvec *keys, struct m0_bufvec *vals, int *rcs, struct m0_tl *ext_list, struct m0_composite_layer_idx_key *max_key)
struct m0_ast_rc ol_ar
Definition: layout.h:179
static void ut_composite_io_op_free(struct m0_op_composite_io *oci)
Definition: layout.c:391
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
const char * ts_name
Definition: ut.h:99
struct m0_tl ccl_layers
Definition: layout.h:159
struct m0_uint128 ccr_subobj
Definition: layout.h:141
static int rc
Definition: layout.c:51
struct m0_sm_group op_sm_group
Definition: client.h:654
static struct m0_op_layout_ops op_layout_dummy_ops
Definition: layout.c:125
struct m0_ut_suite ut_suite_layout
Definition: layout.c:37
struct m0_op ** oci_sub_ops
Definition: layout.h:195
Definition: fid.h:38
M0_INTERNAL void m0_sm_init(struct m0_sm *mach, const struct m0_sm_conf *conf, uint32_t state, struct m0_sm_group *grp)
Definition: sm.c:313
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
static struct m0_realm realm
Definition: sync.c:87
struct m0_entity * op_entity
Definition: client.h:660
int m0_composite_layer_add(struct m0_client_layout *layout, struct m0_obj *sub_obj, int priority)
static void layout_op_cb_fini(struct m0_op_common *oc)
Definition: layout.c:315
static int dummy_op_rc
Definition: layout.c:118
m0_bcount_t is_len
Definition: layout.c:579
static void ut_layout_op_cb_free(void)
Definition: layout.c:183
static void ut_composite_sub_io_ops_build(void)
Definition: layout.c:583
const struct m0_op_layout_ops * ol_ops
Definition: layout.h:185
int m0_client_layout_op(struct m0_obj *obj, enum m0_entity_opcode opcode, struct m0_client_layout *layout, struct m0_op **op)
Definition: layout.c:436
M0_INTERNAL void m0_sm_move(struct m0_sm *mach, int32_t rc, int state)
Definition: sm.c:485
const struct m0_client_layout_ops * ml_ops
Definition: client.h:801
m0_bcount_t ce_len
Definition: layout.h:134
struct m0_tl ccr_wr_exts
Definition: layout.h:146
static struct m0 instance
Definition: main.c:78
static void ut_composite_io_op_cb_fini(void)
Definition: layout.c:473
M0_INTERNAL void m0_sm_group_lock(struct m0_sm_group *grp)
Definition: sm.c:83
static int composite_layout_add_layers(struct m0_client_layout *layout, int nr_layers, struct m0_uint128 *layer_ids)
Definition: layout.c:652
static void m0_fi_enable_once(const char *func, const char *tag)
Definition: finject.h:301
static int do_composite_io_divide(struct m0_client_composite_layout *clayout, int nr_io_segs, struct io_seg *io_segs, struct composite_sub_io **sio_arr, int *nr_subobjs)
Definition: layout.c:691
m0_bindex_t ce_off
Definition: layout.h:133
int m0_client_layout_capture(struct m0_client_layout *layout, struct m0_obj *obj, struct m0_client_layout **out)
Definition: layout.c:138
struct m0_tl ccr_rd_exts
Definition: layout.h:145
struct m0_tl si_exts
static uint64_t found
Definition: base.c:376
M0_INTERNAL int ut_suite_layout_init(void)
Definition: layout.c:904
static void composite_io_op_cb_launch(struct m0_op_common *oc)
struct m0_uint128 si_id
struct m0_dirent * ent
Definition: dir.c:1029
uint64_t u_lo
Definition: types.h:37
static int layout_op_init(struct m0_obj *obj, struct m0_client_layout *layout, enum m0_entity_opcode opcode, struct m0_op *op)
Definition: layout.c:381
static bool layout_op_invariant(struct m0_op_layout *ol)
Definition: layout.c:302
#define m0_tl_find(name, var, head,...)
Definition: tlist.h:757
#define m0_tl_for(name, head, obj)
Definition: tlist.h:695
void m0_free(void *data)
Definition: memory.c:146
int m0_composite_layer_idx_val_to_buf(struct m0_composite_layer_idx_val *val, void **out_vbuf, m0_bcount_t *out_vlen)
#define M0_UT_ASSERT(a)
Definition: ut.h:46
struct m0_sm_conf m0_op_conf
Definition: client.c:145
Definition: vec.h:145
M0_INTERNAL int m0_bufvec_empty_alloc(struct m0_bufvec *bufvec, uint32_t num_segs)
Definition: vec.c:213
Definition: idx_mock.c:47
M0_INTERNAL void m0_sm_fini(struct m0_sm *mach)
Definition: sm.c:331
static void composite_io_op_cb_free(struct m0_op_common *oc)
struct m0_op_obj oci_oo
Definition: layout.h:191