Motr  M0
imask.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2016-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 
30 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_DIX
31 #include "lib/trace.h"
32 #include "lib/memory.h"
33 #include "lib/errno.h"
34 #include "dix/imask.h"
35 #include "lib/misc.h" /* M0_BYTES, m0_bit_get, m0_bit_set */
36 #include "lib/ext.h" /* struct m0_ext */
37 #include "lib/ext_xc.h" /* m0_ext_xc */
38 
39 #define AT(mask, idx) ((mask)->im_range[idx])
40 
41 static m0_bcount_t range_size(const struct m0_ext *range)
42 {
43  return range ? (range->e_end == IMASK_INF) ? IMASK_INF :
44  range->e_end - range->e_start + 1 :
45  0;
46 }
47 
48 static m0_bcount_t range_actual_size(const struct m0_ext *range,
49  uint64_t bs_len)
50 {
51  m0_bcount_t size = range_size(range);
52 
53  return size == IMASK_INF || size > bs_len ?
54  bs_len > range->e_start ? bs_len - range->e_start : 0 :
55  size;
56 }
57 
58 static int dix_imask_range_alloc(struct m0_dix_imask *mask,
59  uint64_t nr)
60 {
61  M0_PRE(mask->im_range == NULL);
62 
63  M0_ALLOC_ARR(mask->im_range, nr);
64  if (mask->im_range == NULL)
65  return M0_ERR(-ENOMEM);
66  mask->im_nr = nr;
67  return 0;
68 }
69 
70 static void dix_imask_range_free(struct m0_dix_imask *mask)
71 {
72  M0_PRE(mask != NULL);
73  m0_free(mask->im_range);
74 }
75 
76 static uint64_t ranges_size(struct m0_ext *range,
77  uint64_t nr,
78  uint64_t bs_len)
79 {
80  uint64_t res = 0;
81  uint64_t i = 0;
82 
83  for (i = 0; i < nr; i++)
84  res += range_actual_size(&range[i], bs_len);
85  return res;
86 }
92 static uint64_t imask_size(struct m0_dix_imask *mask, uint64_t bs_len)
93 {
94  return ranges_size(mask->im_range, mask->im_nr, bs_len);
95 }
96 
97 M0_INTERNAL int m0_dix_imask_init(struct m0_dix_imask *mask,
98  struct m0_ext *range,
99  uint64_t nr)
100 {
101  int rc;
102  uint64_t i;
103 
104  M0_ENTRY();
105  M0_SET0(mask);
106  if (range == NULL || nr == 0) {
107  M0_LOG(M0_DEBUG, "Empty imask %p initialisation", mask);
108  return M0_RC(0);
109  }
110  rc = dix_imask_range_alloc(mask, nr);
111  if (rc != 0)
112  return M0_ERR(rc);
113  for (i = 0; i < mask->im_nr; i++)
114  mask->im_range[i] = range[i];
115  return M0_RC(rc);
116 }
117 
118 M0_INTERNAL void m0_dix_imask_fini(struct m0_dix_imask *mask)
119 {
120  dix_imask_range_free(mask);
121  M0_SET0(mask);
122 }
123 
124 static void mask_bit_copy(void *buffer, m0_bcount_t pos, void *res,
125  m0_bcount_t respos)
126 {
127  m0_bit_set(res, respos, m0_bit_get(buffer, pos));
128 }
129 
130 M0_INTERNAL bool m0_dix_imask_is_empty(const struct m0_dix_imask *mask)
131 {
132  return mask->im_range == NULL || mask->im_nr == 0;
133 }
134 
135 M0_INTERNAL int m0_dix_imask_apply(void *buffer,
136  m0_bcount_t buf_len_bytes,
137  struct m0_dix_imask *mask,
138  void **res,
139  m0_bcount_t *res_len_bits)
140 {
141  char *result;
142  uint64_t mask_size;
143  uint64_t i;
144  m0_bcount_t k;
145  m0_bcount_t j;
146  m0_bcount_t rsize;
147 
148  M0_PRE(buffer != NULL);
149  M0_PRE(buf_len_bytes != 0);
150  mask_size = imask_size(mask, buf_len_bytes * 8);
151  *res_len_bits = 0;
152  *res = NULL;
153  if (mask_size == 0)
154  return M0_RC(0);
155  result = m0_alloc(M0_BYTES(mask_size));
156  if (result == NULL)
157  return M0_ERR(-ENOMEM);
158  k = 0;
159  for (i = 0; i < mask->im_nr; i++) {
160  rsize = range_actual_size(&AT(mask, i), buf_len_bytes * 8);
161  for (j = 0; j < rsize && k < mask_size; j++) {
162  mask_bit_copy(buffer, AT(mask, i).e_start + j,
163  result, k);
164  k++;
165  }
166  }
167  *res_len_bits = mask_size;
168  *res = result;
169  return M0_RC(0);
170 }
171 
172 M0_INTERNAL int m0_dix_imask_copy(struct m0_dix_imask *dst,
173  const struct m0_dix_imask *src)
174 {
175  uint64_t i;
176 
177  dst->im_nr = src->im_nr;
178  M0_ALLOC_ARR(dst->im_range, dst->im_nr);
179  if (dst->im_range == NULL)
180  return M0_ERR(-ENOMEM);
181  for (i = 0; i < dst->im_nr; i++)
182  dst->im_range[i] = src->im_range[i];
183  return 0;
184 }
185 
186 
187 M0_INTERNAL bool m0_dix_imask_eq(const struct m0_dix_imask *imask1,
188  const struct m0_dix_imask *imask2)
189 {
190  M0_PRE(imask1 != NULL);
191  M0_PRE(imask2 != NULL);
192 
193  if (imask1->im_nr != imask2->im_nr)
194  return false;
195 
196  return m0_forall(i, imask1->im_nr,
197  imask1->im_range[i].e_start ==
198  imask2->im_range[i].e_start &&
199  imask1->im_range[i].e_end ==
200  imask2->im_range[i].e_end);
201 }
202 
203 #undef M0_TRACE_SUBSYSTEM
204 
207 /*
208  * Local variables:
209  * c-indentation-style: "K&R"
210  * c-basic-offset: 8
211  * tab-width: 8
212  * fill-column: 80
213  * scroll-step: 1
214  * End:
215  */
216 /*
217  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
218  */
static size_t nr
Definition: dump.c:1505
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
m0_bindex_t e_end
Definition: ext.h:40
static void dix_imask_range_free(struct m0_dix_imask *mask)
Definition: imask.c:70
#define NULL
Definition: misc.h:38
static struct m0_bufvec dst
Definition: xform.c:61
M0_INTERNAL int m0_dix_imask_init(struct m0_dix_imask *mask, struct m0_ext *range, uint64_t nr)
Definition: imask.c:97
struct m0_ext * im_range
Definition: imask.h:66
M0_INTERNAL bool m0_bit_get(void *buffer, m0_bcount_t i)
Definition: misc.c:340
#define M0_LOG(level,...)
Definition: trace.h:167
m0_bindex_t e_start
Definition: ext.h:96
M0_INTERNAL int m0_dix_imask_apply(void *buffer, m0_bcount_t buf_len_bytes, struct m0_dix_imask *mask, void **res, m0_bcount_t *res_len_bits)
Definition: imask.c:135
uint64_t m0_bcount_t
Definition: types.h:77
#define AT(mask, idx)
Definition: imask.c:39
#define M0_SET0(obj)
Definition: misc.h:64
M0_INTERNAL bool m0_dix_imask_eq(const struct m0_dix_imask *imask1, const struct m0_dix_imask *imask2)
Definition: imask.c:187
return M0_RC(rc)
#define M0_ENTRY(...)
Definition: trace.h:170
int i
Definition: dir.c:1033
static m0_bcount_t range_size(const struct m0_ext *range)
Definition: imask.c:41
#define M0_BYTES(bits_nr)
Definition: misc.h:442
return M0_ERR(-EOPNOTSUPP)
static m0_bcount_t range_actual_size(const struct m0_ext *range, uint64_t bs_len)
Definition: imask.c:48
uint64_t im_nr
Definition: imask.h:64
M0_INTERNAL int m0_dix_imask_copy(struct m0_dix_imask *dst, const struct m0_dix_imask *src)
Definition: imask.c:172
static uint64_t ranges_size(struct m0_ext *range, uint64_t nr, uint64_t bs_len)
Definition: imask.c:76
static int dix_imask_range_alloc(struct m0_dix_imask *mask, uint64_t nr)
Definition: imask.c:58
void * m0_alloc(size_t size)
Definition: memory.c:126
static uint64_t imask_size(struct m0_dix_imask *mask, uint64_t bs_len)
Definition: imask.c:92
M0_INTERNAL bool m0_dix_imask_is_empty(const struct m0_dix_imask *mask)
Definition: imask.c:130
#define m0_forall(var, nr,...)
Definition: misc.h:112
Definition: ext.h:37
m0_bindex_t e_start
Definition: ext.h:39
Definition: addb2.c:200
M0_INTERNAL void m0_dix_imask_fini(struct m0_dix_imask *mask)
Definition: imask.c:118
m0_bcount_t size
Definition: di.c:39
M0_INTERNAL void m0_bit_set(void *buffer, m0_bcount_t i, bool val)
Definition: misc.c:349
static void mask_bit_copy(void *buffer, m0_bcount_t pos, void *res, m0_bcount_t respos)
Definition: imask.c:124
void m0_free(void *data)
Definition: memory.c:146
struct m0_pdclust_src_addr src
Definition: fd.c:108
int32_t rc
Definition: trigger_fop.h:47