Motr  M0
cksum_utils.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 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 #include "lib/buf.h" /* m0_buf */
23 #include "lib/vec.h" /* m0_indexvec */
24 #include "lib/ext.h" /* m0_ext */
25 #include "lib/trace.h" /* M0_RC */
26 #include "lib/cksum_utils.h"
27 
28 
30  m0_bindex_t ext_len,
31  m0_bindex_t unit_sz )
32 {
33 
34  /* Compute how many unit starts in a given extent spans:
35  * Illustration below shows how extents can be received w.r.t unit size (4)
36  * | Unit 0|| Unit 1|| Unit 2|| Unit 3 |
37  |0|1|2|3||4|5|6|7||8|9|a|b|
38  * 1. | e1| => 1 (0,2)(ext_start,ext_len)
39  * 2. | e2 | => 1 (0,4) ending on unit 0
40  * 3. | e2 | => 2 (0,5) ending on unit 1's start
41  * 4. | e3 | => 1 (2,5)
42  * 5. | e4 | => 0 (1,3) within unit 0
43  * 6. | e5 | => 1 (3,5) ending on unit 1 end
44  * 7. | e6 | => 2 (3,8) ending on unit 2
45  * To compute how many DU start we need to find the DU Index of
46  * start and end.
47  * Overall: compute unit start and end index, difference would give us
48  * number of unit boundaries in extent span, but it would miss start
49  * unit if it is on unit boundary, so we need to additionally check for
50  * same.
51  */
52 
53  m0_bcount_t cs_nob;
54  M0_ASSERT(unit_sz);
55  cs_nob = ( (ext_start + ext_len - 1)/unit_sz - ext_start/unit_sz );
56 
58  if ((ext_start % unit_sz) == 0)
59  cs_nob++;
60 
61  return cs_nob;
62 }
63 
64 
66  m0_bindex_t base_off,
67  m0_bindex_t unit_sz)
68 {
69  M0_ASSERT(unit_sz);
70  /* Unit size we get from layout id using m0_obj_layout_id_to_unit_size(lid) */
71  return (off - base_off)/unit_sz;
72 }
73 
74 M0_INTERNAL void * m0_extent_get_checksum_addr(void *b_addr,
75  m0_bindex_t off,
76  m0_bindex_t base_off,
77  m0_bindex_t unit_sz,
78  m0_bcount_t cs_size)
79 {
80  M0_ASSERT(unit_sz && cs_size);
81  return (char *)b_addr + m0_extent_get_unit_offset(off, base_off, unit_sz) *
82  cs_size;
83 }
84 
86  m0_bindex_t ext_length,
87  m0_bindex_t unit_sz,
88  m0_bcount_t cs_size )
89 {
90  M0_ASSERT(unit_sz && cs_size);
91  return m0_extent_get_num_unit_start(ext_start, ext_length, unit_sz) * cs_size;
92 }
93 
94 /* This function will get checksum address for application provided checksum buffer
95  * Checksum is corresponding to on offset (e.g gob offset) & its extent and this
96  * function helps to locate exact address for the above.
97  * Checksum is stored in contigious buffer: cksum_buf_vec, while COB extents may
98  * not be contigious e.g.
99  * Assuming each extent has two DU, so two checksum.
100  * | CS0 | CS1 | CS2 | CS3 | CS4 | CS5 | CS6 |
101  * | iv_index[0] | | iv_index[1] | iv_index[2] | | iv_index[3] |
102  * Now if we have an offset for CS3 then after first travesal b_addr will point to
103  * start of CS2 and then it will land in m0_ext_is_in and will compute correct
104  * addr for CS3.
105  */
106 
107 M0_INTERNAL void * m0_extent_vec_get_checksum_addr(void *cksum_buf_vec,
108  m0_bindex_t off,
109  void *ivec,
110  m0_bindex_t unit_sz,
111  m0_bcount_t cs_sz )
112 {
113  void *cksum_addr = NULL;
114  struct m0_ext ext;
115  struct m0_indexvec *vec = (struct m0_indexvec *)ivec;
116  struct m0_bufvec *cksum_vec = (struct m0_bufvec *)cksum_buf_vec;
117  struct m0_bufvec_cursor cksum_cursor;
118  int attr_nob = 0;
119  int i;
120 
121  /* Get the checksum nobs consumed till reaching the off in given io */
122  for (i = 0; i < vec->iv_vec.v_nr; i++) {
123  ext.e_start = vec->iv_index[i];
124  ext.e_end = vec->iv_index[i] + vec->iv_vec.v_count[i];
125 
126  /* We construct current extent e.g for iv_index[0] and check if offset is
127  * within the span of current extent
128  * | iv_index[0] || iv_index[1] | iv_index[2] || iv_index[3] |
129  */
130  if (m0_ext_is_in(&ext, off)) {
131  attr_nob += ( m0_extent_get_unit_offset(off, ext.e_start, unit_sz) * cs_sz);
132  break;
133  }
134  else {
135  /* off is not in the current extent, so account increment the b_addr */
136  attr_nob += m0_extent_get_checksum_nob(ext.e_start,
137  vec->iv_vec.v_count[i], unit_sz, cs_sz);
138  }
139  }
140 
142  M0_ASSERT(i < vec->iv_vec.v_nr);
143 
145  m0_bufvec_cursor_init(&cksum_cursor, cksum_vec);
146 
147  if (attr_nob) {
148  m0_bufvec_cursor_move(&cksum_cursor, attr_nob);
149  }
150  cksum_addr = m0_bufvec_cursor_addr(&cksum_cursor);
151  return cksum_addr;
152 }
m0_bindex_t e_end
Definition: ext.h:40
#define NULL
Definition: misc.h:38
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
M0_INTERNAL void * m0_extent_get_checksum_addr(void *b_addr, m0_bindex_t off, m0_bindex_t base_off, m0_bindex_t unit_sz, m0_bcount_t cs_size)
Definition: cksum_utils.c:74
M0_INTERNAL m0_bcount_t m0_extent_get_checksum_nob(m0_bindex_t ext_start, m0_bindex_t ext_length, m0_bindex_t unit_sz, m0_bcount_t cs_size)
Definition: cksum_utils.c:85
M0_INTERNAL bool m0_bufvec_cursor_move(struct m0_bufvec_cursor *cur, m0_bcount_t count)
Definition: vec.c:574
int i
Definition: dir.c:1033
void * b_addr
Definition: buf.h:231
static void * vec
Definition: xcode.c:168
#define M0_ASSERT(cond)
M0_INTERNAL void m0_bufvec_cursor_init(struct m0_bufvec_cursor *cur, const struct m0_bufvec *bvec)
Definition: vec.c:563
M0_INTERNAL bool m0_ext_is_in(const struct m0_ext *ext, m0_bindex_t index)
Definition: ext.c:48
M0_INTERNAL m0_bcount_t m0_extent_get_num_unit_start(m0_bindex_t ext_start, m0_bindex_t ext_len, m0_bindex_t unit_sz)
Definition: cksum_utils.c:29
Definition: ext.h:37
m0_bindex_t e_start
Definition: ext.h:39
M0_INTERNAL m0_bcount_t m0_extent_get_unit_offset(m0_bindex_t off, m0_bindex_t base_off, m0_bindex_t unit_sz)
Definition: cksum_utils.c:65
Definition: vec.h:145
M0_INTERNAL void * m0_extent_vec_get_checksum_addr(void *cksum_buf_vec, m0_bindex_t off, void *ivec, m0_bindex_t unit_sz, m0_bcount_t cs_sz)
Definition: cksum_utils.c:107