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 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CLIENT
24 #include "lib/trace.h"
25 
26 #include "motr/client.h"
27 #include "motr/layout.h"
28 #include "motr/st/st.h"
29 #include "motr/st/st_misc.h"
30 #include "motr/st/st_assert.h"
31 
32 #include "lib/memory.h"
33 #include "lib/vec.h"
34 #include "lib/types.h"
35 #include "lib/errno.h" /* ENOENT */
36 
37 #ifndef __KERNEL__
38 # include <stdlib.h>
39 # include <unistd.h>
40 #else
41 # include <linux/delay.h>
42 #endif
43 
44 /*
45  * Fill those pre-created objects with some value
46  */
47 enum { CHAR_NUM = 6 };
48 static char pattern[CHAR_NUM] = {'C', 'L', 'O', 'V', 'I', 'S'};
49 
50 static struct m0_uint128 test_id;
52 static uint64_t layout_id;
54 
58 static int create_obj(struct m0_uint128 id)
59 {
60  struct m0_op *ops[] = {NULL};
61  struct m0_obj *obj;
62  int rc;
63 
65  if (obj == NULL)
66  return -ENOMEM;
67 
69  &id, layout_id);
70 
71  rc = st_entity_create(NULL, &obj->ob_entity, &ops[0]);
72  rc = rc?:ops[0]->op_sm.sm_rc;
73  if (rc != 0) {
74  mem_free(obj);
75  return rc;
76  }
77 
80  M0_OS_STABLE),
82  st_op_fini(ops[0]);
83  st_op_free(ops[0]);
84  st_entity_fini(&obj->ob_entity);
85  mem_free(obj);
86 
87  return rc;
88 }
89 
90 static int write_obj(struct m0_uint128 id)
91 {
92  int i;
93  int rc;
94  int blk_cnt;
95  int blk_size;
96  char value;
97  uint64_t last_index;
98  struct m0_obj obj;
99  struct m0_op *ops[1] = {NULL};
100  struct m0_indexvec ext;
101  struct m0_bufvec data;
102  struct m0_bufvec attr;
103 
105  M0_SET0(&obj);
106 
107  /* Prepare the data with 'value' */
108  blk_cnt = 4;
109  blk_size = unit_size;
110 
111  rc = m0_bufvec_alloc(&data, blk_cnt, blk_size);
112  if (rc != 0)
113  return rc;
114 
115  for (i = 0; i < blk_cnt; i++) {
116  /*
117  * The pattern written to object has to match
118  * to those in read tests
119  */
120  value = pattern[i % CHAR_NUM];
121  memset(data.ov_buf[i], value, blk_size);
122  }
123 
124  /* Prepare indexvec for write */
125  rc = m0_bufvec_alloc(&attr, blk_cnt, 1);
126  if(rc != 0) return rc;
127 
128  rc = m0_indexvec_alloc(&ext, blk_cnt);
129  if (rc != 0) return rc;
130 
131  last_index = 0;
132  for (i = 0; i < blk_cnt; i++) {
133  ext.iv_index[i] = last_index ;
134  ext.iv_vec.v_count[i] = blk_size;
135  last_index += blk_size;
136 
137  /* we don't want any attributes */
138  attr.ov_vec.v_count[i] = 0;
139  }
140 
141  /* Write to object */
142  memset(&obj, 0, sizeof obj);
143  ops[0] = NULL;
144 
145  st_obj_init(
147  &id, layout_id);
148  st_entity_open(&obj.ob_entity);
149  //M0_ASSERT(obj.ob_attr.oa_layout_id == layout_id);
150  st_obj_op(&obj, M0_OC_WRITE, &ext, &data, NULL, 0, 0, &ops[0]);
151  st_op_launch(ops, 1);
153  M0_OS_STABLE),
154  M0_TIME_NEVER);
155 
156  /* fini and release */
157  st_op_fini(ops[0]);
158  st_op_free(ops[0]);
159  st_entity_fini(&obj.ob_entity);
160 
163  m0_indexvec_free(&ext);
164  return rc;
165 }
166 
170 static void layout_op_get_obj(void)
171 {
172  int rc;
173  struct m0_uint128 id;
174  struct m0_op *ops[] = {NULL};
175  struct m0_obj *obj;
176  struct m0_client_layout *layout;
177 
178  /* Create an object with default layout type (PDCLUST). */
179  oid_get(&id);
180  create_obj(id);
181 
182  /* Sample code to retrieve layout of the created object. */
183  M0_ALLOC_PTR(obj);
185 
186  /* 1. Initialise in-memory object data struct. */
188  &id, layout_id);
189 
190  /* 2. Open the object to get its attributes. */
191  st_entity_open(&obj->ob_entity);
193  M0_LT_PDCLUST);
194 
195  /* 3. Issue LAYOUT_GET op. */
197  ST_ASSERT_FATAL(layout != NULL);
198 
199  rc = st_layout_op(obj, M0_EO_LAYOUT_GET, layout, &ops[0]);
200  ST_ASSERT_FATAL(rc == 0);
201  ST_ASSERT_FATAL(ops[0] != NULL);
202  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
203 
206  M0_OS_STABLE),
207  M0_TIME_NEVER);
208  ST_ASSERT_FATAL(rc == 0);
209  ST_ASSERT_FATAL(ops[0]->op_sm.sm_state == M0_OS_STABLE);
210  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
211 
212  st_op_fini(ops[0]);
213  st_op_free(ops[0]);
214  st_entity_fini(&obj->ob_entity);
215  m0_client_layout_free(layout);
216  m0_free(obj);
217 }
218 
219 static int layout_create_capture_obj(struct m0_client_layout *layout,
220  struct m0_uint128 *ret_id)
221 {
222  int rc;
223  struct m0_uint128 id;
224  struct m0_op *ops[] = {NULL};
225  struct m0_obj *obj = NULL;
226 
227  oid_get(&id);
228  create_obj(id);
229  *ret_id = id;
230 
231  M0_ALLOC_PTR(obj);
232  if (obj == NULL)
233  return -ENOMEM;
234 
236  &id, layout_id);
237  st_entity_open(&obj->ob_entity);
239  layout, &ops[0]);
242  M0_OS_STABLE),
243  M0_TIME_NEVER);
244  st_op_fini(ops[0]);
245  st_op_free(ops[0]);
246  st_entity_fini(&obj->ob_entity);
247  m0_free(obj);
248 
249  return rc;
250 }
251 
256 static void layout_capture(void)
257 {
258  int rc;
259  struct m0_uint128 orig_id;
260  struct m0_uint128 id;
261  struct m0_op *ops[] = {NULL};
262  struct m0_obj *orig_obj;
263  struct m0_client_layout *orig_layout;
264  struct m0_client_layout *layout;
265 
266  /* Create an object with default layout type (PDCLUST). */
267  oid_get(&orig_id);
268  create_obj(orig_id);
269 
270  /*
271  * Sample code to capture layout and set an object with
272  * captured layout.
273  */
274  M0_ALLOC_PTR(orig_obj);
275  ST_ASSERT_FATAL(orig_obj != NULL);
276 
277  /* 1. Initialise in-memory object data struct. */
279  &orig_id, layout_id);
280 
281  /* 2. Open the object to get its attributes. */
282  st_entity_open(&orig_obj->ob_entity);
284  M0_LT_PDCLUST);
285 
286  /* 3. Issue LAYOUT_GET op. */
287  orig_layout = m0_client_layout_alloc(M0_LT_PDCLUST);
288  ST_ASSERT_FATAL(orig_layout != NULL);
289 
290  rc = st_layout_op(orig_obj, M0_EO_LAYOUT_GET,
291  orig_layout, &ops[0]);
292  ST_ASSERT_FATAL(rc == 0);
293  ST_ASSERT_FATAL(ops[0] != NULL);
294  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
295 
298  M0_OS_STABLE),
299  M0_TIME_NEVER);
300  ST_ASSERT_FATAL(rc == 0);
301  ST_ASSERT_FATAL(ops[0]->op_sm.sm_state == M0_OS_STABLE);
302  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
303 
304  st_op_fini(ops[0]);
305  st_op_free(ops[0]);
306  ops[0] = NULL;
307 
308  /* 4. Capture layout. */
309  rc = m0_client_layout_capture(orig_layout, orig_obj, &layout);
310  ST_ASSERT_FATAL(rc == 0);
311  ST_ASSERT_FATAL(layout != NULL);
312 
313  /* 5. Create a new object with the captured layout.*/
314  rc = layout_create_capture_obj(layout, &id);
315  ST_ASSERT_FATAL(rc == 0);
316 
317  /* Fini and free entities and layouts. */
318  m0_client_layout_free(layout);
319  st_entity_fini(&orig_obj->ob_entity);
320  m0_client_layout_free(orig_layout);
321  m0_free(orig_obj);
322 }
323 
327 static void layout_capture_io(void)
328 {
329  int rc;
330  struct m0_uint128 orig_id;
331  struct m0_uint128 id;
332  struct m0_op *ops[] = {NULL};
333  struct m0_obj *orig_obj;
334  struct m0_client_layout *orig_layout;
335  struct m0_client_layout *layout;
336 
337  /* Create an object with default layout type (PDCLUST). */
338  oid_get(&orig_id);
339  create_obj(orig_id);
340 
341  /*
342  * Sample code to capture layout and set an object with
343  * captured layout.
344  */
345  M0_ALLOC_PTR(orig_obj);
346  ST_ASSERT_FATAL(orig_obj != NULL);
347 
348  /* 1. Initialise in-memory object data struct. */
350  &orig_id, layout_id);
351 
352  /* 2. Open the object to get its attributes. */
353  st_entity_open(&orig_obj->ob_entity);
355  M0_LT_PDCLUST);
356 
357  /* 3. Issue LAYOUT_GET op. */
358  orig_layout = m0_client_layout_alloc(M0_LT_PDCLUST);
359  ST_ASSERT_FATAL(orig_layout != NULL);
360 
361  rc = st_layout_op(orig_obj, M0_EO_LAYOUT_GET,
362  orig_layout, &ops[0]);
363  ST_ASSERT_FATAL(rc == 0);
364  ST_ASSERT_FATAL(ops[0] != NULL);
365  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
366 
369  M0_OS_STABLE),
370  M0_TIME_NEVER);
371  ST_ASSERT_FATAL(rc == 0);
372  ST_ASSERT_FATAL(ops[0]->op_sm.sm_state == M0_OS_STABLE);
373  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
374 
375  st_op_fini(ops[0]);
376  st_op_free(ops[0]);
377  ops[0] = NULL;
378 
379  /* 4. Capture layout. */
380  rc = m0_client_layout_capture(orig_layout, orig_obj, &layout);
381  ST_ASSERT_FATAL(rc == 0);
382  ST_ASSERT_FATAL(layout != NULL);
383 
384  /* 5. Create a new object with the captured layout.*/
385  rc = layout_create_capture_obj(layout, &id);
386  ST_ASSERT_FATAL(rc == 0);
387 
388  /* 6. Write to the newly created object above.*/
389  rc = write_obj(id);
390  ST_ASSERT_FATAL(rc == 0);
391 
392  /* Fini and free entities and layouts. */
393  m0_client_layout_free(layout);
394  st_entity_fini(&orig_obj->ob_entity);
395  m0_client_layout_free(orig_layout);
396  m0_free(orig_obj);
397 }
398 
400  struct m0_uint128 *ret_id)
401 {
402  int rc;
403  struct m0_uint128 id;
404  struct m0_op *ops[] = {NULL};
405  struct m0_obj *obj = NULL;
406 
407  oid_get(&id);
408  create_obj(id);
409  *ret_id = id;
410 
411  M0_ALLOC_PTR(obj);
412  if (obj == NULL)
413  return -ENOMEM;
414 
416  &id, layout_id);
417  st_entity_open(&obj->ob_entity);
419  layout, &ops[0]);
420 
423  M0_OS_STABLE),
424  M0_TIME_NEVER);
425 
426  st_op_fini(ops[0]);
427  st_op_free(ops[0]);
428 
429  st_entity_fini(&obj->ob_entity);
430  m0_free(obj);
431 
432  return rc;
433 }
434 
436  int nr_layers,
437  struct m0_uint128 *layer_ids)
438 {
439  int i;
440  int j;
441  int rc = 0;
442  struct m0_uint128 id;
443  struct m0_obj obj;
444 
445  M0_ASSERT(nr_layers > 0);
446 
447  for (i = 0; i < nr_layers; i++) {
448  /* Create a sub-object. */
449  oid_get(&id);
450  rc = create_obj(id);
451  if (rc != 0)
452  break;
453 
454  M0_SET0(&obj);
456  &id, layout_id);
457  rc = m0_composite_layer_add(layout, &obj, i);
458  st_entity_fini(&obj.ob_entity);
459  if (rc != 0)
460  break;
461  layer_ids[i] = id;
462  }
463 
464  if (rc != 0) {
465  for (j = 0; j < i; j++)
466  m0_composite_layer_del(layout, layer_ids[j]);
467  }
468 
469  return rc;
470 }
471 
475 static void layout_composite_create(void)
476 {
477  int rc;
478  int nr_layers;
479  struct m0_uint128 id;
480  struct m0_uint128 *layer_ids;
481  struct m0_client_layout *layout;
482 
483  /* Create a composite layout with layers. */
485  ST_ASSERT_FATAL(layout != NULL);
486 
487  nr_layers = 3;
488  M0_ALLOC_ARR(layer_ids, nr_layers);
489  ST_ASSERT_FATAL(layer_ids != NULL);
490  rc = layout_composite_add_layers(layout, nr_layers, layer_ids);
491  ST_ASSERT_FATAL(rc == 0);
492 
493  /* Create a new object with the captured layout.*/
494  rc = layout_composite_create_obj(layout, &id);
495  ST_ASSERT_FATAL(rc == 0);
496 
497  m0_client_layout_free(layout);
498 }
499 
505 {
506  int rc;
507  int nr_layers;
508  struct m0_uint128 id;
509  struct m0_uint128 *layer_ids;
510  struct m0_op *ops[] = {NULL};
511  struct m0_obj obj;
512  struct m0_client_layout *layout;
513  struct m0_client_composite_layout *clayout;
514  struct m0_client_layout *layout_to_check;
515  struct m0_client_composite_layout *clayout_to_check;
516 
517  /* Create a composite layout with layers. */
519  ST_ASSERT_FATAL(layout != NULL);
520 
521  nr_layers = 1;
522  M0_ALLOC_ARR(layer_ids, nr_layers);
523  ST_ASSERT_FATAL(layer_ids != NULL);
524  rc = layout_composite_add_layers(layout, nr_layers, layer_ids);
525  ST_ASSERT_FATAL(rc == 0);
526 
527  /* Create a new object with the captured layout.*/
528  rc = layout_composite_create_obj(layout, &id);
529  ST_ASSERT_FATAL(rc == 0);
530 
531 
532  /* Prepare and issue LAYOUT_GET op. */
533  M0_SET0(&obj);
535  &id, layout_id);
536  st_entity_open(&obj.ob_entity);
539 
540  layout_to_check = m0_client_layout_alloc(M0_LT_COMPOSITE);
541  ST_ASSERT_FATAL(layout_to_check != NULL);
543  layout_to_check, &ops[0]);
546  M0_OS_STABLE),
547  M0_TIME_NEVER);
548  ST_ASSERT_FATAL(rc == 0);
549  ST_ASSERT_FATAL(ops[0]->op_sm.sm_state == M0_OS_STABLE);
550  ST_ASSERT_FATAL(ops[0]->op_rc == 0);
551 
552  st_op_fini(ops[0]);
553  st_op_free(ops[0]);
554  st_entity_fini(&obj.ob_entity);
555 
556  /* Check returned layout. */
557  clayout = M0_AMB(clayout, layout, ccl_layout);
558  clayout_to_check =
559  M0_AMB(clayout_to_check, layout_to_check, ccl_layout);
561  clayout->ccl_nr_layers == clayout->ccl_nr_layers);
562 
563  m0_client_layout_free(layout);
564  m0_client_layout_free(layout_to_check);
565 }
566 
567 /*---------------------------------------------------------------------------*
568  * Composite IO *
569  *---------------------------------------------------------------------------*/
570 
575 };
576 
577 struct io_seg {
580 };
581 
582 static int write_io_segs(struct m0_uint128 id, int nr_io_segs,
583  struct io_seg *io_segs)
584 {
585  int i;
586  int rc;
587  char value;
588  struct m0_obj obj;
589  struct m0_op *ops[1] = {NULL};
590  struct m0_indexvec ext;
591  struct m0_bufvec data;
592  struct m0_bufvec attr;
593 
594  /* Prepare the data with 'value' */
595  rc = m0_bufvec_empty_alloc(&data, nr_io_segs);
596  if (rc != 0)
597  return rc;
598 
599  for (i = 0; i < nr_io_segs; i++) {
600  data.ov_vec.v_count[i] = io_segs[i].is_len;
601  data.ov_buf[i] = m0_alloc(io_segs[i].is_len);
602  if (data.ov_buf[i] == NULL)
603  goto free;
604 
605  /*
606  * The pattern written to object has to match
607  * to those in read tests
608  */
609  value = pattern[i % CHAR_NUM];
610  memset(data.ov_buf[i], value, io_segs[i].is_len);
611  }
612 
613  /* Prepare indexvec and attr for write */
614  rc = m0_bufvec_alloc(&attr, nr_io_segs, 1);
615  if(rc != 0)
616  goto free;
617  rc = m0_indexvec_alloc(&ext, nr_io_segs);
618  if (rc != 0)
619  goto free;
620  for (i = 0; i < nr_io_segs; i++) {
621  ext.iv_index[i] = io_segs[i].is_off;
622  ext.iv_vec.v_count[i] = io_segs[i].is_len;
623 
624  /* we don't want any attributes */
625  attr.ov_vec.v_count[i] = 0;
626  }
627 
628  /* Write to object */
629  memset(&obj, 0, sizeof obj);
630  st_obj_init(
632  &id, layout_id);
633  st_entity_open(&obj.ob_entity);
634  st_obj_op(&obj, M0_OC_WRITE, &ext, &data, NULL, 0, 0, &ops[0]);
635  st_op_launch(ops, 1);
637  M0_OS_STABLE),
638  M0_TIME_NEVER);
639 
640  /* fini and release */
641  st_op_fini(ops[0]);
642  st_op_free(ops[0]);
643  st_entity_fini(&obj.ob_entity);
644 
645 free:
648  m0_indexvec_free(&ext);
649  return rc;
650 }
651 
652 static int fill_ext_kv_pairs(struct composite_extent *exts, int nr_exts,
653  struct m0_bufvec *keys, struct m0_bufvec *vals)
654 {
655  int i;
656  int rc;
657  int nr_kvp;
660 
661 
662  nr_kvp = keys->ov_vec.v_nr;
663  for (i = 0; i < nr_kvp; i++) {
664  /* Set key and value. */
665  key.cek_layer_id = exts[i].ce_id;
666  key.cek_off = exts[i].ce_off;
667  val.cev_len = exts[i].ce_len;
669  &key, &keys->ov_buf[i], &keys->ov_vec.v_count[i])?:
671  &val, &vals->ov_buf[i], &vals->ov_vec.v_count[i]);
672  if (rc != 0)
673  return rc;
674  }
675 
676  return 0;
677 }
678 
679 static int do_add_extents(struct m0_uint128 id,
680  struct m0_bufvec *keys,
681  struct m0_bufvec *vals,
682  int *rcs)
683 {
684  int rc;
685  struct m0_op *ops[1] = {NULL};
686  struct m0_idx idx;
687 
688  memset(&idx, 0, sizeof idx);
689  ops[0] = NULL;
690 
691  m0_composite_layer_idx(id, true, &idx);
692  st_idx_op(&idx, M0_IC_PUT, keys, vals, rcs, 0, &ops[0]);
693  st_op_launch(ops, 1);
694  rc = st_op_wait(ops[0],
696  M0_OS_STABLE),
697  M0_TIME_NEVER);
698  rc = rc != 0?rc:ops[0]->op_sm.sm_rc;
699 
700  /* fini and release */
701  st_op_fini(ops[0]);
702  st_op_free(ops[0]);
704 
705  return rc;
706 }
707 
708 static int
709 add_extents(struct m0_uint128 id, int nr_exts, struct composite_extent *exts)
710 {
711  int rc;
712  struct m0_bufvec keys;
713  struct m0_bufvec vals;
714  int *rcs = NULL;
715 
716  /* Allocate bufvec's for keys and vals. */
717  rc = m0_bufvec_empty_alloc(&keys, nr_exts)?:
718  m0_bufvec_empty_alloc(&vals, nr_exts);
719  if (rc != 0) {
720  rc = -ENOMEM;
721  goto exit;
722  }
723  M0_ALLOC_ARR(rcs, nr_exts);
724  if (rcs == NULL) {
725  rc = -ENOMEM;
726  goto exit;
727  }
728 
729  /* Fill keys and values with some data. */
730  rc = fill_ext_kv_pairs(exts, nr_exts, &keys, &vals);
731  if (rc < 0)
732  goto exit;
733 
734  /* Do the real job. */
735  rc = do_add_extents(id, &keys, &vals, rcs);
736 
737 exit:
738  m0_bufvec_free(&keys);
739  m0_bufvec_free(&vals);
740  m0_free0(&rcs);
741  return rc;
742 }
743 
745 {
746  int i;
747  int j;
748  int rc;
749  int nr_comp_exts = 0;
750  int nr_io_segs;
751  int nr_layers;
752  struct m0_uint128 id;
753  struct m0_uint128 *layer_ids;
754  struct m0_client_layout *layout;
755  struct io_seg *io_segs;
756  struct composite_extent *comp_exts;
757  m0_bindex_t off;
758  m0_bcount_t len;
759 
760  /* Create a composite layout with layers. */
762  ST_ASSERT_FATAL(layout != NULL);
763 
764  nr_layers = 3;
765  M0_ALLOC_ARR(layer_ids, nr_layers);
766  ST_ASSERT_FATAL(layer_ids != NULL);
767  rc = layout_composite_add_layers(layout, nr_layers, layer_ids);
768  ST_ASSERT_FATAL(rc == 0);
769 
770  /* Create a new object with the captured layout.*/
771  rc = layout_composite_create_obj(layout, &id);
772  ST_ASSERT_FATAL(rc == 0);
773 
774  /* Add extents to one layer. */
775  nr_comp_exts = 10;
776  M0_ALLOC_ARR(comp_exts, nr_comp_exts);
777  ST_ASSERT_FATAL(comp_exts != NULL);
778  for (i = 0; i < nr_layers; i++) {
779  off = 0;
780  for (j = 0; j < nr_comp_exts; j++) {
781  len = (j + 1) *1024 * 1024;
782 
783  /* Set key and value. */
784  comp_exts[j].ce_id = layer_ids[i];
785  comp_exts[j].ce_off = off;
786  comp_exts[j].ce_len = len;
787 
788  off += len + 1024 * 1024;
789  }
790  rc = add_extents(layer_ids[i], nr_comp_exts, comp_exts);
791  ST_ASSERT_FATAL(rc == 0);
792  }
793 
794  /* Write to the newly created object above.*/
795  nr_io_segs= 4;
796  M0_ALLOC_ARR(io_segs, nr_io_segs);
797  ST_ASSERT_FATAL(io_segs != NULL);
798  for (i = 0; i < nr_io_segs; i++) {
799  io_segs[i].is_off = i * unit_size;
800  io_segs[i].is_len = unit_size;
801  }
802  rc = write_io_segs(id, nr_io_segs, io_segs);
803  ST_ASSERT_FATAL(rc == 0);
804 
805  m0_client_layout_free(layout);
806  m0_free(layer_ids);
807  m0_free(comp_exts);
808  m0_free(io_segs);
809 }
810 
812 {
813  int i;
814  int rc;
815  int nr_io_segs;
816  int nr_layers;
817  struct m0_uint128 id;
818  struct m0_uint128 *layer_ids;
819  struct m0_client_layout *layout;
820  struct io_seg *io_segs;
821  struct composite_extent comp_ext;
822  m0_bindex_t off;
823  m0_bcount_t len;
824 
825  /* Create a composite layout with layers. */
827  ST_ASSERT_FATAL(layout != NULL);
828 
829  nr_layers = 3;
830  M0_ALLOC_ARR(layer_ids, nr_layers);
831  ST_ASSERT_FATAL(layer_ids != NULL);
832  rc = layout_composite_add_layers(layout, nr_layers, layer_ids);
833  ST_ASSERT_FATAL(rc == 0);
834 
835  /* Create a new object with the captured layout.*/
836  rc = layout_composite_create_obj(layout, &id);
837  ST_ASSERT_FATAL(rc == 0);
838 
839  /* Add extents to one layer. */
840  off = 0;
841  for (i = 0; i < nr_layers; i++) {
842  /* Set key and value. */
843  off = i * 16 * unit_size;
844  len = 16 * unit_size;
845  comp_ext.ce_id = layer_ids[i];
846  comp_ext.ce_off = off;
847  comp_ext.ce_len = len;
848  rc = add_extents(layer_ids[i], 1, &comp_ext);
849  ST_ASSERT_FATAL(rc == 0);
850  }
851 
852  /* Write to the newly created object above.*/
853  nr_io_segs= 3;
854  M0_ALLOC_ARR(io_segs, nr_io_segs);
855  ST_ASSERT_FATAL(io_segs != NULL);
856  for (i = 0; i < nr_io_segs; i++) {
857  io_segs[i].is_off = i * 16 * unit_size;
858  io_segs[i].is_len = 16 * unit_size;
859  }
860  rc = write_io_segs(id, nr_io_segs, io_segs);
861  ST_ASSERT_FATAL(rc == 0);
862 
863  m0_client_layout_free(layout);
864  m0_free(layer_ids);
865  m0_free(io_segs);
866 }
868 {
869  int i;
870  int rc;
871  int nr_io_segs;
872  int nr_layers;
873  struct m0_uint128 id;
874  struct m0_uint128 *layer_ids;
875  struct m0_client_layout *layout;
876  struct io_seg *io_segs;
877  struct composite_extent comp_ext;
878  m0_bindex_t off;
879  m0_bcount_t len;
880 
881  /* Create a composite layout with layers. */
883  ST_ASSERT_FATAL(layout != NULL);
884 
885  nr_layers = 3;
886  M0_ALLOC_ARR(layer_ids, nr_layers);
887  ST_ASSERT_FATAL(layer_ids != NULL);
888  rc = layout_composite_add_layers(layout, nr_layers, layer_ids);
889  ST_ASSERT_FATAL(rc == 0);
890 
891  /* Create a new object with the captured layout.*/
892  rc = layout_composite_create_obj(layout, &id);
893  ST_ASSERT_FATAL(rc == 0);
894 
895  /* Add extents to one layer. */
896  off = 0;
897  for (i = 0; i < nr_layers; i++) {
898  /* Set key and value. */
899  len = 16 * unit_size;
900  comp_ext.ce_id = layer_ids[i];
901  comp_ext.ce_off = off;
902  comp_ext.ce_len = len;
903  rc = add_extents(layer_ids[i], 1, &comp_ext);
904  ST_ASSERT_FATAL(rc == 0);
905  off += len - 4 * unit_size;
906  }
907 
908  /* Write to the newly created object above.*/
909  nr_io_segs= 3;
910  M0_ALLOC_ARR(io_segs, nr_io_segs);
911  ST_ASSERT_FATAL(io_segs != NULL);
912  for (i = 0; i < nr_io_segs; i++) {
913  io_segs[i].is_off = i * 16 * unit_size;
914  if (i == nr_io_segs - 1)
915  io_segs[i].is_len = (16 - 8) * unit_size;
916  else
917  io_segs[i].is_len = 16 * unit_size;
918  }
919  rc = write_io_segs(id, nr_io_segs, io_segs);
920  ST_ASSERT_FATAL(rc == 0);
921 
922  m0_client_layout_free(layout);
923  m0_free(layer_ids);
924  m0_free(io_segs);
925 }
926 
928 {
929  int i;
930  int rc;
931  int nr_comp_exts = 0;
932  int nr_io_segs;
933  struct m0_uint128 orig_id;
934  struct m0_uint128 cap_id;
935  struct m0_uint128 id;
936  struct m0_client_layout *orig_layout;
937  struct m0_client_layout *cap_layout;
938  struct m0_client_layout *layout;
939  struct m0_op *ops[] = {NULL};
940  struct m0_obj *orig_obj;
941  struct m0_obj obj;
942  struct io_seg *io_segs;
943  struct composite_extent *comp_exts;
944  m0_bindex_t off;
945  m0_bcount_t len;
946 
947  /* Create an object with default layout type (PDCLUST). */
948  oid_get(&orig_id);
949  create_obj(orig_id);
950 
951  /*
952  * Sample code to capture layout and set an object with
953  * captured layout.
954  */
955  M0_ALLOC_PTR(orig_obj);
956  ST_ASSERT_FATAL(orig_obj != NULL);
957 
958  /* 1. Initialise in-memory object data struct. */
960  &orig_id, layout_id);
961 
962  /* 2. Open the object to get its attributes. */
963  st_entity_open(&orig_obj->ob_entity);
965  M0_LT_PDCLUST);
966 
967  /* 3. Issue LAYOUT_GET op. */
968  orig_layout = m0_client_layout_alloc(M0_LT_PDCLUST);
969  ST_ASSERT_FATAL(orig_layout != NULL);
970 
971  rc = st_layout_op(orig_obj, M0_EO_LAYOUT_GET,
972  orig_layout, &ops[0]);
973  ST_ASSERT_FATAL(rc == 0);
974  ST_ASSERT_FATAL(ops[0] != NULL);
975  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
976 
979  M0_OS_STABLE),
980  M0_TIME_NEVER);
981  ST_ASSERT_FATAL(rc == 0);
982  ST_ASSERT_FATAL(ops[0]->op_sm.sm_state == M0_OS_STABLE);
983  ST_ASSERT_FATAL(ops[0]->op_sm.sm_rc == 0);
984 
985  st_op_fini(ops[0]);
986  st_op_free(ops[0]);
987  ops[0] = NULL;
988 
989  /* 4. Capture layout. */
990  rc = m0_client_layout_capture(orig_layout, orig_obj, &cap_layout);
991  ST_ASSERT_FATAL(rc == 0);
992  ST_ASSERT_FATAL(cap_layout != NULL);
993 
994  /* 5. Create a new object with the captured layout.*/
995  rc = layout_create_capture_obj(cap_layout, &cap_id);
996  ST_ASSERT_FATAL(rc == 0);
997 
998  /* 6. Create a composite layout including the capture subobject. */
1000  ST_ASSERT_FATAL(layout != NULL);
1001 
1002  M0_SET0(&obj);
1004  &cap_id, layout_id);
1005  rc = m0_composite_layer_add(layout, &obj, 0);
1006  ST_ASSERT_FATAL(rc == 0);
1007  st_entity_fini(&obj.ob_entity);
1008 
1009  rc = layout_composite_create_obj(layout, &id);
1010  ST_ASSERT_FATAL(rc == 0);
1011 
1012  /* Add extents to one layer. */
1013  nr_comp_exts = 10;
1014  M0_ALLOC_ARR(comp_exts, nr_comp_exts);
1015  ST_ASSERT_FATAL(comp_exts != NULL);
1016 
1017  off = 0;
1018  for (i = 0; i < nr_comp_exts; i++) {
1019  len = (i + 1) *1024 * 1024;
1020 
1021  /* Set key and value. */
1022  comp_exts[i].ce_id = cap_id;
1023  comp_exts[i].ce_off = off;
1024  comp_exts[i].ce_len = len;
1025 
1026  off += len + 1024 * 1024;
1027  }
1028  rc = add_extents(cap_id, nr_comp_exts, comp_exts);
1029  ST_ASSERT_FATAL(rc == 0);
1030 
1031  /* 7. Write to the newly created object above.*/
1032  nr_io_segs= 4;
1033  M0_ALLOC_ARR(io_segs, nr_io_segs);
1034  ST_ASSERT_FATAL(io_segs != NULL);
1035  for (i = 0; i < nr_io_segs; i++) {
1036  io_segs[i].is_off = i * unit_size;
1037  io_segs[i].is_len = unit_size;
1038  }
1039  rc = write_io_segs(id, nr_io_segs, io_segs);
1040  ST_ASSERT_FATAL(rc == 0);
1041 
1042  /* Fini and free entities and layouts. */
1043  m0_client_layout_free(cap_layout);
1044  st_entity_fini(&orig_obj->ob_entity);
1045  m0_client_layout_free(orig_layout);
1046  m0_free(orig_obj);
1047 
1048  m0_client_layout_free(layout);
1049  m0_free(comp_exts);
1050  m0_free(io_segs);
1051 }
1052 
1054 {
1055  int i;
1056  int j;
1057  int rc;
1058  int nr_comp_exts = 0;
1059  int nr_layers;
1060  struct m0_uint128 id;
1061  struct m0_uint128 *layer_ids;
1062  struct m0_client_layout *layout;
1063  struct composite_extent *comp_exts;
1064  m0_bindex_t off;
1065  m0_bcount_t len;
1066 
1067  /* Create a composite layout with layers. */
1069  ST_ASSERT_FATAL(layout != NULL);
1070 
1071  nr_layers = 3;
1072  M0_ALLOC_ARR(layer_ids, nr_layers);
1073  ST_ASSERT_FATAL(layer_ids != NULL);
1074  rc = layout_composite_add_layers(layout, nr_layers, layer_ids);
1075  ST_ASSERT_FATAL(rc == 0);
1076 
1077  /* Create a new object with composite layout.*/
1078  rc = layout_composite_create_obj(layout, &id);
1079  ST_ASSERT_FATAL(rc == 0);
1080 
1081  /* Add extents to one layer. */
1082  for (i = 0; i < nr_layers; i++) {
1083  off = 0;
1084  nr_comp_exts = 10;
1085  M0_ALLOC_ARR(comp_exts, nr_comp_exts);
1086  ST_ASSERT_FATAL(comp_exts != NULL);
1087  for (j = 0; j < nr_comp_exts; j++) {
1088  len = (j + 1) *1024 * 1024;
1089 
1090  /* Set key and value. */
1091  comp_exts[j].ce_id = layer_ids[i];
1092  comp_exts[j].ce_off = off;
1093  comp_exts[j].ce_len = len;
1094 
1095  off += len + 1024 * 1024;
1096  }
1097  rc = add_extents(layer_ids[i], nr_comp_exts, comp_exts);
1098  ST_ASSERT_FATAL(rc == 0);
1099  }
1100 
1101  m0_client_layout_free(layout);
1102  m0_free(layer_ids);
1103  m0_free(comp_exts);
1104 }
1105 
1109 static int st_layout_suite_init(void)
1110 {
1111  int rc;
1112 
1113  /*
1114  * Retrieve the uber realm. We don't need to open this,
1115  * as realms are not actually implemented yet
1116  */
1118  &M0_UBER_REALM,
1119  st_get_instance());
1121 
1122  if (rc != 0)
1123  console_printf("Failed to open uber realm\n");
1124 
1125  test_id = M0_ID_APP;
1126  test_id.u_lo += generate_random(0xffff);
1127 
1129  return rc;
1130 }
1131 
1135 static int st_layout_suite_fini(void)
1136 {
1137  return 0;
1138 }
1139 
1141  .ss_name = "layout_st",
1142  .ss_init = st_layout_suite_init,
1143  .ss_fini = st_layout_suite_fini,
1144  .ss_tests = {
1145  { "layout_op_get_obj",
1147  { "layout_capture",
1148  &layout_capture},
1149  { "layout_capture_io",
1151  { "layout_composite_create",
1153  { "layout_composite_create_then_get",
1155  { "layout_composite_extent_idx",
1157  { "layout_composite_io_one_layer",
1159  { "layout_composite_io_multi_layers",
1161  { "layout_composite_io_overlapping_layers",
1163  { "layout_composite_io_on_capture_layer",
1165  { NULL, NULL }
1166  }
1167 };
1168 
1169 #undef M0_TRACE_SUBSYSTEM
1170 
1171 /*
1172  * Local variables:
1173  * c-indentation-style: "K&R"
1174  * c-basic-offset: 8
1175  * tab-width: 8
1176  * fill-column: 80
1177  * scroll-step: 1
1178  * End:
1179  */
uint64_t id
Definition: cob.h:2380
m0_bindex_t is_off
Definition: layout.c:578
int st_entity_create(struct m0_fid *pool, struct m0_entity *entity, struct m0_op **op)
Definition: api.c:71
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
static int st_layout_suite_fini(void)
Definition: layout.c:1135
enum m0_client_layout_type m0_obj_layout_type(struct m0_obj *obj)
Definition: obj.c:879
Definition: client.h:835
void st_op_free(struct m0_op *op)
Definition: api.c:147
Definition: layout.c:577
Definition: client.h:788
M0_INTERNAL int m0_indexvec_alloc(struct m0_indexvec *ivec, uint32_t len)
Definition: vec.c:532
#define NULL
Definition: misc.h:38
static int fill_ext_kv_pairs(struct composite_extent *exts, int nr_exts, struct m0_bufvec *keys, struct m0_bufvec *vals)
Definition: layout.c:652
Definition: idx_mock.c:52
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
static void layout_composite_io_overlapping_layers(void)
Definition: layout.c:867
static int layout_composite_create_obj(struct m0_client_layout *layout, struct m0_uint128 *ret_id)
Definition: layout.c:399
#define MEM_ALLOC_PTR(arr)
Definition: st_misc.h:81
struct m0_vec ov_vec
Definition: vec.h:147
m0_bindex_t ce_off
Definition: layout.c:573
struct m0_bufvec data
Definition: di.c:40
int const char const void * value
Definition: dir.c:325
uint64_t m0_client_layout_id(const struct m0_client *instance)
Definition: obj.c:859
M0_INTERNAL void m0_indexvec_free(struct m0_indexvec *ivec)
Definition: vec.c:553
uint64_t m0_bindex_t
Definition: types.h:80
static int do_add_extents(struct m0_uint128 id, struct m0_bufvec *keys, struct m0_bufvec *vals, int *rcs)
Definition: layout.c:679
#define M0_BITS(...)
Definition: misc.h:236
uint64_t m0_bcount_t
Definition: types.h:77
static int write_obj(struct m0_uint128 id)
Definition: layout.c:90
int st_idx_op(struct m0_idx *idx, enum m0_idx_opcode opcode, struct m0_bufvec *keys, struct m0_bufvec *vals, int *rcs, int flag, struct m0_op **op)
Definition: api.c:113
#define M0_SET0(obj)
Definition: misc.h:64
const struct m0_uint128 M0_UBER_REALM
Definition: client.c:85
static int layout_create_capture_obj(struct m0_client_layout *layout, struct m0_uint128 *ret_id)
Definition: layout.c:219
struct m0_uint128 ce_id
Definition: layout.c:572
#define ST_ASSERT_FATAL(a)
Definition: st_assert.h:31
void ** ov_buf
Definition: vec.h:149
static struct foo * obj
Definition: tlist.c:302
static void layout_composite_create_then_get(void)
Definition: layout.c:504
const struct m0_uint128 M0_ID_APP
Definition: client.c:92
M0_INTERNAL int m0_bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size)
Definition: vec.c:220
struct m0_vec iv_vec
Definition: vec.h:139
static uint32_t unit_size
Definition: layout.c:53
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
m0_bindex_t * iv_index
Definition: vec.h:141
struct m0_entity in_entity
Definition: client.h:836
int i
Definition: dir.c:1033
static void layout_op_get_obj(void)
Definition: layout.c:170
struct m0_realm co_realm
Definition: client.h:881
Definition: client.h:641
struct m0_client_layout * m0_client_layout_alloc(enum m0_client_layout_type type)
Definition: layout.c:473
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
static uint64_t layout_id
Definition: layout.c:52
static int st_layout_suite_init(void)
Definition: layout.c:1109
static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:949
struct m0_entity re_entity
Definition: client.h:871
int oid_get(struct m0_uint128 *oid)
Definition: oid.c:373
#define m0_free0(pptr)
Definition: memory.h:77
void m0_client_layout_free(struct m0_client_layout *layout)
Definition: layout.c:504
#define M0_ASSERT(cond)
int m0_composite_layer_idx(struct m0_uint128 layer_id, bool write, struct m0_idx *idx)
Definition: st.h:83
int m0_composite_layer_idx_key_to_buf(struct m0_composite_layer_idx_key *key, void **out_kbuf, m0_bcount_t *out_klen)
static void layout_capture(void)
Definition: layout.c:256
struct m0_client_layout ccl_layout
Definition: layout.h:157
void * m0_alloc(size_t size)
Definition: memory.c:126
void m0_composite_layer_del(struct m0_client_layout *layout, struct m0_uint128 subobj_id)
struct m0_container st_layout_container
Definition: layout.c:51
uint32_t v_nr
Definition: vec.h:51
int32_t sm_rc
Definition: sm.h:336
static int layout_composite_add_layers(struct m0_client_layout *layout, int nr_layers, struct m0_uint128 *layer_ids)
Definition: layout.c:435
m0_bcount_t * v_count
Definition: vec.h:53
void console_printf(const char *fmt,...)
Definition: st_misc.c:155
static void mem_free(const struct m0_be_btree *btree, struct m0_be_tx *tx, void *ptr)
Definition: btree.c:102
static void layout_composite_extent_idx(void)
Definition: layout.c:1053
struct st_suite st_suite_layout
Definition: layout.c:1140
void st_obj_init(struct m0_obj *obj, struct m0_realm *parent, const struct m0_uint128 *id, uint64_t layout_id)
Definition: api.c:42
static void layout_composite_io_one_layer(void)
Definition: layout.c:744
static char pattern[CHAR_NUM]
Definition: layout.c:48
static struct m0_uint128 test_id
Definition: layout.c:50
static int create_obj(struct m0_uint128 id)
Definition: layout.c:58
static int rc
Definition: layout.c:51
void st_obj_op(struct m0_obj *obj, enum m0_obj_opcode opcode, struct m0_indexvec *ext, struct m0_bufvec *data, struct m0_bufvec *attr, uint64_t mask, uint32_t flags, struct m0_op **op)
Definition: api.c:100
static int add_extents(struct m0_uint128 id, int nr_exts, struct composite_extent *exts)
Definition: layout.c:709
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
static void layout_composite_io_on_capture_layer(void)
Definition: layout.c:927
int m0_composite_layer_add(struct m0_client_layout *layout, struct m0_obj *sub_obj, int priority)
struct m0_client * st_get_instance()
Definition: st.c:57
m0_bcount_t is_len
Definition: layout.c:579
#define M0_CLIENT_THREAD_ENTER
struct m0_entity ob_entity
Definition: client.h:789
void st_op_launch(struct m0_op **op, uint32_t nr)
Definition: api.c:129
void st_entity_fini(struct m0_entity *entity)
Definition: api.c:94
uint32_t generate_random(uint32_t max)
Definition: st_misc.c:164
const char * ss_name
Definition: st.h:85
static void layout_composite_create(void)
Definition: layout.c:475
int m0_client_layout_capture(struct m0_client_layout *layout, struct m0_obj *obj, struct m0_client_layout **out)
Definition: layout.c:138
void m0_container_init(struct m0_container *con, struct m0_realm *parent, const struct m0_uint128 *id, struct m0_client *instance)
Definition: realm.c:31
void st_entity_open(struct m0_entity *entity)
Definition: api.c:153
struct m0_sm en_sm
Definition: client.h:732
struct m0_fom_ops ops
Definition: io_foms.c:623
uint64_t u_lo
Definition: types.h:37
static void layout_capture_io(void)
Definition: layout.c:327
void m0_free(void *data)
Definition: memory.c:146
int32_t st_op_wait(struct m0_op *op, uint64_t bits, m0_time_t to)
Definition: api.c:136
void st_op_fini(struct m0_op *op)
Definition: api.c:142
static void layout_composite_io_multi_layers(void)
Definition: layout.c:811
#define ARRAY_SIZE(a)
Definition: misc.h:45
static int write_io_segs(struct m0_uint128 id, int nr_io_segs, struct io_seg *io_segs)
Definition: layout.c:582
int m0_composite_layer_idx_val_to_buf(struct m0_composite_layer_idx_val *val, void **out_vbuf, m0_bcount_t *out_vlen)
Definition: vec.h:145
m0_bcount_t ce_len
Definition: layout.c:574
M0_INTERNAL int m0_bufvec_empty_alloc(struct m0_bufvec *bufvec, uint32_t num_segs)
Definition: vec.c:213
int st_layout_op(struct m0_obj *obj, enum m0_entity_opcode opcode, struct m0_client_layout *layout, struct m0_op **op)
Definition: api.c:183
Definition: idx_mock.c:47