Motr  M0
vec.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-2021 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 "lib/arith.h" /* min3 */
24 #include "lib/vec.h"
25 #include "lib/assert.h"
26 #include "lib/memory.h"
27 #include "lib/misc.h" /* M0_SET0, memcpy */
28 #include "lib/errno.h"
29 #include "lib/finject.h"
30 
31 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_LIB
32 #include "lib/trace.h"
33 
39 M0_BASSERT(M0_SEG_SIZE == M0_0VEC_ALIGN);
40 
41 static m0_bcount_t vec_count(const struct m0_vec *vec, uint32_t i)
42 {
44 
45  for (count = 0; i < vec->v_nr; ++i) {
46  /* overflow check */
47  M0_ASSERT_EX(count + vec->v_count[i] >= count);
48  count += vec->v_count[i];
49  }
50  return count;
51 }
52 
53 M0_INTERNAL m0_bcount_t m0_vec_count(const struct m0_vec *vec)
54 {
55  return vec_count(vec, 0);
56 }
57 
58 M0_INTERNAL bool m0_vec_is_empty(const struct m0_vec *vec)
59 {
60  uint32_t i;
61 
62  for (i = 0; i < vec->v_nr; ++i)
63  if (vec->v_count[i] > 0)
64  return false;
65 
66  return true;
67 }
68 
69 static bool m0_vec_cursor_invariant(const struct m0_vec_cursor *cur)
70 {
71  return
72  cur->vc_vec != NULL &&
73  cur->vc_seg <= cur->vc_vec->v_nr &&
74  ergo(cur->vc_seg < cur->vc_vec->v_nr,
75  cur->vc_offset < cur->vc_vec->v_count[cur->vc_seg]) &&
76  ergo(cur->vc_seg == cur->vc_vec->v_nr,
77  cur->vc_offset == 0);
78 }
79 
84 {
85  while (cur->vc_seg < cur->vc_vec->v_nr &&
86  cur->vc_vec->v_count[cur->vc_seg] == 0) {
87  ++cur->vc_seg;
88  cur->vc_offset = 0;
89  }
90 }
91 
92 M0_INTERNAL void m0_vec_cursor_init(struct m0_vec_cursor *cur,
93  const struct m0_vec *vec)
94 {
95  cur->vc_vec = vec;
96  cur->vc_seg = 0;
97  cur->vc_offset = 0;
100 }
101 
102 M0_INTERNAL bool m0_vec_cursor_move(struct m0_vec_cursor *cur,
104 {
105  m0_bcount_t step;
106 
108  while (count > 0 && cur->vc_seg < cur->vc_vec->v_nr) {
109  step = m0_vec_cursor_step(cur);
110  if (count >= step) {
111  cur->vc_seg++;
112  cur->vc_offset = 0;
113  count -= step;
114  } else {
115  cur->vc_offset += count;
116  count = 0;
117  }
119  }
121 
122  return cur->vc_seg == cur->vc_vec->v_nr;
123 }
124 
126 {
127  M0_PRE(cur->vc_seg < cur->vc_vec->v_nr);
129  return cur->vc_vec->v_count[cur->vc_seg] - cur->vc_offset;
130 }
131 
132 M0_INTERNAL m0_bcount_t m0_vec_cursor_end(const struct m0_vec_cursor *cur)
133 {
134  return m0_vec_cursor_step(cur) +
135  vec_count(cur->vc_vec, cur->vc_seg + 1);
136 }
137 
138 
139 static int bufvec_alloc(struct m0_bufvec *bufvec,
140  uint32_t num_segs,
142  unsigned shift,
143  bool pack)
144 {
145  uint32_t i;
146 #ifdef __KERNEL__
147  M0_ASSERT(!pack);
148 #endif
149 
150  M0_PRE(num_segs > 0);
151  M0_PRE(ergo(shift != 0, seg_size > 0));
152  bufvec->ov_buf = NULL;
153  bufvec->ov_vec.v_nr = num_segs;
154 
155  M0_ALLOC_ARR(bufvec->ov_vec.v_count, num_segs);
156  if (bufvec->ov_vec.v_count == NULL)
157  goto fail;
158 
159  M0_ALLOC_ARR(bufvec->ov_buf, num_segs);
160  if (bufvec->ov_buf == NULL)
161  goto fail;
162 
163  if (M0_FI_ENABLED("empty-fail")) {
164  /* to panic if we try to m0_free() it */
165  bufvec->ov_buf[0] = (void*)1;
166  goto fail;
167  }
168 
169  if (seg_size != 0) {
170  void *addr = NULL;
171  if (pack) {
172  M0_ASSERT(shift != 0);
173  addr = m0_alloc_aligned(seg_size * num_segs, shift);
174  }
175 
176  for (i = 0; i < num_segs; ++i) {
177  if (shift != 0) {
178  if (pack)
179  bufvec->ov_buf[i] = addr + i * seg_size;
180  else
181  bufvec->ov_buf[i] =
183  shift);
184  } else
185  bufvec->ov_buf[i] = m0_alloc(seg_size);
186 
187  if (bufvec->ov_buf[i] == NULL)
188  goto fail;
189  if (M0_FI_ENABLED("buf-alloc-fail"))
190  goto fail;
191  bufvec->ov_vec.v_count[i] = seg_size;
192  }
193  }
194  return 0;
195 
196 fail:
197  if (seg_size != 0)
198  m0_bufvec_free(bufvec);
199  else
200  m0_bufvec_free2(bufvec);
201 
202  return M0_ERR(-ENOMEM);
203 }
204 
205 static int m0__bufvec_alloc(struct m0_bufvec *bufvec,
206  uint32_t num_segs,
208  unsigned shift)
209 {
210  return bufvec_alloc(bufvec, num_segs, seg_size, shift, false);
211 }
212 
213 M0_INTERNAL int m0_bufvec_empty_alloc(struct m0_bufvec *bufvec,
214  uint32_t num_segs)
215 {
216  return m0__bufvec_alloc(bufvec, num_segs, 0, 0);
217 }
218 M0_EXPORTED(m0_bufvec_empty_alloc);
219 
220 M0_INTERNAL int m0_bufvec_alloc(struct m0_bufvec *bufvec,
221  uint32_t num_segs, m0_bcount_t seg_size)
222 {
223  M0_PRE(seg_size > 0);
224  return m0__bufvec_alloc(bufvec, num_segs, seg_size, 0);
225 }
226 M0_EXPORTED(m0_bufvec_alloc);
227 
228 M0_INTERNAL int m0_bufvec_extend(struct m0_bufvec *bufvec,
229  uint32_t num_segs)
230 {
231  int i = 0;
232  void **new_buf_arr = NULL;
233  uint32_t new_num_segs;
235  m0_bcount_t *new_seg_count_arr;
236 
237  M0_PRE(num_segs > 0);
238  M0_PRE(bufvec != NULL);
239  M0_PRE(bufvec->ov_buf != NULL);
240  M0_PRE(bufvec->ov_vec.v_nr > 0);
241 
242  /* Based on assumption that all segment sizes are equal */
243  seg_size = bufvec->ov_vec.v_count[0];
244  new_num_segs = bufvec->ov_vec.v_nr + num_segs;
245  M0_ALLOC_ARR(new_seg_count_arr, new_num_segs);
246  if (new_seg_count_arr == NULL)
247  goto fail;
248  memcpy(new_seg_count_arr,
249  bufvec->ov_vec.v_count,
250  bufvec->ov_vec.v_nr * sizeof(new_seg_count_arr[0]));
251  M0_ALLOC_ARR(new_buf_arr, new_num_segs);
252  if (new_buf_arr == NULL)
253  goto fail;
254  memcpy(new_buf_arr,
255  bufvec->ov_buf,
256  bufvec->ov_vec.v_nr * sizeof(new_buf_arr[0]));
257  for (i = bufvec->ov_vec.v_nr; i < new_num_segs; ++i) {
258  new_buf_arr[i] = m0_alloc(seg_size);
259  if (new_buf_arr[i] == NULL)
260  goto fail;
261  new_seg_count_arr[i] = seg_size;
262  }
263  m0_free(bufvec->ov_vec.v_count);
264  m0_free(bufvec->ov_buf);
265  bufvec->ov_vec.v_count = new_seg_count_arr;
266  bufvec->ov_buf = new_buf_arr;
267  bufvec->ov_vec.v_nr = new_num_segs;
268 
269  return 0;
270 fail:
271  m0_free(new_seg_count_arr);
272  while (--i >= 0)
273  m0_free(new_buf_arr[i]);
274  m0_free(new_buf_arr);
275 
276  return M0_ERR(-ENOMEM);
277 }
278 M0_EXPORTED(m0_bufvec_extend);
279 
280 M0_INTERNAL int m0_bufvec_merge(struct m0_bufvec *dst_bufvec,
281  struct m0_bufvec *src_bufvec)
282 {
283  uint32_t i;
284  uint32_t new_v_nr;
285  m0_bcount_t *new_v_count;
286  void **new_buf;
287 
288  M0_PRE(dst_bufvec != NULL);
289  M0_PRE(src_bufvec != NULL);
290  M0_PRE(dst_bufvec->ov_buf != NULL);
291  M0_PRE(src_bufvec->ov_buf != NULL);
292  M0_PRE(dst_bufvec->ov_vec.v_nr > 0);
293  M0_PRE(src_bufvec->ov_vec.v_nr > 0);
294 
295  new_v_nr = dst_bufvec->ov_vec.v_nr + src_bufvec->ov_vec.v_nr;
296  M0_ALLOC_ARR(new_v_count, new_v_nr);
297  if (new_v_count == NULL)
298  return M0_ERR(-ENOMEM);
299 
300  M0_ALLOC_ARR(new_buf, new_v_nr);
301  if (new_buf == NULL) {
302  m0_free(new_v_count);
303  return M0_ERR(-ENOMEM);
304  }
305 
306  for (i = 0; i < dst_bufvec->ov_vec.v_nr; ++i) {
307  new_v_count[i] = dst_bufvec->ov_vec.v_count[i];
308  new_buf[i] = dst_bufvec->ov_buf[i];
309  }
310 
311  for (i = 0; i < src_bufvec->ov_vec.v_nr; ++i) {
312  new_v_count[dst_bufvec->ov_vec.v_nr + i] =
313  src_bufvec->ov_vec.v_count[i];
314  new_buf[dst_bufvec->ov_vec.v_nr + i] =
315  src_bufvec->ov_buf[i];
316  }
317 
318  m0_free(dst_bufvec->ov_vec.v_count);
319  m0_free(dst_bufvec->ov_buf);
320  dst_bufvec->ov_vec.v_nr = new_v_nr;
321  dst_bufvec->ov_vec.v_count = new_v_count;
322  dst_bufvec->ov_buf = new_buf;
323 
324  return 0;
325 }
326 M0_EXPORTED(m0_bufvec_merge);
327 
331 M0_INTERNAL int m0__bufvec_dont_dump(struct m0_bufvec *bufvec)
332 {
333  uint32_t i;
334  uint32_t num_segs = bufvec->ov_vec.v_nr;
335  int rc = 0;
336 
337  M0_ENTRY();
338  M0_PRE(num_segs > 0);
339 
340  for (i = 0; i < num_segs; ++i) {
341  rc = m0_dont_dump(bufvec->ov_buf[i],
342  (size_t)bufvec->ov_vec.v_count[i]);
343  if (rc != 0) {
344  M0_LOG(M0_ERROR, "%d: don't dump addr %p+%lu failed: %d",
345  i, bufvec->ov_buf[i],
346  (size_t)bufvec->ov_vec.v_count[i], rc);
347  break;
348  }
349  }
350 
351  return M0_RC(rc);
352 }
353 M0_EXPORTED(m0__bufvec_dont_dump);
354 
355 M0_INTERNAL int m0_bufvec_alloc_aligned(struct m0_bufvec *bufvec,
356  uint32_t num_segs,
357  m0_bcount_t seg_size, unsigned shift)
358 {
359  if (M0_FI_ENABLED("oom"))
360  return M0_ERR(-ENOMEM);
361 
362  return m0__bufvec_alloc(bufvec, num_segs, seg_size, shift);
363 }
364 M0_EXPORTED(m0_bufvec_alloc_aligned);
365 
366 M0_INTERNAL int m0_bufvec_alloc_aligned_packed(struct m0_bufvec *bufvec,
367  uint32_t num_segs,
369  unsigned shift)
370 {
371 
372  return bufvec_alloc(bufvec, num_segs, seg_size, shift,
373 #ifndef __KERNEL__
374  true);
375 #else
376  false);
377 #endif
378 }
379 
380 static void m0_bufvec__free(struct m0_bufvec *bufvec, bool free_bufs)
381 {
382  uint32_t i;
383 
384  if (bufvec != NULL) {
385  if (bufvec->ov_buf != NULL && free_bufs) {
386  for (i = 0; i < bufvec->ov_vec.v_nr; ++i)
387  m0_free(bufvec->ov_buf[i]);
388  }
389  m0_free(bufvec->ov_buf);
390  m0_free(bufvec->ov_vec.v_count);
391  M0_SET0(bufvec);
392  }
393 }
394 
395 M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
396 {
397  m0_bufvec__free(bufvec, true);
398 }
399 M0_EXPORTED(m0_bufvec_free);
400 
401 M0_INTERNAL void m0_bufvec_free2(struct m0_bufvec *bufvec)
402 {
403  m0_bufvec__free(bufvec, false);
404 }
405 M0_EXPORTED(m0_bufvec_free2);
406 
407 M0_INTERNAL void bufvec_free_aligned(struct m0_bufvec *bufvec,
408  unsigned shift,
409  bool pack)
410 {
411 #ifdef __KERNEL__
412  M0_ASSERT(!pack);
413 #endif
414  if (shift == 0)
415  m0_bufvec_free(bufvec);
416  else if (bufvec != NULL) {
417  if (bufvec->ov_buf != NULL) {
418  uint32_t i;
419  if (pack)
420  m0_free_aligned(bufvec->ov_buf[0],
421  vec_count(&bufvec->ov_vec, 0),
422  shift);
423  else {
424  for (i = 0; i < bufvec->ov_vec.v_nr; ++i)
425  m0_free_aligned(bufvec->ov_buf[i],
426  bufvec->ov_vec.v_count[i],
427  shift);
428  }
429  m0_free(bufvec->ov_buf);
430  }
431  m0_free(bufvec->ov_vec.v_count);
432  M0_SET0(bufvec);
433  }
434 }
435 
436 M0_INTERNAL void m0_bufvec_free_aligned(struct m0_bufvec *bufvec,
437  unsigned shift)
438 {
439  return bufvec_free_aligned(bufvec, shift, false);
440 }
441 M0_EXPORTED(m0_bufvec_free_aligned);
442 
443 M0_INTERNAL void m0_bufvec_free_aligned_packed(struct m0_bufvec *bufvec,
444  unsigned shift)
445 {
446 #ifndef __KERNEL__
447  return bufvec_free_aligned(bufvec, shift, true);
448 #else
449  return bufvec_free_aligned(bufvec, shift, false);
450 #endif
451 }
452 
453 
454 static uint32_t vec_pack(uint32_t nr, m0_bcount_t *cnt, m0_bindex_t *idx)
455 {
456  uint32_t i = 0;
457  uint32_t j;
458  m0_bindex_t seg_end;
459 
460  if (nr == 0)
461  return 0;
462 
463  for (j = i + 1; j < nr; ++j) {
464  seg_end = idx[i] + cnt[i];
465  if (idx[j] <= seg_end) {
466  if (cnt[j] > seg_end - idx[j])
467  cnt[i] += cnt[j] - (seg_end - idx[j]);
468  } else {
469  ++i;
470  if (i != j) {
471  idx[i] = idx[j];
472  cnt[i] = cnt[j];
473  }
474  }
475  }
476 
477  return i + 1;
478 }
479 
480 M0_INTERNAL uint32_t m0_bufvec_pack(struct m0_bufvec *bv)
481 {
482  uint32_t new_nr = vec_pack(bv->ov_vec.v_nr, bv->ov_vec.v_count,
483  (m0_bindex_t*)bv->ov_buf);
484  uint32_t diff = bv->ov_vec.v_nr - new_nr;
485 
486  bv->ov_vec.v_nr = new_nr;
487 
488  return diff;
489 }
490 
491 M0_INTERNAL int m0_bufvec_splice(const struct m0_bufvec *bvec, m0_bcount_t nr,
492  struct m0_buf *buf)
493 {
494  m0_bcount_t nob;
495  m0_bcount_t k;
496  uint32_t i;
497  int rc;
498 
499  nob = m0_vec_count(&bvec->ov_vec);
500  M0_PRE(nr <= nob);
501 
502  nob = nr ?: nob;
503  if (nob == 0) {
504  *buf = M0_BUF_INIT0;
505  return M0_RC(0);
506  }
507  rc = m0_buf_alloc(buf, nob);
508  if (rc != 0)
509  return M0_ERR(-ENOMEM);
510  k = 0;
511  for (i = 0; i < bvec->ov_vec.v_nr; i++) {
512  m0_bcount_t moved = min64u(bvec->ov_vec.v_count[i], nob);
513  memcpy((char *)buf->b_addr + k, bvec->ov_buf[i], moved);
514  k += moved;
515  nob -= moved;
516  }
517  M0_POST(nob == 0);
518  return M0_RC(0);
519 }
520 
521 M0_INTERNAL uint32_t m0_indexvec_pack(struct m0_indexvec *iv)
522 {
523  uint32_t new_nr = vec_pack(iv->iv_vec.v_nr, iv->iv_vec.v_count,
524  iv->iv_index);
525  uint32_t diff = iv->iv_vec.v_nr - new_nr;
526 
527  iv->iv_vec.v_nr = new_nr;
528 
529  return diff;
530 }
531 
532 M0_INTERNAL int m0_indexvec_alloc(struct m0_indexvec *ivec,
533  uint32_t len)
534 {
535  M0_PRE(ivec != NULL);
536  M0_PRE(len > 0);
537 
538  M0_ALLOC_ARR(ivec->iv_index, len);
539  if (ivec->iv_index == NULL)
540  return M0_ERR(-ENOMEM);
541 
542  M0_ALLOC_ARR(ivec->iv_vec.v_count, len);
543  if (ivec->iv_vec.v_count == NULL) {
544  m0_free0(&ivec->iv_index);
545  return M0_ERR(-ENOMEM);
546  }
547 
548  ivec->iv_vec.v_nr = len;
549  return 0;
550 }
551 M0_EXPORTED(m0_indexvec_alloc);
552 
553 M0_INTERNAL void m0_indexvec_free(struct m0_indexvec *ivec)
554 {
555  M0_PRE(ivec != NULL);
556 
557  m0_free0(&ivec->iv_index);
558  m0_free0(&ivec->iv_vec.v_count);
559  ivec->iv_vec.v_nr = 0;
560 }
561 M0_EXPORTED(m0_indexvec_free);
562 
563 M0_INTERNAL void m0_bufvec_cursor_init(struct m0_bufvec_cursor *cur,
564  const struct m0_bufvec *bvec)
565 {
566  M0_PRE(cur != NULL);
567  M0_PRE(bvec != NULL &&
568  bvec->ov_vec.v_nr != 0 && bvec->ov_vec.v_count != NULL &&
569  bvec->ov_buf != NULL);
570  m0_vec_cursor_init(&cur->bc_vc, &bvec->ov_vec);
571 }
572 M0_EXPORTED(m0_bufvec_cursor_init);
573 
574 M0_INTERNAL bool m0_bufvec_cursor_move(struct m0_bufvec_cursor *cur,
576 {
577  return m0_vec_cursor_move(&cur->bc_vc, count);
578 }
579 M0_EXPORTED(m0_bufvec_cursor_move);
580 
582  *cur)
583 {
584  return m0_vec_cursor_step(&cur->bc_vc);
585 }
586 M0_EXPORTED(m0_bufvec_cursor_step);
587 
588 M0_INTERNAL void *bufvec_cursor_addr(struct m0_bufvec_cursor *cur)
589 {
590  struct m0_vec_cursor *vc = &cur->bc_vc;
591  struct m0_bufvec *bv = M0_AMB(bv, vc->vc_vec, ov_vec);
592 
594  return bv->ov_buf[vc->vc_seg] + vc->vc_offset;
595 }
596 
597 M0_INTERNAL void *m0_bufvec_cursor_addr(struct m0_bufvec_cursor *cur)
598 {
600  return bufvec_cursor_addr(cur);
601 }
602 M0_EXPORTED(m0_bufvec_cursor_addr);
603 
604 M0_INTERNAL bool m0_bufvec_cursor_align(struct m0_bufvec_cursor *cur,
605  uint64_t alignment)
606 {
607  uint64_t addr;
608  uint64_t count;
609 
610  if (m0_bufvec_cursor_move(cur, 0))
611  return true;
612 
613  addr = (uint64_t)m0_bufvec_cursor_addr(cur);
614  count = m0_align(addr, alignment) - addr;
615 
617 }
618 M0_EXPORTED(m0_bufvec_cursor_align);
619 
621  struct m0_bufvec_cursor *scur,
622  m0_bcount_t num_bytes)
623 {
624  m0_bcount_t bytes_copied = 0;
625 
626  M0_BUFVEC_FOR2(dcur, scur, frag_size) {
627  if (num_bytes == 0)
628  break;
629  frag_size = min_check(frag_size, num_bytes);
630  memmove(bufvec_cursor_addr(dcur), bufvec_cursor_addr(scur),
631  frag_size);
632  num_bytes -= frag_size;
633  bytes_copied += frag_size;
635  return bytes_copied;
636 }
637 M0_EXPORTED(m0_bufvec_cursor_copy);
638 
639 M0_INTERNAL int m0_bufvec_cursor_cmp(struct m0_bufvec_cursor *c0,
640  struct m0_bufvec_cursor *c1)
641 {
642  int result = 0;
643 
644  M0_BUFVEC_FOR2(c0, c1, frag_size) {
645  result = memcmp(bufvec_cursor_addr(c0), bufvec_cursor_addr(c1),
646  frag_size);
647  if (result != 0)
648  break;
650  return result;
651 }
652 M0_EXPORTED(m0_bufvec_cursor_cmp);
653 
655  struct m0_bufvec_cursor *c1)
656 {
657  m0_bcount_t prefix = 0;
658  m0_bcount_t i;
659 
660  M0_BUFVEC_FOR2(c0, c1, frag_size) {
661  char *a0 = bufvec_cursor_addr(c0);
662  char *a1 = bufvec_cursor_addr(c1);
663  /*
664  * Surprisingly, there is no standard library function for
665  * the longest common prefix.
666  */
667  for (i = 0; i < frag_size; i++) {
668  if (a0[i] != a1[i])
669  return prefix + i;
670  }
671  prefix += frag_size;
673  return prefix;
674 }
675 M0_EXPORTED(m0_bufvec_cursor_prefix);
676 
678  void *sdata,
679  m0_bcount_t num_bytes)
680 {
681  struct m0_bufvec_cursor scur;
682  struct m0_bufvec sbuf = M0_BUFVEC_INIT_BUF(&sdata, &num_bytes);
683 
684  M0_PRE(dcur != NULL);
685  M0_PRE(sdata != NULL);
686 
687  m0_bufvec_cursor_init(&scur, &sbuf);
688 
689  return m0_bufvec_cursor_copy(dcur, &scur, num_bytes);
690 }
691 
693  void *ddata,
694  m0_bcount_t num_bytes)
695 {
696  struct m0_bufvec_cursor dcur;
697  struct m0_bufvec dbuf = M0_BUFVEC_INIT_BUF(&ddata, &num_bytes);
698 
699  M0_PRE(scur != NULL);
700  M0_PRE(ddata != NULL);
701 
702  m0_bufvec_cursor_init(&dcur, &dbuf);
703 
704  return m0_bufvec_cursor_copy(&dcur, scur, num_bytes);
705 }
706 
707 M0_INTERNAL void m0_ivec_cursor_init(struct m0_ivec_cursor *cur,
708  const struct m0_indexvec *ivec)
709 {
710  M0_PRE(cur != NULL);
711  M0_PRE(ivec != NULL);
712  M0_PRE(ivec->iv_vec.v_nr > 0);
713  M0_PRE(ivec->iv_vec.v_count != NULL && ivec->iv_index != NULL);
714 
715  m0_vec_cursor_init(&cur->ic_cur, &ivec->iv_vec);
716 }
717 
718 M0_INTERNAL bool m0_ivec_cursor_move(struct m0_ivec_cursor *cur,
720 {
721  M0_PRE(cur != NULL);
722 
723  return m0_vec_cursor_move(&cur->ic_cur, count);
724 }
725 
727 {
728  M0_PRE(cur != NULL);
729 
730  return m0_vec_cursor_step(&cur->ic_cur);
731 }
732 
734 {
735  struct m0_indexvec *ivec;
736 
737  M0_PRE(cur != NULL);
738  M0_PRE(cur->ic_cur.vc_seg < cur->ic_cur.vc_vec->v_nr);
739 
740  ivec = container_of(cur->ic_cur.vc_vec, struct m0_indexvec, iv_vec);
741  return ivec->iv_index[cur->ic_cur.vc_seg] + cur->ic_cur.vc_offset;
742 }
743 
744 M0_INTERNAL bool
746 {
748  bool ret = false;
749 
750  M0_PRE(cur != NULL);
752 
753  while (m0_ivec_cursor_index(cur) != dest) {
757  if (ret)
758  break;
759  }
760 
761  return ret;
762 }
763 
764 M0_INTERNAL m0_bindex_t
766 {
767  uint32_t i;
768  m0_bindex_t idx;
770  m0_bindex_t max_seg_end;
771  struct m0_indexvec *ivec;
772 
773  M0_PRE(cur != NULL);
775 
776  ivec = container_of(cur->ic_cur.vc_vec, struct m0_indexvec, iv_vec);
777 
778  i = cur->ic_cur.vc_seg;
779  max_seg_end = ivec->iv_index[i] + ivec->iv_vec.v_count[i];
780 
781  for (i += 1; i < ivec->iv_vec.v_nr; i++) {
782  idx = ivec->iv_index[i];
783  if (idx >= dest || /* the end */
784  idx > max_seg_end) /* a hole */
785  break;
786  cnt = ivec->iv_vec.v_count[i];
787  if (idx + cnt > max_seg_end)
788  max_seg_end = idx + cnt;
789  }
790 
791  return min64u(max_seg_end, dest);
792 }
793 
794 M0_INTERNAL void m0_0vec_fini(struct m0_0vec *zvec)
795 {
796  if (zvec != NULL) {
797  m0_free(zvec->z_bvec.ov_vec.v_count);
798  m0_free(zvec->z_bvec.ov_buf);
799  m0_free(zvec->z_index);
800  }
801 }
802 
803 static bool addr_is_4k_aligned(void *addr)
804 {
805  return ((uint64_t)addr & M0_0VEC_MASK) == 0;
806 }
807 
808 static bool m0_0vec_invariant(const struct m0_0vec *zvec)
809 {
810  const struct m0_bufvec *bvec = &zvec->z_bvec;
811 
812  return zvec != NULL && zvec->z_index != NULL &&
813  bvec->ov_buf != NULL &&
814  bvec->ov_vec.v_count != NULL &&
815  bvec->ov_vec.v_nr != 0 &&
816  /*
817  * All segments are aligned on 4k boundary and the sizes of all
818  * segments except the last one are positive multiples of 4k.
819  */
822  ergo(i < bvec->ov_vec.v_nr - 1,
823  !(bvec->ov_vec.v_count[i] & M0_0VEC_MASK)));
824 }
825 
826 M0_INTERNAL int m0_0vec_init(struct m0_0vec *zvec, uint32_t segs_nr)
827 {
828  M0_PRE(zvec != NULL);
829  M0_PRE(segs_nr != 0);
830 
831  M0_SET0(zvec);
832  M0_ALLOC_ARR(zvec->z_index, segs_nr);
833  if (zvec->z_index == NULL)
834  return M0_ERR(-ENOMEM);
835 
836  M0_ALLOC_ARR(zvec->z_bvec.ov_vec.v_count, segs_nr);
837  if (zvec->z_bvec.ov_vec.v_count == NULL)
838  goto failure;
839 
840  zvec->z_bvec.ov_vec.v_nr = segs_nr;
841 
842  M0_ALLOC_ARR(zvec->z_bvec.ov_buf, segs_nr);
843  if (zvec->z_bvec.ov_buf == NULL)
844  goto failure;
845  zvec->z_last_buf_idx = 0;
846  zvec->z_count = 0;
847  return 0;
848 failure:
849  m0_0vec_fini(zvec);
850  return M0_ERR(-ENOMEM);
851 }
852 
853 M0_INTERNAL void m0_0vec_bvec_init(struct m0_0vec *zvec,
854  const struct m0_bufvec *src,
855  const m0_bindex_t * index)
856 {
857  uint32_t i;
858  struct m0_bufvec *dst;
859 
860  M0_PRE(zvec != NULL);
861  M0_PRE(src != NULL);
862  M0_PRE(index != NULL);
863  M0_PRE(src->ov_vec.v_nr <= zvec->z_bvec.ov_vec.v_nr);
864 
865  dst = &zvec->z_bvec;
866  for (i = 0; i < src->ov_vec.v_nr; ++i) {
867  zvec->z_index[i] = index[i];
868  dst->ov_vec.v_count[i] = src->ov_vec.v_count[i];
869  M0_ASSERT(dst->ov_buf[i] == NULL);
870  dst->ov_buf[i] = src->ov_buf[i];
871  }
872 
873  M0_POST(m0_0vec_invariant(zvec));
874 }
875 
876 M0_INTERNAL void m0_0vec_bufs_init(struct m0_0vec *zvec,
877  void **bufs,
878  const m0_bindex_t * index,
879  const m0_bcount_t * counts, uint32_t segs_nr)
880 {
881  uint32_t i;
882  struct m0_bufvec *bvec;
883 
884  M0_PRE(zvec != NULL);
885  M0_PRE(bufs != NULL);
886  M0_PRE(index != NULL);
887  M0_PRE(counts != NULL);
888  M0_PRE(segs_nr != 0);
889  M0_PRE(segs_nr <= zvec->z_bvec.ov_vec.v_nr);
890 
891  bvec = &zvec->z_bvec;
892 
893  for (i = 0; i < segs_nr; ++i) {
894  zvec->z_index[i] = index[i];
895  bvec->ov_vec.v_count[i] = counts[i];
896  M0_ASSERT(bvec->ov_buf[i] == NULL);
897  bvec->ov_buf[i] = bufs[i];
898  }
899 
900  M0_POST(m0_0vec_invariant(zvec));
901 }
902 
903 M0_INTERNAL int m0_0vec_cbuf_add(struct m0_0vec *zvec,
904  const struct m0_buf *buf,
905  const m0_bindex_t * index)
906 {
907  uint32_t curr_seg;
908  struct m0_bufvec *bvec;
909 
910  M0_PRE(zvec != NULL);
911  M0_PRE(buf != NULL);
912  M0_PRE(index != NULL);
913 
914  bvec = &zvec->z_bvec;
915 
916  curr_seg = zvec->z_last_buf_idx;
917  if (curr_seg == bvec->ov_vec.v_nr)
918  return M0_ERR(-EMSGSIZE);
919 
920  M0_ASSERT(bvec->ov_buf[curr_seg] == NULL);
921  bvec->ov_buf[curr_seg] = buf->b_addr;
922  bvec->ov_vec.v_count[curr_seg] = buf->b_nob;
923  zvec->z_index[curr_seg] = *index;
924  zvec->z_last_buf_idx++;
925  zvec->z_count += buf->b_nob;
927  return 0;
928 }
929 
933 static void data_to_bufvec(struct m0_bufvec *src_buf, void **data,
934  size_t *len)
935 {
936  M0_PRE(src_buf != NULL);
937  M0_PRE(len != 0);
938  M0_PRE(data != NULL);
939  M0_CASSERT(sizeof len == sizeof src_buf->ov_vec.v_count);
940 
941  src_buf->ov_vec.v_nr = 1;
942  src_buf->ov_vec.v_count = (m0_bcount_t *)len;
943  src_buf->ov_buf = data;
944 }
945 
946 M0_INTERNAL int m0_data_to_bufvec_copy(struct m0_bufvec_cursor *cur, void *data,
947  size_t len)
948 {
950  struct m0_bufvec_cursor src_cur;
951  struct m0_bufvec src_buf;
952 
953  M0_PRE(cur != NULL);
954  M0_PRE(data != NULL);
955 
956  data_to_bufvec(&src_buf, &data, &len);
957  m0_bufvec_cursor_init(&src_cur, &src_buf);
958  count = m0_bufvec_cursor_copy(cur, &src_cur, len);
959  if (count != len)
960  return M0_ERR(-EFAULT);
961  return 0;
962 }
963 
964 M0_INTERNAL int m0_bufvec_to_data_copy(struct m0_bufvec_cursor *cur, void *data,
965  size_t len)
966 {
968  struct m0_bufvec_cursor dcur;
969  struct m0_bufvec dest_buf;
970 
971  M0_PRE(cur != NULL);
972  M0_PRE(data != NULL);
973  M0_PRE(len != 0);
974 
975  data_to_bufvec(&dest_buf, &data, &len);
976  m0_bufvec_cursor_init(&dcur, &dest_buf);
977  count = m0_bufvec_cursor_copy(&dcur, cur, len);
978  if (count != len)
979  return M0_ERR(-EFAULT);
980  return 0;
981 }
982 
984  struct m0_bufvec *src,
985  m0_bcount_t num_bytes)
986 {
987  struct m0_bufvec_cursor s_cur;
988  struct m0_bufvec_cursor d_cur;
989 
990  M0_PRE(dst != NULL);
991  M0_PRE(src != NULL);
992 
993  m0_bufvec_cursor_init(&s_cur, src);
994  m0_bufvec_cursor_init(&d_cur, dst);
995 
996  return m0_bufvec_cursor_copy(&d_cur, &s_cur, num_bytes);
997 }
998 
999 M0_INTERNAL m0_bcount_t m0_io_count(const struct m0_io_indexvec *io_info)
1000 {
1001  int i;
1003 
1004  M0_PRE(io_info != NULL);
1005 
1006  for (count = 0, i = 0; i < io_info->ci_nr; ++i)
1007  count += io_info->ci_iosegs[i].ci_count;
1008 
1009  return count;
1010 }
1011 
1012 static uint32_t ivec_nr_or_prepare(struct m0_indexvec *in,
1014  int req,
1015  uint32_t bshift,
1016  struct m0_indexvec *out)
1017 {
1018  struct m0_ivec_cursor cursor;
1019  int nr;
1020 
1021  m0_ivec_cursor_init(&cursor, in);
1022 
1023  for (nr = 0; !m0_ivec_cursor_move(&cursor, offset) && req > 0; ++nr) {
1024  offset = m0_ivec_cursor_step(&cursor);
1025  if (out != NULL) {
1026  m0_bcount_t cnt =
1027  min64u(m0_ivec_cursor_step(&cursor), req);
1028 
1029  out->iv_index[nr] =
1030  m0_ivec_cursor_index(&cursor) >> bshift;
1031  out->iv_vec.v_count[nr] = cnt >> bshift;
1032  }
1033  req -= offset;
1034  }
1035 
1036  return nr;
1037 }
1038 
1039 M0_INTERNAL int m0_indexvec_split(struct m0_indexvec *in,
1040  m0_bcount_t curr_pos,
1041  m0_bcount_t nb_len,
1042  uint32_t bshift,
1043  struct m0_indexvec *out)
1044 {
1045  int rc;
1046  uint32_t nr;
1047 
1048  M0_PRE(in != NULL);
1049  M0_PRE(out != NULL);
1050 
1051  nr = ivec_nr_or_prepare(in, curr_pos, nb_len, bshift, NULL);
1052  rc = m0_indexvec_alloc(out, nr);
1053  if (rc == 0)
1054  ivec_nr_or_prepare(in, curr_pos, nb_len, bshift, out);
1055  return M0_RC(rc);
1056 }
1057 
1058 M0_INTERNAL int m0_indexvec_wire2mem(struct m0_io_indexvec *wire_ivec,
1059  int max_frags_nr,
1060  uint32_t bshift,
1061  struct m0_indexvec *mem_ivec)
1062 {
1063  int rc;
1064  int i;
1065  m0_bcount_t *cnts;
1066  m0_bindex_t *offs;
1067 
1068  M0_PRE(wire_ivec != NULL);
1069  M0_PRE(mem_ivec != NULL);
1070 
1071  rc = m0_indexvec_alloc(mem_ivec, max_frags_nr);
1072  if (rc != 0)
1073  return M0_RC(rc);
1074 
1075  offs = mem_ivec->iv_index;
1076  cnts = mem_ivec->iv_vec.v_count;
1077  mem_ivec->iv_vec.v_nr = wire_ivec->ci_nr;
1078 
1079  for (i = 0; i < wire_ivec->ci_nr; ++i) {
1080  *(offs++) = wire_ivec->ci_iosegs[i].ci_index >> bshift;
1081  *(cnts++) = wire_ivec->ci_iosegs[i].ci_count >> bshift;
1082  }
1083 
1084  return 0;
1085 }
1086 
1087 M0_INTERNAL int m0_indexvec_mem2wire(struct m0_indexvec *mem_ivec,
1088  int max_frags_nr,
1089  uint32_t bshift,
1090  struct m0_io_indexvec *wire_ivec)
1091 {
1092  int i;
1093  m0_bcount_t *cnts;
1094  m0_bindex_t *offs;
1095 
1096  M0_PRE(wire_ivec != NULL);
1097  M0_PRE(mem_ivec != NULL);
1098 
1099 
1100  M0_ALLOC_ARR(wire_ivec->ci_iosegs, mem_ivec->iv_vec.v_nr);
1101  if (wire_ivec->ci_iosegs == NULL)
1102  return M0_ERR(-ENOMEM);
1103 
1104  offs = mem_ivec->iv_index;
1105  cnts = mem_ivec->iv_vec.v_count;
1106  wire_ivec->ci_nr = mem_ivec->iv_vec.v_nr;
1107 
1108  for (i = 0; i < wire_ivec->ci_nr; ++i) {
1109  wire_ivec->ci_iosegs[i].ci_index = *(offs++) >> bshift;
1110  wire_ivec->ci_iosegs[i].ci_count = *(cnts++) >> bshift;
1111  }
1112 
1113  return 0;
1114 }
1115 
1116 M0_INTERNAL int m0_indexvec_universal_set(struct m0_indexvec *iv)
1117 {
1118  int rc;
1119 
1120  M0_PRE(iv != NULL);
1121  rc = m0_indexvec_alloc(iv, 1);
1122  if (rc != 0)
1123  return rc;
1124  iv->iv_index[0] = 0;
1125  iv->iv_vec.v_count[0] = ~(m0_bcount_t)(0);
1126  return 0;
1127 }
1128 
1129 M0_INTERNAL bool m0_indexvec_is_universal(const struct m0_indexvec *iv)
1130 {
1131  M0_PRE(iv != NULL);
1132 
1133  return m0_vec_count(&iv->iv_vec) == (m0_bcount_t)~0ULL;
1134 }
1135 
1136 M0_INTERNAL int m0_indexvec_varr_alloc(struct m0_indexvec_varr *ivec,
1137  uint32_t len)
1138 {
1139  int rc;
1140 
1141  M0_PRE(ivec != NULL);
1142  M0_PRE(len > 0);
1143 
1144  M0_SET0(ivec);
1145  rc = m0_varr_init(&ivec->iv_count, len, sizeof(m0_bcount_t),
1146  m0_pagesize_get());
1147  if (rc == 0) {
1148  rc = m0_varr_init(&ivec->iv_index, len, sizeof(m0_bindex_t),
1149  m0_pagesize_get());
1150  if (rc != 0)
1151  m0_varr_fini(&ivec->iv_count);
1152  else
1153  ivec->iv_nr = len;
1154  }
1155  M0_LOG(M0_DEBUG, "ivec varr allocated for %p[%u] rc=%d", ivec, len, rc);
1156  return rc;
1157 }
1158 M0_EXPORTED(m0_indexvec_varr_alloc);
1159 
1160 M0_INTERNAL void m0_indexvec_varr_free(struct m0_indexvec_varr *ivec)
1161 {
1162  M0_PRE(ivec != NULL);
1163  m0_varr_fini(&ivec->iv_count);
1164  m0_varr_fini(&ivec->iv_index);
1165  M0_LOG(M0_DEBUG, "ivec varr freed for %p", ivec);
1166 }
1167 M0_EXPORTED(m0_indexvec_varr_free);
1168 
1170 {
1172 
1173  while (cur->vc_seg < m0_varr_size(&cur->vc_ivv->iv_count)) {
1174  v_count = m0_varr_ele_get(&cur->vc_ivv->iv_count, cur->vc_seg);
1175  if (*v_count == 0) {
1176  ++cur->vc_seg;
1177  cur->vc_offset = 0;
1178  } else
1179  break;
1180  }
1181 }
1182 
1184  struct m0_indexvec_varr *ivec)
1185 {
1186  M0_PRE(cur != NULL);
1187  M0_PRE(ivec != NULL);
1188  M0_PRE(m0_varr_size(&ivec->iv_index) > 0);
1189  M0_PRE(m0_varr_size(&ivec->iv_index) == m0_varr_size(&ivec->iv_count));
1190 
1191  cur->vc_ivv = ivec;
1192  cur->vc_seg = 0;
1193  cur->vc_offset = 0;
1195 }
1196 M0_EXPORTED(m0_ivec_varr_cursor_init);
1197 
1200 {
1201  M0_PRE(cur != NULL);
1202 
1203  M0_LOG(M0_DEBUG, "ivec %p cur %p forward %llu", cur->vc_ivv, cur,
1204  (unsigned long long)count);
1205  while (count > 0 && cur->vc_seg < m0_varr_size(&cur->vc_ivv->iv_count)){
1206  m0_bcount_t step;
1207 
1208  step = m0_ivec_varr_cursor_step(cur);
1209  if (count >= step) {
1210  cur->vc_seg++;
1211  cur->vc_offset = 0;
1212  count -= step;
1213  } else {
1214  cur->vc_offset += count;
1215  count = 0;
1216  }
1218  }
1219  return cur->vc_seg == m0_varr_size(&cur->vc_ivv->iv_count);
1220 }
1221 M0_EXPORTED(m0_ivec_varr_cursor_move);
1222 
1223 M0_INTERNAL m0_bcount_t
1225 {
1227 
1228  M0_PRE(cur != NULL);
1229  M0_PRE(cur->vc_seg < m0_varr_size(&cur->vc_ivv->iv_count));
1230 
1231  v_count = m0_varr_ele_get(&cur->vc_ivv->iv_count, cur->vc_seg);
1232  return *v_count - cur->vc_offset;
1233 }
1234 M0_EXPORTED(m0_ivec_varr_cursor_step);
1235 
1236 M0_INTERNAL m0_bindex_t
1238 {
1239  m0_bindex_t *v_index;
1240 
1241  M0_PRE(cur != NULL);
1242  M0_PRE(cur->vc_seg < cur->vc_ivv->iv_nr);
1243 
1244  v_index = m0_varr_ele_get(&cur->vc_ivv->iv_index, cur->vc_seg);
1245  return *v_index + cur->vc_offset;
1246 }
1247 M0_EXPORTED(m0_ivec_varr_cursor_index);
1248 
1249 M0_INTERNAL bool
1251 {
1252  m0_bindex_t min;
1253  bool ret = false;
1254 
1255  M0_PRE(cur != NULL);
1257 
1258  while (m0_ivec_varr_cursor_index(cur) != dest) {
1263  if (ret)
1264  break;
1265  }
1266  return ret;
1267 }
1268 M0_EXPORTED(m0_ivec_varr_cursor_move_to);
1269 
1270 M0_INTERNAL m0_bindex_t
1272  m0_bindex_t dest)
1273 {
1274  uint32_t i;
1275  m0_bindex_t *idx;
1276  m0_bcount_t *cnt;
1277  m0_bindex_t max_seg_end;
1278 
1279  M0_PRE(cur != NULL);
1281 
1282  i = cur->vc_seg;
1283  idx = m0_varr_ele_get(&cur->vc_ivv->iv_index, i);
1284  cnt = m0_varr_ele_get(&cur->vc_ivv->iv_count, i);
1285  max_seg_end = *idx + *cnt;
1286 
1287  for (i += 1; i < cur->vc_ivv->iv_nr; i++) {
1288  idx = m0_varr_ele_get(&cur->vc_ivv->iv_index, i);
1289  if (*idx >= dest || /* the end */
1290  *idx > max_seg_end) /* a hole */
1291  break;
1292  cnt = m0_varr_ele_get(&cur->vc_ivv->iv_count, i);
1293  if (*idx + *cnt > max_seg_end)
1294  max_seg_end = *idx + *cnt;
1295  }
1296 
1297  return min64u(max_seg_end, dest);
1298 }
1299 M0_EXPORTED(m0_ivec_varr_cursor_conti);
1300 
1301 M0_INTERNAL int m0_bufvec_to_buf_copy(struct m0_buf *buf,
1302  const struct m0_bufvec *bvec)
1303 {
1304  struct m0_bufvec_cursor cursor;
1305 
1306  M0_PRE(buf != NULL);
1307  M0_PRE(bvec != NULL);
1308 
1309  m0_bufvec_cursor_init(&cursor, bvec);
1310 
1311  return M0_RC(m0_bufvec_to_data_copy(&cursor, buf->b_addr,
1312  (size_t)buf->b_nob));
1313 }
1314 
1315 M0_INTERNAL int m0_buf_to_bufvec_copy(struct m0_bufvec *bvec,
1316  const struct m0_buf *buf)
1317 {
1318  struct m0_bufvec_cursor cursor;
1319 
1320  M0_PRE(bvec != NULL);
1321  M0_PRE(buf != NULL);
1322 
1323  m0_bufvec_cursor_init(&cursor, bvec);
1324 
1325  return M0_RC(m0_data_to_bufvec_copy(&cursor, buf->b_addr,
1326  (size_t)buf->b_nob));
1327 }
1328 
1329 #undef M0_TRACE_SUBSYSTEM
1330 
1333 /*
1334  * Local variables:
1335  * c-indentation-style: "K&R"
1336  * c-basic-offset: 8
1337  * tab-width: 8
1338  * fill-column: 80
1339  * scroll-step: 1
1340  * End:
1341  */
static m0_bcount_t seg_size
Definition: net.c:118
M0_INTERNAL m0_bcount_t m0_bufvec_copy(struct m0_bufvec *dst, struct m0_bufvec *src, m0_bcount_t num_bytes)
Definition: vec.c:983
static void m0_vec_cursor_normalize(struct m0_vec_cursor *cur)
Definition: vec.c:83
#define M0_BUFVEC_INIT_BUF(addr_ptr, count_ptr)
Definition: vec.h:165
M0_INTERNAL int m0_0vec_init(struct m0_0vec *zvec, uint32_t segs_nr)
Definition: vec.c:826
M0_INTERNAL void m0_ivec_cursor_init(struct m0_ivec_cursor *cur, const struct m0_indexvec *ivec)
Definition: vec.c:707
M0_INTERNAL int m0_bufvec_to_buf_copy(struct m0_buf *buf, const struct m0_bufvec *bvec)
Definition: vec.c:1301
uint64_t ci_count
Definition: vec.h:627
static size_t nr
Definition: dump.c:1505
M0_INTERNAL bool m0_ivec_varr_cursor_move_to(struct m0_ivec_varr_cursor *cur, m0_bindex_t dest)
Definition: vec.c:1250
#define M0_PRE(cond)
m0_bcount_t z_count
Definition: vec.h:520
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_INTERNAL int m0_bufvec_alloc_aligned_packed(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size, unsigned shift)
Definition: vec.c:366
M0_INTERNAL int m0_indexvec_alloc(struct m0_indexvec *ivec, uint32_t len)
Definition: vec.c:532
static int(* diff[M0_PARITY_CAL_ALGO_NR])(struct m0_parity_math *math, struct m0_buf *old, struct m0_buf *new, struct m0_buf *parity, uint32_t index)
Definition: parity_math.c:290
M0_INTERNAL void m0_0vec_fini(struct m0_0vec *zvec)
Definition: vec.c:794
#define NULL
Definition: misc.h:38
static struct m0_bufvec dst
Definition: xform.c:61
M0_INTERNAL m0_bcount_t m0_ivec_cursor_step(const struct m0_ivec_cursor *cur)
Definition: vec.c:726
M0_INTERNAL int m0_buf_to_bufvec_copy(struct m0_bufvec *bvec, const struct m0_buf *buf)
Definition: vec.c:1315
static struct buffer * cur(struct m0_addb2_mach *mach, m0_bcount_t space)
Definition: addb2.c:791
m0_bindex_t * z_index
Definition: vec.h:516
#define ergo(a, b)
Definition: misc.h:293
M0_INTERNAL m0_bindex_t m0_ivec_cursor_conti(const struct m0_ivec_cursor *cur, m0_bindex_t dest)
Definition: vec.c:765
static void m0_bufvec__free(struct m0_bufvec *bufvec, bool free_bufs)
Definition: vec.c:380
static struct io_request req
Definition: file.c:100
M0_INTERNAL int m0_bufvec_splice(const struct m0_bufvec *bvec, m0_bcount_t nr, struct m0_buf *buf)
Definition: vec.c:491
#define M0_LOG(level,...)
Definition: trace.h:167
#define min_check(a, b)
Definition: arith.h:88
M0_INTERNAL uint32_t m0_bufvec_pack(struct m0_bufvec *bv)
Definition: vec.c:480
#define M0_CASSERT(cond)
static uint32_t vec_pack(uint32_t nr, m0_bcount_t *cnt, m0_bindex_t *idx)
Definition: vec.c:454
static m0_bcount_t vec_count(const struct m0_vec *vec, uint32_t i)
Definition: vec.c:41
M0_INTERNAL void m0_0vec_bvec_init(struct m0_0vec *zvec, const struct m0_bufvec *src, const m0_bindex_t *index)
Definition: vec.c:853
M0_INTERNAL int m0_bufvec_merge(struct m0_bufvec *dst_bufvec, struct m0_bufvec *src_bufvec)
Definition: vec.c:280
struct m0_vec ov_vec
Definition: vec.h:147
static struct m0_uint128 prefix
Definition: extmap.c:45
struct m0_bufvec data
Definition: di.c:40
M0_INTERNAL m0_bindex_t m0_ivec_varr_cursor_conti(const struct m0_ivec_varr_cursor *cur, m0_bindex_t dest)
Definition: vec.c:1271
M0_INTERNAL m0_bcount_t m0_ivec_varr_cursor_step(const struct m0_ivec_varr_cursor *cur)
Definition: vec.c:1224
Definition: vec.h:49
M0_INTERNAL m0_bcount_t m0_vec_cursor_end(const struct m0_vec_cursor *cur)
Definition: vec.c:132
M0_INTERNAL void m0_indexvec_free(struct m0_indexvec *ivec)
Definition: vec.c:553
M0_INTERNAL void m0_free_aligned(void *data, size_t size, unsigned shift)
Definition: memory.c:192
static void pack(struct m0_addb2_mach *mach)
Definition: addb2.c:966
uint64_t m0_bindex_t
Definition: types.h:80
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
#define container_of(ptr, type, member)
Definition: misc.h:33
#define M0_SET0(obj)
Definition: misc.h:64
uint32_t ci_nr
Definition: vec.h:635
M0_INTERNAL int m0_data_to_bufvec_copy(struct m0_bufvec_cursor *cur, void *data, size_t len)
Definition: vec.c:946
static bool m0_vec_cursor_invariant(const struct m0_vec_cursor *cur)
Definition: vec.c:69
void ** ov_buf
Definition: vec.h:149
M0_INTERNAL bool m0_ivec_cursor_move_to(struct m0_ivec_cursor *cur, m0_bindex_t dest)
Definition: vec.c:745
M0_INTERNAL int m0_bufvec_extend(struct m0_bufvec *bufvec, uint32_t num_segs)
Definition: vec.c:228
Definition: sock.c:887
static m0_bcount_t count
Definition: xcode.c:167
M0_INTERNAL int m0_bufvec_cursor_cmp(struct m0_bufvec_cursor *c0, struct m0_bufvec_cursor *c1)
Definition: vec.c:639
M0_INTERNAL int m0_bufvec_alloc_aligned(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size, unsigned shift)
Definition: vec.c:355
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
return M0_RC(rc)
M0_INTERNAL void * bufvec_cursor_addr(struct m0_bufvec_cursor *cur)
Definition: vec.c:588
#define M0_ASSERT_EX(cond)
uint64_t ci_index
Definition: vec.h:626
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL int m0_pagesize_get(void)
Definition: memory.c:233
Definition: buf.h:37
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
m0_bindex_t * iv_index
Definition: vec.h:141
M0_INTERNAL bool m0_bufvec_cursor_move(struct m0_bufvec_cursor *cur, m0_bcount_t count)
Definition: vec.c:574
static char * addr
Definition: node_k.c:37
int i
Definition: dir.c:1033
M0_INTERNAL int m0_bufvec_to_data_copy(struct m0_bufvec_cursor *cur, void *data, size_t len)
Definition: vec.c:964
M0_INTERNAL int m0_indexvec_varr_alloc(struct m0_indexvec_varr *ivec, uint32_t len)
Definition: vec.c:1136
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_copyfrom(struct m0_bufvec_cursor *scur, void *ddata, m0_bcount_t num_bytes)
Definition: vec.c:692
M0_INTERNAL bool m0_vec_is_empty(const struct m0_vec *vec)
Definition: vec.c:58
#define M0_BUFVEC_ENDFOR2
Definition: vec.h:439
return M0_ERR(-EOPNOTSUPP)
static struct m0_tl cnts
Definition: cnt.c:42
Definition: cnt.h:36
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
M0_INTERNAL m0_bindex_t m0_ivec_varr_cursor_index(const struct m0_ivec_varr_cursor *cur)
Definition: vec.c:1237
M0_INTERNAL int m0_dont_dump(void *p, size_t size)
Definition: memory.c:243
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_copy(struct m0_bufvec_cursor *dcur, struct m0_bufvec_cursor *scur, m0_bcount_t num_bytes)
Definition: vec.c:620
M0_INTERNAL void m0_vec_cursor_init(struct m0_vec_cursor *cur, const struct m0_vec *vec)
Definition: vec.c:92
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_step(const struct m0_bufvec_cursor *cur)
Definition: vec.c:581
M0_INTERNAL uint64_t m0_varr_size(const struct m0_varr *arr)
Definition: varr.c:567
#define m0_free0(pptr)
Definition: memory.h:77
static void * vec
Definition: xcode.c:168
#define M0_ASSERT(cond)
static struct m0_bufvec bvec
Definition: xcode.c:169
M0_INTERNAL int m0_indexvec_wire2mem(struct m0_io_indexvec *wire_ivec, int max_frags_nr, uint32_t bshift, struct m0_indexvec *mem_ivec)
Definition: vec.c:1058
M0_INTERNAL int m0_varr_init(struct m0_varr *arr, uint64_t nr, size_t size, size_t bufsize)
Definition: varr.c:114
#define M0_BUF_INIT0
Definition: buf.h:71
M0_INTERNAL void m0_bufvec_cursor_init(struct m0_bufvec_cursor *cur, const struct m0_bufvec *bvec)
Definition: vec.c:563
Definition: vec.h:512
M0_INTERNAL void bufvec_free_aligned(struct m0_bufvec *bufvec, unsigned shift, bool pack)
Definition: vec.c:407
M0_INTERNAL int m0_buf_alloc(struct m0_buf *buf, size_t size)
Definition: buf.c:43
void * m0_alloc(size_t size)
Definition: memory.c:126
struct m0_varr iv_index
Definition: vec.h:711
static int bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size, unsigned shift, bool pack)
Definition: vec.c:139
#define M0_POST(cond)
Definition: xcode.h:73
m0_bcount_t counts[SEGS_NR]
Definition: di.c:44
M0_INTERNAL int m0_0vec_cbuf_add(struct m0_0vec *zvec, const struct m0_buf *buf, const m0_bindex_t *index)
Definition: vec.c:903
struct m0_varr iv_count
Definition: vec.h:708
uint32_t v_nr
Definition: vec.h:51
static bool m0_0vec_invariant(const struct m0_0vec *zvec)
Definition: vec.c:808
static m0_bindex_t offset
Definition: dump.c:173
m0_bcount_t * v_count
Definition: vec.h:1319
m0_bcount_t * v_count
Definition: vec.h:53
M0_INTERNAL bool m0_ivec_cursor_move(struct m0_ivec_cursor *cur, m0_bcount_t count)
Definition: vec.c:718
static uint64_t min64u(uint64_t a, uint64_t b)
Definition: arith.h:66
static void m0_ivec_varr_cursor_normalize(struct m0_ivec_varr_cursor *cur)
Definition: vec.c:1169
M0_INTERNAL void m0_indexvec_varr_free(struct m0_indexvec_varr *ivec)
Definition: vec.c:1160
uint32_t vc_seg
Definition: vec.h:94
M0_INTERNAL void m0_bufvec_free_aligned(struct m0_bufvec *bufvec, unsigned shift)
Definition: vec.c:436
M0_INTERNAL m0_bcount_t m0_vec_count(const struct m0_vec *vec)
Definition: vec.c:53
struct m0_bufvec z_bvec
Definition: vec.h:514
m0_bcount_t vc_offset
Definition: vec.h:96
#define m0_forall(var, nr,...)
Definition: misc.h:112
M0_INTERNAL uint32_t m0_indexvec_pack(struct m0_indexvec *iv)
Definition: vec.c:521
static bool addr_is_4k_aligned(void *addr)
Definition: vec.c:803
M0_INTERNAL void m0_ivec_varr_cursor_init(struct m0_ivec_varr_cursor *cur, struct m0_indexvec_varr *ivec)
Definition: vec.c:1183
static uint8_t fail[DATA_UNIT_COUNT_MAX+PARITY_UNIT_COUNT_MAX]
static long long min(long long a, long long b)
Definition: crate.c:191
M0_INTERNAL int m0_indexvec_split(struct m0_indexvec *in, m0_bcount_t curr_pos, m0_bcount_t nb_len, uint32_t bshift, struct m0_indexvec *out)
Definition: vec.c:1039
M0_INTERNAL m0_bcount_t m0_vec_cursor_step(const struct m0_vec_cursor *cur)
Definition: vec.c:125
M0_INTERNAL void m0_varr_fini(struct m0_varr *arr)
Definition: varr.c:486
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
M0_INTERNAL m0_bcount_t m0_bufvec_cursor_prefix(struct m0_bufvec_cursor *c0, struct m0_bufvec_cursor *c1)
Definition: vec.c:654
M0_INTERNAL int m0_indexvec_mem2wire(struct m0_indexvec *mem_ivec, int max_frags_nr, uint32_t bshift, struct m0_io_indexvec *wire_ivec)
Definition: vec.c:1087
uint32_t iv_nr
Definition: vec.h:714
M0_INTERNAL bool m0_bufvec_cursor_align(struct m0_bufvec_cursor *cur, uint64_t alignment)
Definition: vec.c:604
M0_INTERNAL int m0__bufvec_dont_dump(struct m0_bufvec *bufvec)
Definition: vec.c:331
M0_INTERNAL int m0_indexvec_universal_set(struct m0_indexvec *iv)
Definition: vec.c:1116
M0_INTERNAL bool m0_vec_cursor_move(struct m0_vec_cursor *cur, m0_bcount_t count)
Definition: vec.c:102
M0_INTERNAL m0_bcount_t m0_io_count(const struct m0_io_indexvec *io_info)
Definition: vec.c:999
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
M0_INTERNAL m0_bindex_t m0_ivec_cursor_index(const struct m0_ivec_cursor *cur)
Definition: vec.c:733
m0_bindex_t z_last_buf_idx
Definition: vec.h:518
M0_BASSERT(M0_SEG_SIZE==M0_0VEC_ALIGN)
M0_INTERNAL bool m0_indexvec_is_universal(const struct m0_indexvec *iv)
Definition: vec.c:1129
M0_INTERNAL void m0_bufvec_free_aligned_packed(struct m0_bufvec *bufvec, unsigned shift)
Definition: vec.c:443
static uint32_t ivec_nr_or_prepare(struct m0_indexvec *in, m0_bcount_t offset, int req, uint32_t bshift, struct m0_indexvec *out)
Definition: vec.c:1012
#define out(...)
Definition: gen.c:41
M0_INTERNAL void m0_0vec_bufs_init(struct m0_0vec *zvec, void **bufs, const m0_bindex_t *index, const m0_bcount_t *counts, uint32_t segs_nr)
Definition: vec.c:876
M0_INTERNAL void * m0_alloc_aligned(size_t size, unsigned shift)
Definition: memory.c:168
const struct m0_vec * vc_vec
Definition: vec.h:92
static int m0__bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size, unsigned shift)
Definition: vec.c:205
void m0_free(void *data)
Definition: memory.c:146
static void data_to_bufvec(struct m0_bufvec *src_buf, void **data, size_t *len)
Definition: vec.c:933
struct m0_ioseg * ci_iosegs
Definition: vec.h:636
struct m0_pdclust_src_addr src
Definition: fd.c:108
M0_INTERNAL void m0_bufvec_free2(struct m0_bufvec *bufvec)
Definition: vec.c:401
int32_t rc
Definition: trigger_fop.h:47
#define M0_POST_EX(cond)
static uint64_t m0_align(uint64_t val, uint64_t alignment)
Definition: arith.h:170
#define M0_BUFVEC_FOR2(c0, c1, frag)
Definition: vec.h:429
M0_INTERNAL bool m0_ivec_varr_cursor_move(struct m0_ivec_varr_cursor *cur, m0_bcount_t count)
Definition: vec.c:1198
Definition: vec.h:145
M0_INTERNAL int m0_bufvec_empty_alloc(struct m0_bufvec *bufvec, uint32_t num_segs)
Definition: vec.c:213
M0_INTERNAL void * m0_varr_ele_get(struct m0_varr *arr, uint64_t index)
Definition: varr.c:505