Motr  M0
di.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-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 
27 #undef M0_TRACE_SUBSYSTEM
28 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_FILE
29 
30 #include "lib/trace.h"
31 #include "stob/battr.h"
32 #include "file/di.h"
33 #include "file/file.h"
34 #include "lib/misc.h"
35 #include "lib/vec_xc.h"
36 #include "file/crc.c"
37 
38 struct di_info {
40  uint32_t d_bit_set_nr;
41  uint32_t d_pos;
42  uint32_t d_blks_nr;
43 };
44 
45 static m0_bcount_t current_pos(const struct di_info *info, int i)
46 {
47  M0_PRE(info != NULL);
48 
49  return info->d_pos + i * info->d_bit_set_nr;
50 }
51 
52 static uint64_t file_di_crc_mask(const struct m0_file *file);
53 static uint64_t file_di_crc_in_shift(const struct m0_file *file);
54 static uint64_t file_di_crc_out_shift(const struct m0_file *file);
55 static void file_di_crc_sum(const struct m0_file *file,
56  const struct m0_indexvec *io_info,
57  const struct m0_bufvec *in_vec,
58  struct m0_bufvec *di_vec);
59 static bool file_di_crc_check(const struct m0_file *file,
60  const struct m0_indexvec *io_info,
61  const struct m0_bufvec *in_vec,
62  const struct m0_bufvec *di_vec);
63 static void file_checksum(void (*checksum)(const void *data,
64  m0_bcount_t bsize,
65  uint64_t *csum),
66  const struct m0_bufvec *in_vec,
67  const struct m0_indexvec *io_info,
68  struct di_info *di,
69  struct m0_bufvec *di_vec);
70 static bool file_checksum_check(bool (*checksum)(const void *data,
71  m0_bcount_t bsize,
72  const uint64_t *csum),
73  const struct m0_bufvec *in_vec,
74  const struct m0_indexvec *io_info,
75  struct di_info *di,
76  const struct m0_bufvec *di_vec);
77 
78 static void t10_ref_tag_compute(const struct m0_indexvec *io_info,
79  struct di_info *di,
80  struct m0_bufvec *di_vec);
81 static bool t10_ref_tag_check(const struct m0_indexvec *io_info,
82  struct di_info *di,
83  const struct m0_bufvec *di_vec);
84 
85 static void file_di_info_setup(const struct m0_file *file,
86  const struct m0_indexvec *io_info,
87  struct di_info *di);
88 
89 static struct m0_di_type file_di_crc = {
90  .dt_name = "crc32-4k+t10-ref-tag",
91 };
92 
93 static struct m0_di_type file_di_none_type = {
94  .dt_name = "di-none",
95 };
96 
97 static void file_di_none_sum(const struct m0_file *file,
98  const struct m0_indexvec *io_info,
99  const struct m0_bufvec *in_vec,
100  struct m0_bufvec *di_vec)
101 {
102  return;
103 }
104 
105 static bool file_di_none_check(const struct m0_file *file,
106  const struct m0_indexvec *io_info,
107  const struct m0_bufvec *in_vec,
108  const struct m0_bufvec *di_vec)
109 {
110  return true;
111 }
112 
113 static uint64_t file_di_none_mask(const struct m0_file *file)
114 {
115  return 0;
116 }
117 
118 static uint64_t file_di_none_in_shift(const struct m0_file *file)
119 {
120  return 12;
121 }
122 
123 static uint64_t file_di_none_out_shift(const struct m0_file *file)
124 {
125  return 0;
126 }
127 
128 static const struct m0_di_ops di_ops[M0_DI_NR] = {
129  [M0_DI_NONE] = {
131  .do_mask = file_di_none_mask,
132  .do_in_shift = file_di_none_in_shift,
133  .do_out_shift = file_di_none_out_shift,
134  .do_sum = file_di_none_sum,
135  .do_check = file_di_none_check,
136  },
137 
138  [M0_DI_CRC32_4K] = {
139  .do_type = &file_di_crc,
140  .do_mask = file_di_crc_mask,
141  .do_in_shift = file_di_crc_in_shift,
142  .do_out_shift = file_di_crc_out_shift,
143  .do_sum = file_di_crc_sum,
144  .do_check = file_di_crc_check,
145  },
146 };
147 
148 static uint64_t file_di_crc_mask(const struct m0_file *file)
149 {
151 }
152 
153 static uint64_t file_di_crc_in_shift(const struct m0_file *file)
154 {
155  return 12;
156 }
157 
158 static uint64_t file_di_crc_out_shift(const struct m0_file *file)
159 {
161 }
162 
163 static void file_di_crc_sum(const struct m0_file *file,
164  const struct m0_indexvec *io_info,
165  const struct m0_bufvec *in_vec,
166  struct m0_bufvec *di_vec)
167 {
168  struct di_info di;
169 
170  M0_PRE(file != NULL);
171  M0_PRE(in_vec != NULL);
172  M0_PRE(di_vec != NULL);
173  M0_PRE(io_info != NULL);
174 
175  file_di_info_setup(file, io_info, &di);
176 
177  file_checksum(&m0_crc32, in_vec, io_info, &di, di_vec);
178  di.d_pos += M0_DI_CRC32_LEN;
179  t10_ref_tag_compute(io_info, &di, di_vec);
180 }
181 
182 static void file_di_info_setup(const struct m0_file *file,
183  const struct m0_indexvec *io_info,
184  struct di_info *di)
185 {
186  di->d_pos = 0;
187  di->d_bsize = M0_BITS(file->fi_di_ops->do_in_shift(file));
188  di->d_bit_set_nr = m0_no_of_bits_set(
190  di->d_blks_nr = m0_vec_count(&io_info->iv_vec) / di->d_bsize;
191 }
192 
193 static bool file_di_invariant(const struct m0_bufvec *in_vec,
194  const struct m0_bufvec *di_vec,
195  const struct m0_indexvec *io_info,
196  const struct di_info *di)
197 {
198  struct m0_bufvec_cursor data_cur;
199  struct m0_bufvec_cursor cksum_cur;
200 
201  m0_bufvec_cursor_init(&data_cur, in_vec);
202  m0_bufvec_cursor_init(&cksum_cur, di_vec);
203 
204  return
205  _0C(in_vec != NULL) &&
206  _0C(di_vec != NULL) &&
207  _0C(io_info != NULL) &&
208  _0C(di != NULL) &&
209  _0C(di->d_bsize > 0) &&
210  _0C(di->d_bit_set_nr > 0) &&
211  _0C(!m0_bufvec_cursor_move(&data_cur,
212  (di->d_blks_nr - 1) * di->d_bsize)) &&
213  _0C(!m0_bufvec_cursor_move(&cksum_cur,
214  (current_pos(di, di->d_blks_nr) - 1) * M0_DI_ELEMENT_SIZE));
215 }
216 
217 /*
218  * For each data block in "in_vec" computes checksum using "checksum()" function
219  * and store the result as the "di->d_pos"-th block attribute in "di_vec".
220  *
221  * @param in_vec Input data blocks.
222  * @param io_info Data offset and count values.
223  * @param di Consist of position, number of elements in a group
224  * and block size of the data.
225  * @param di_vec Di data to be computed.
226  */
227 static void file_checksum(void (*checksum)(const void *data, m0_bcount_t bsize,
228  uint64_t *csum),
229  const struct m0_bufvec *in_vec,
230  const struct m0_indexvec *io_info,
231  struct di_info *di,
232  struct m0_bufvec *di_vec)
233 {
234  int i;
235  struct m0_bufvec_cursor data_cur;
236  struct m0_bufvec_cursor cksum_cur;
237  uint8_t *blk_data;
238  uint64_t *cksum;
239 
240  M0_ENTRY();
241  M0_PRE(file_di_invariant(in_vec, di_vec, io_info, di));
242 
243  m0_bufvec_cursor_init(&data_cur, in_vec);
244  m0_bufvec_cursor_init(&cksum_cur, di_vec);
245  cksum = m0_bufvec_cursor_addr(&cksum_cur);
246  for (i = 0; i < di->d_blks_nr; i++) {
247  blk_data = m0_bufvec_cursor_addr(&data_cur);
248  checksum(blk_data, di->d_bsize, cksum + current_pos(di, i));
249  m0_bufvec_cursor_move(&data_cur, di->d_bsize);
250  }
251 
252  M0_LEAVE();
253 }
254 
255 static bool file_di_crc_check(const struct m0_file *file,
256  const struct m0_indexvec *io_info,
257  const struct m0_bufvec *in_vec,
258  const struct m0_bufvec *di_vec)
259 {
260  struct di_info di;
261  bool check;
262 
263  M0_PRE(file != NULL);
264  M0_PRE(in_vec != NULL);
265  M0_PRE(di_vec != NULL);
266  M0_PRE(io_info != NULL);
267 
268  file_di_info_setup(file, io_info, &di);
269  check = file_checksum_check(&m0_crc32_chk, in_vec, io_info, &di,
270  di_vec);
271  if (check) {
272  di.d_pos += M0_DI_CRC32_LEN;
273  return t10_ref_tag_check(io_info, &di, di_vec);
274  }
275 
276  return check;
277 }
278 
279 /*
280  * For each data block in "in_vec" computes checksum using "checksum()"
281  * compare the result with the "di->d_pos"-th block attribute in
282  * "di_vec".
283  *
284  * @param in_vec Input data blocks.
285  * @param io_info Data offset and count values.
286  * @param di Consist of position, number of elements in a group
287  * and block size of the data.
288  * @param di_vec Di data to be verified.
289  */
290 static bool file_checksum_check(bool (*checksum)(const void *data,
291  m0_bcount_t bsize,
292  const uint64_t *csum),
293  const struct m0_bufvec *in_vec,
294  const struct m0_indexvec *io_info,
295  struct di_info *di,
296  const struct m0_bufvec *di_vec)
297 {
298  int i;
299  struct m0_bufvec_cursor data_cur;
300  struct m0_bufvec_cursor cksum_cur;
301  uint8_t *blk_data;
302  uint64_t *cksum;
303 
304  M0_ENTRY();
305  M0_PRE(file_di_invariant(in_vec, di_vec, io_info, di));
306 
307  m0_bufvec_cursor_init(&data_cur, in_vec);
308  m0_bufvec_cursor_init(&cksum_cur, di_vec);
309  cksum = m0_bufvec_cursor_addr(&cksum_cur);
310  for (i = 0; i < di->d_blks_nr; i++) {
311  blk_data = m0_bufvec_cursor_addr(&data_cur);
312  if (!checksum(blk_data, di->d_bsize,
313  cksum + current_pos(di, i)))
314  return M0_RC(false);
315  m0_bufvec_cursor_move(&data_cur, di->d_bsize);
316  }
317 
318  return M0_RC(true);
319 }
320 
321 static void t10_ref_tag_compute(const struct m0_indexvec *io_info,
322  struct di_info *di,
323  struct m0_bufvec *di_vec)
324 {
325  struct m0_bufvec_cursor cksum_cur;
326  uint64_t *cksum;
327  int i;
328 
329  M0_ENTRY();
330 
331  m0_bufvec_cursor_init(&cksum_cur, di_vec);
332  cksum = m0_bufvec_cursor_addr(&cksum_cur);
333  for (i = 0; i < io_info->iv_vec.v_nr; i++)
334  cksum[current_pos(di, i)] = io_info->iv_index[i] +
335  io_info->iv_vec.v_count[i];
336  M0_LEAVE();
337 }
338 
339 static bool t10_ref_tag_check(const struct m0_indexvec *io_info,
340  struct di_info *di,
341  const struct m0_bufvec *di_vec)
342 {
343  struct m0_bufvec_cursor cksum_cur;
344  uint64_t *cksum;
345  int i;
346 
347  M0_ENTRY();
348 
349  m0_bufvec_cursor_init(&cksum_cur, di_vec);
350  cksum = m0_bufvec_cursor_addr(&cksum_cur);
351  for (i = 0; i < io_info->iv_vec.v_nr; i++) {
352  m0_bcount_t cur_pos = current_pos(di, i);
353 
354  if (cksum[cur_pos] != io_info->iv_index[i] +
355  io_info->iv_vec.v_count[i]) {
356  M0_LOG(M0_ERROR,"Segment no: %d TAG value is %d \n", i,
357  (int)cksum[cur_pos]);
358  return M0_RC(false);
359  }
360  }
361 
362  return M0_RC(true);
363 }
364 
365 M0_INTERNAL const struct m0_di_ops *m0_di_ops_get(enum m0_di_types di_type)
366 {
367  M0_PRE(IS_IN_ARRAY(di_type, di_ops));
368 
369  return &di_ops[di_type];
370 }
371 
372 M0_INTERNAL void m0_md_di_set(void *addr, m0_bcount_t nob,
373  uint64_t *cksum_field)
374 {
375  md_crc32_cksum_set(addr, nob, cksum_field);
376 }
377 
378 M0_INTERNAL bool m0_md_di_chk(void *addr, m0_bcount_t nob,
379  uint64_t *cksum_field)
380 {
381  return md_crc32_cksum_check(addr, nob, cksum_field);
382 }
383 
384 M0_INTERNAL m0_bcount_t m0_di_size_get(const struct m0_file *file,
385  const m0_bcount_t size)
386 {
387  M0_PRE(file != NULL);
388 
389  return file->fi_di_ops->do_out_shift(file) *
392 }
393 
394 #undef M0_TRACE_SUBSYSTEM
395 
396 /*
397  * Local variables:
398  * c-indentation-style: "K&R"
399  * c-basic-offset: 8
400  * tab-width: 8
401  * fill-column: 79
402  * scroll-step: 1
403  * End:
404  */
uint32_t d_pos
Definition: di.c:41
#define M0_PRE(cond)
#define NULL
Definition: misc.h:38
m0_bcount_t d_bsize
Definition: di.c:39
struct m0_file file
Definition: di.c:36
#define M0_LOG(level,...)
Definition: trace.h:167
static void file_di_none_sum(const struct m0_file *file, const struct m0_indexvec *io_info, const struct m0_bufvec *in_vec, struct m0_bufvec *di_vec)
Definition: di.c:97
M0_LEAVE()
uint64_t(* do_out_shift)(const struct m0_file *file)
Definition: di.h:109
struct m0_bufvec data
Definition: di.c:40
static struct m0_di_type file_di_crc
Definition: di.c:89
#define M0_BITS(...)
Definition: misc.h:236
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
uint64_t(* do_mask)(const struct m0_file *file)
Definition: di.h:98
static int di
Definition: pool_trigger.c:53
Definition: di.h:92
static bool file_di_crc_check(const struct m0_file *file, const struct m0_indexvec *io_info, const struct m0_bufvec *in_vec, const struct m0_bufvec *di_vec)
Definition: di.c:255
const struct m0_di_type * do_type
Definition: di.h:93
Definition: di.c:38
M0_INTERNAL bool m0_crc32_chk(const void *data, uint64_t len, const uint64_t *cksum)
Definition: crc.c:93
struct m0_vec iv_vec
Definition: vec.h:139
return M0_RC(rc)
static void file_di_crc_sum(const struct m0_file *file, const struct m0_indexvec *io_info, const struct m0_bufvec *in_vec, struct m0_bufvec *di_vec)
Definition: di.c:163
#define M0_ENTRY(...)
Definition: trace.h:170
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
m0_di_types
Definition: di.h:72
int i
Definition: dir.c:1033
Definition: di.h:80
static bool file_di_none_check(const struct m0_file *file, const struct m0_indexvec *io_info, const struct m0_bufvec *in_vec, const struct m0_bufvec *di_vec)
Definition: di.c:105
static uint64_t file_di_none_mask(const struct m0_file *file)
Definition: di.c:113
const char * dt_name
Definition: di.h:64
static void t10_ref_tag_compute(const struct m0_indexvec *io_info, struct di_info *di, struct m0_bufvec *di_vec)
Definition: di.c:321
static uint64_t file_di_crc_in_shift(const struct m0_file *file)
Definition: di.c:153
uint32_t d_bit_set_nr
Definition: di.c:40
M0_INTERNAL void m0_crc32(const void *data, uint64_t len, uint64_t *cksum)
Definition: crc.c:83
M0_INTERNAL void m0_bufvec_cursor_init(struct m0_bufvec_cursor *cur, const struct m0_bufvec *bvec)
Definition: vec.c:563
M0_INTERNAL uint32_t m0_no_of_bits_set(uint64_t val)
Definition: misc.c:227
uint32_t d_blks_nr
Definition: di.c:42
static void file_di_info_setup(const struct m0_file *file, const struct m0_indexvec *io_info, struct di_info *di)
Definition: di.c:182
Definition: xcode.h:73
uint32_t v_nr
Definition: vec.h:51
m0_bcount_t * v_count
Definition: vec.h:53
static const struct m0_di_ops di_ops[M0_DI_NR]
Definition: di.c:128
static void md_crc32_cksum_set(void *data, uint64_t len, uint64_t *cksum)
Definition: crc.c:103
static bool t10_ref_tag_check(const struct m0_indexvec *io_info, struct di_info *di, const struct m0_bufvec *di_vec)
Definition: di.c:339
M0_INTERNAL m0_bcount_t m0_vec_count(const struct m0_vec *vec)
Definition: vec.c:53
uint64_t(* do_in_shift)(const struct m0_file *file)
Definition: di.h:104
M0_INTERNAL m0_bcount_t m0_di_size_get(const struct m0_file *file, const m0_bcount_t size)
Definition: di.c:384
static bool file_di_invariant(const struct m0_bufvec *in_vec, const struct m0_bufvec *di_vec, const struct m0_indexvec *io_info, const struct di_info *di)
Definition: di.c:193
M0_INTERNAL const struct m0_di_ops * m0_di_ops_get(enum m0_di_types di_type)
Definition: di.c:365
static bool file_checksum_check(bool(*checksum)(const void *data, m0_bcount_t bsize, const uint64_t *csum), const struct m0_bufvec *in_vec, const struct m0_indexvec *io_info, struct di_info *di, const struct m0_bufvec *di_vec)
Definition: di.c:290
m0_bcount_t size
Definition: di.c:39
#define _0C(exp)
Definition: assert.h:311
#define IS_IN_ARRAY(idx, array)
Definition: misc.h:311
M0_INTERNAL bool m0_md_di_chk(void *addr, m0_bcount_t nob, uint64_t *cksum_field)
Definition: di.c:378
static uint64_t file_di_none_in_shift(const struct m0_file *file)
Definition: di.c:118
static uint64_t file_di_crc_out_shift(const struct m0_file *file)
Definition: di.c:158
void check(struct workload *w)
static uint64_t file_di_crc_mask(const struct m0_file *file)
Definition: di.c:148
Definition: file.h:81
Definition: di.h:73
M0_INTERNAL void m0_md_di_set(void *addr, m0_bcount_t nob, uint64_t *cksum_field)
Definition: di.c:372
static void file_checksum(void(*checksum)(const void *data, m0_bcount_t bsize, uint64_t *csum), const struct m0_bufvec *in_vec, const struct m0_indexvec *io_info, struct di_info *di, struct m0_bufvec *di_vec)
Definition: di.c:227
static uint64_t file_di_none_out_shift(const struct m0_file *file)
Definition: di.c:123
static bool md_crc32_cksum_check(void *data, uint64_t len, uint64_t *cksum)
Definition: crc.c:120
static struct m0_di_type file_di_none_type
Definition: di.c:93
const struct m0_di_ops * fi_di_ops
Definition: file.h:92
Definition: vec.h:145
static m0_bcount_t current_pos(const struct di_info *info, int i)
Definition: di.c:45
Definition: di.h:60