Motr  M0
layout.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 
33 #include "lib/errno.h"
34 #include "lib/assert.h"
35 #include "lib/buf.h"
36 #include "lib/hash_fnc.h"
37 #include "lib/misc.h" /* M0_BYTES */
38 #include "lib/memory.h"
39 #include "lib/ext.h" /* m0_ext */
40 #include "layout/layout.h"
41 #include "layout/pdclust.h"
42 #include "pool/pool.h"
43 #include "dix/imask.h"
44 #include "dix/layout.h"
45 
46 
48  const struct m0_fid *fid,
49  uint64_t layout_id,
50  struct m0_pool_version *pver,
51  struct m0_dix_linst *dli)
52 {
53  int rc;
54  struct m0_layout *l;
55  struct m0_layout_instance *li;
56 
58  M0_ASSERT(l != NULL);
59  dli->li_pl = M0_AMB(dli->li_pl, l, pl_base.sl_base);
60  l->l_pver = pver;
62  if (rc != 0)
63  return M0_ERR(rc);
65  return M0_RC(0);
66 }
67 
68 M0_INTERNAL uint32_t m0_dix_devices_nr(struct m0_dix_linst *linst)
69 {
70  struct m0_pool_version *pver;
71 
72  pver = m0_pdl_to_layout(linst->li_pl)->l_pver;
73  return pver->pv_mach.pm_state->pst_nr_devices;
74 }
75 
76 M0_INTERNAL struct m0_pooldev *m0_dix_tgt2sdev(struct m0_dix_linst *linst,
77  uint64_t tgt)
78 {
79  struct m0_pool_version *pver;
80 
81  pver = m0_pdl_to_layout(linst->li_pl)->l_pver;
83  return &pver->pv_mach.pm_state->pst_devices_array[tgt];
84 }
85 
86 M0_INTERNAL int m0_dix_layout_init(struct m0_dix_linst *dli,
87  struct m0_layout_domain *domain,
88  const struct m0_fid *fid,
89  uint64_t layout_id,
90  struct m0_pool_version *pver,
91  struct m0_dix_ldesc *dld)
92 {
93  M0_PRE(dli != NULL);
94  M0_PRE(domain != NULL);
95  M0_PRE(pver != NULL);
96 
97  M0_SET0(dli);
98  dli->li_ldescr = dld;
99  return layout_create(domain, fid, layout_id, pver, dli);
100 }
101 
102 M0_INTERNAL void m0_dix_layout_fini(struct m0_dix_linst *li)
103 {
104  M0_PRE(li != NULL);
105  if (li->li_pi != NULL)
107  if (li->li_pl != NULL)
109 }
110 
111 static void dix_hash(struct m0_dix_ldesc *ldesc,
112  struct m0_buf *buf,
113  uint64_t *hash)
114 {
115  void *val = buf->b_addr;
116  m0_bcount_t len = buf->b_nob;
117 
118  M0_PRE(ldesc != NULL);
119  M0_PRE(buf != NULL);
120  M0_PRE(buf->b_addr != NULL);
121 
122  len = M0_BYTES(len);
123  switch(ldesc->ld_hash_fnc) {
124  case HASH_FNC_NONE:
125  M0_PRE(len <= sizeof(uint64_t));
126  *hash = val == NULL ? 0 : *(uint64_t *)val;
127  break;
128  case HASH_FNC_FNV1:
129  *hash = m0_hash_fnc_fnv1(val, len);
130  break;
131  case HASH_FNC_CITY:
132  *hash = m0_hash_fnc_city(val, len);
133  break;
134  default:
135  M0_IMPOSSIBLE("Incorrect hash function type");
136  }
137 }
138 
139 static bool unit_is_valid(struct m0_pdclust_attr *attr, uint64_t unit)
140 {
141  return unit < attr->pa_N + attr->pa_K + attr->pa_S;
142 }
143 
144 M0_INTERNAL void m0_dix_target(struct m0_dix_linst *inst,
145  uint64_t unit,
146  struct m0_buf *key,
147  uint64_t *out_id)
148 {
149  struct m0_pdclust_src_addr src;
150  struct m0_pdclust_tgt_addr tgt;
151 
152  M0_PRE(inst != NULL);
153  M0_PRE(inst->li_pl != NULL);
154  M0_PRE(key != NULL);
155  M0_PRE(unit_is_valid(&inst->li_pl->pl_attr, unit));
156  if (key->b_addr != NULL)
157  dix_hash(inst->li_ldescr, key, &src.sa_group);
158  else
159  src.sa_group = 0;
160  src.sa_unit = unit;
161  if (M0_FI_ENABLED("pdcluster-map"))
163  else
164  m0_fd_fwd_map(inst->li_pi, &src, &tgt);
165  *out_id = tgt.ta_obj;
167  "Key %p, group/unit [%" PRIx64 ",%" PRIx64 "] -> target %"PRIx64,
168  key, src.sa_group, unit, *out_id);
169 }
170 
171 M0_INTERNAL int m0_dix_ldesc_init(struct m0_dix_ldesc *ld,
172  struct m0_ext *range,
173  m0_bcount_t range_nr,
175  struct m0_fid *pver)
176 {
177  int rc;
178 
179  M0_PRE(ld != NULL);
180  M0_SET0(ld);
181  rc = m0_dix_imask_init(&ld->ld_imask, range, range_nr);
182  if (rc == 0) {
183  ld->ld_hash_fnc = htype;
184  ld->ld_pver = *pver;
185  }
186  return rc;
187 }
188 
189 M0_INTERNAL int m0_dix_ldesc_copy(struct m0_dix_ldesc *dst,
190  const struct m0_dix_ldesc *src)
191 {
192  dst->ld_hash_fnc = src->ld_hash_fnc;
193  dst->ld_pver = src->ld_pver;
194  return m0_dix_imask_copy(&dst->ld_imask, &src->ld_imask);
195 }
196 
197 M0_INTERNAL void m0_dix_ldesc_fini(struct m0_dix_ldesc *ld)
198 {
200 }
201 
202 M0_INTERNAL
204  const struct m0_fid *index,
205  struct m0_layout_domain *ldom,
206  struct m0_pool_version *pver,
207  struct m0_dix_ldesc *ldesc,
208  struct m0_buf *key)
209 {
210  struct m0_fid layout_fid;
211  uint64_t layout_id;
212  struct m0_pdclust_attr *pd_attr;
213  int rc;
214 
215  M0_ENTRY("iter %p", iter);
216  M0_PRE(iter != NULL);
217  M0_PRE(index != NULL);
218  M0_PRE(ldom != NULL);
219  M0_PRE(pver != NULL);
220  M0_PRE(ldesc != NULL);
221 
222  M0_ASSERT(pver->pv_attr.pa_N == 1);
223 
224  layout_fid = *index;
226  M0_DEFAULT_LAYOUT_ID);
227  rc = m0_dix_layout_init(&iter->dit_linst, ldom, &layout_fid,
228  layout_id, pver, ldesc);
229  if (rc != 0)
230  return M0_ERR(rc);
231  rc = m0_dix_imask_apply(key->b_addr, key->b_nob,
232  &ldesc->ld_imask,
233  &iter->dit_key.b_addr,
234  &iter->dit_key.b_nob);
235  if (rc != 0) {
237  return M0_ERR(rc);
238  }
239 
240  pd_attr = &iter->dit_linst.li_pl->pl_attr;
242  "N=%u. Only layouts with N=1 are supported.",
243  pver->pv_attr.pa_N);
244  iter->dit_W = pd_attr->pa_N + pd_attr->pa_K + pd_attr->pa_S;
245  iter->dit_unit = 0;
246  return M0_RC(rc);
247 }
248 
249 M0_INTERNAL void m0_dix_layout_iter_next(struct m0_dix_layout_iter *iter,
250  uint64_t *tgt)
251 {
252  M0_ENTRY("iter %p", iter);
253  M0_PRE(iter->dit_unit < iter->dit_W);
254  m0_dix_layout_iter_get_at(iter, iter->dit_unit, tgt);
255  iter->dit_unit++;
256 }
257 
258 M0_INTERNAL void m0_dix_layout_iter_get_at(struct m0_dix_layout_iter *iter,
259  uint64_t unit,
260  uint64_t *tgt)
261 {
262  m0_dix_target(&iter->dit_linst, unit, &iter->dit_key, tgt);
263 }
264 
265 M0_INTERNAL uint32_t m0_dix_liter_W(struct m0_dix_layout_iter *iter)
266 {
267  return iter->dit_W;
268 }
269 
270 M0_INTERNAL uint32_t m0_dix_liter_N(struct m0_dix_layout_iter *iter)
271 {
272  return iter->dit_linst.li_pl->pl_attr.pa_N;
273 }
274 
275 M0_INTERNAL uint32_t m0_dix_liter_P(struct m0_dix_layout_iter *iter)
276 {
277  return iter->dit_linst.li_pl->pl_attr.pa_P;
278 }
279 
280 M0_INTERNAL uint32_t m0_dix_liter_K(struct m0_dix_layout_iter *iter)
281 {
282  return iter->dit_linst.li_pl->pl_attr.pa_K;
283 }
284 
285 M0_INTERNAL uint32_t m0_dix_liter_S(struct m0_dix_layout_iter *iter)
286 {
287  return iter->dit_linst.li_pl->pl_attr.pa_S;
288 }
289 
290 M0_INTERNAL uint32_t m0_dix_liter_spare_offset(struct m0_dix_layout_iter *iter)
291 {
292  return m0_dix_liter_N(iter) + m0_dix_liter_K(iter);
293 }
294 
295 M0_INTERNAL uint32_t m0_dix_liter_unit_classify(struct m0_dix_layout_iter *iter,
296  uint64_t unit)
297 {
298  return m0_pdclust_unit_classify(iter->dit_linst.li_pl, unit);
299 }
300 
301 
302 M0_INTERNAL void m0_dix_layout_iter_goto(struct m0_dix_layout_iter *iter,
303  uint64_t unit)
304 {
305  M0_ENTRY("iter %p", iter);
306  M0_PRE(unit_is_valid(&iter->dit_linst.li_pl->pl_attr, unit));
307  iter->dit_unit = unit;
308 }
309 
310 M0_INTERNAL void m0_dix_layout_iter_reset(struct m0_dix_layout_iter *iter)
311 {
312  m0_dix_layout_iter_goto(iter, 0);
313 }
314 
315 M0_INTERNAL void m0_dix_layout_iter_fini(struct m0_dix_layout_iter *iter)
316 {
317  M0_ENTRY("iter %p", iter);
318  m0_buf_free(&iter->dit_key);
320 }
321 
322 M0_INTERNAL bool m0_dix_layout_eq(const struct m0_dix_layout *layout1,
323  const struct m0_dix_layout *layout2)
324 {
325  const struct m0_dix_ldesc *ldesc1;
326  const struct m0_dix_ldesc *ldesc2;
327 
328  M0_PRE(layout1 != NULL);
329  M0_PRE(layout2 != NULL);
330 
331  if (layout1->dl_type != layout2->dl_type)
332  return false;
333 
334  if (layout1->dl_type == DIX_LTYPE_ID)
335  return layout1->u.dl_id == layout2->u.dl_id;
336 
337  /* Compare layout descriptors. */
338  ldesc1 = &layout1->u.dl_desc;
339  ldesc2 = &layout2->u.dl_desc;
340 
341  return ldesc1->ld_hash_fnc == ldesc2->ld_hash_fnc &&
342  m0_fid_eq(&ldesc1->ld_pver, &ldesc2->ld_pver) &&
343  m0_dix_imask_eq(&ldesc1->ld_imask, &ldesc2->ld_imask);
344 }
345 
346 #undef M0_TRACE_SUBSYSTEM
347 
350 /*
351  * Local variables:
352  * c-indentation-style: "K&R"
353  * c-basic-offset: 8
354  * tab-width: 8
355  * fill-column: 80
356  * scroll-step: 1
357  * End:
358  */
359 /*
360  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
361  */
M0_INTERNAL struct m0_layout * m0_layout_find(struct m0_layout_domain *dom, uint64_t lid)
Definition: layout.c:861
struct m0_poolmach_state * pm_state
Definition: pool_machine.h:169
#define M0_PRE(cond)
M0_INTERNAL uint32_t m0_dix_liter_K(struct m0_dix_layout_iter *iter)
Definition: layout.c:280
uint64_t sa_group
Definition: pdclust.h:241
#define NULL
Definition: misc.h:38
uint32_t pst_nr_devices
Definition: pool_machine.h:108
static struct m0_bufvec dst
Definition: xform.c:61
struct m0_pool_version * l_pver
Definition: layout.h:261
struct m0_pdclust_instance * li_pi
Definition: layout.h:116
M0_INTERNAL int m0_dix_imask_init(struct m0_dix_imask *mask, struct m0_ext *range, uint64_t nr)
Definition: imask.c:97
Definition: idx_mock.c:52
void * b_addr
Definition: buf.h:39
uint32_t pa_N
Definition: pdclust.h:104
struct m0_poolmach pv_mach
Definition: pool.h:133
#define M0_LOG(level,...)
Definition: trace.h:167
static bool unit_is_valid(struct m0_pdclust_attr *attr, uint64_t unit)
Definition: layout.c:139
struct m0_dix_linst dit_linst
Definition: layout.h:135
struct m0_layout_instance pi_base
Definition: pdclust.h:173
uint32_t pa_K
Definition: pdclust.h:107
uint64_t ta_obj
Definition: pdclust.h:256
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
M0_INTERNAL int m0_dix_layout_iter_init(struct m0_dix_layout_iter *iter, const struct m0_fid *index, struct m0_layout_domain *ldom, struct m0_pool_version *pver, struct m0_dix_ldesc *ldesc, struct m0_buf *key)
Definition: layout.c:203
M0_INTERNAL void m0_dix_target(struct m0_dix_linst *inst, uint64_t unit, struct m0_buf *key, uint64_t *out_id)
Definition: layout.c:144
uint32_t pa_S
Definition: pdclust.h:110
uint64_t m0_bcount_t
Definition: types.h:77
#define M0_SET0(obj)
Definition: misc.h:64
struct m0_pdclust_attr pl_attr
Definition: pdclust.h:150
M0_INTERNAL bool m0_dix_imask_eq(const struct m0_dix_imask *imask1, const struct m0_dix_imask *imask2)
Definition: imask.c:187
#define PRIx64
Definition: types.h:61
M0_INTERNAL uint32_t m0_dix_liter_S(struct m0_dix_layout_iter *iter)
Definition: layout.c:285
Definition: sock.c:887
M0_INTERNAL int m0_layout_instance_build(struct m0_layout *l, const struct m0_fid *fid, struct m0_layout_instance **out)
Definition: layout.c:1113
M0_INTERNAL void m0_dix_layout_fini(struct m0_dix_linst *li)
Definition: layout.c:102
M0_INTERNAL void m0_dix_layout_iter_fini(struct m0_dix_layout_iter *iter)
Definition: layout.c:315
M0_INTERNAL int m0_dix_ldesc_copy(struct m0_dix_ldesc *dst, const struct m0_dix_ldesc *src)
Definition: layout.c:189
struct m0_fid fid
Definition: di.c:46
return M0_RC(rc)
#define M0_ENTRY(...)
Definition: trace.h:170
Definition: buf.h:37
#define M0_BYTES(bits_nr)
Definition: misc.h:442
static void dix_hash(struct m0_dix_ldesc *ldesc, struct m0_buf *buf, uint64_t *hash)
Definition: layout.c:111
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL bool m0_dix_layout_eq(const struct m0_dix_layout *layout1, const struct m0_dix_layout *layout2)
Definition: layout.c:322
M0_INTERNAL uint64_t m0_pool_version2layout_id(const struct m0_fid *pv_fid, uint64_t lid)
Definition: pool.c:1900
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
struct m0_pdclust_attr pd_attr
Definition: fd.c:95
static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:949
m0_bcount_t b_nob
Definition: buf.h:38
#define M0_ASSERT(cond)
M0_INTERNAL uint32_t m0_dix_liter_spare_offset(struct m0_dix_layout_iter *iter)
Definition: layout.c:290
M0_INTERNAL void m0_dix_layout_iter_next(struct m0_dix_layout_iter *iter, uint64_t *tgt)
Definition: layout.c:249
struct m0_fid pver
Definition: idx_dix.c:74
M0_INTERNAL int m0_dix_imask_copy(struct m0_dix_imask *dst, const struct m0_dix_imask *src)
Definition: imask.c:172
M0_INTERNAL uint64_t m0_hash_fnc_fnv1(const void *buffer, m0_bcount_t len)
Definition: hash_fnc.c:84
M0_INTERNAL int m0_dix_ldesc_init(struct m0_dix_ldesc *ld, struct m0_ext *range, m0_bcount_t range_nr, enum m0_dix_hash_fnc_type htype, struct m0_fid *pver)
Definition: layout.c:171
M0_INTERNAL void m0_dix_layout_iter_get_at(struct m0_dix_layout_iter *iter, uint64_t unit, uint64_t *tgt)
Definition: layout.c:258
int layout_id
Definition: dir.c:331
M0_INTERNAL uint64_t m0_hash_fnc_city(const void *buffer, m0_bcount_t len)
Definition: hash_fnc.c:205
M0_INTERNAL uint32_t m0_dix_liter_unit_classify(struct m0_dix_layout_iter *iter, uint64_t unit)
Definition: layout.c:295
struct m0_dix_ldesc * li_ldescr
Definition: layout.h:114
M0_INTERNAL uint32_t m0_dix_liter_W(struct m0_dix_layout_iter *iter)
Definition: layout.c:265
uint32_t dl_type
Definition: layout.h:100
struct m0_dix_imask ld_imask
Definition: layout.h:79
M0_INTERNAL void m0_buf_free(struct m0_buf *buf)
Definition: buf.c:55
M0_INTERNAL void m0_pdclust_instance_map(struct m0_pdclust_instance *pi, const struct m0_pdclust_src_addr *src, struct m0_pdclust_tgt_addr *tgt)
Definition: pdclust.c:701
union m0_dix_layout::@145 u
struct m0_fid ld_pver
Definition: layout.h:78
static struct m0_clink l[NR]
Definition: chan.c:37
M0_INTERNAL void m0_dix_layout_iter_reset(struct m0_dix_layout_iter *iter)
Definition: layout.c:310
M0_INTERNAL struct m0_layout * m0_pdl_to_layout(struct m0_pdclust_layout *pl)
Definition: pdclust.c:393
M0_INTERNAL void m0_dix_ldesc_fini(struct m0_dix_ldesc *ld)
Definition: layout.c:197
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
uint64_t sa_unit
Definition: pdclust.h:243
struct m0_pdclust_tgt_addr tgt
Definition: fd.c:110
static int rc
Definition: layout.c:51
uint64_t dit_unit
Definition: layout.h:141
#define M0_FI_ENABLED(tag)
Definition: finject.h:231
Definition: ext.h:37
Definition: fid.h:38
M0_INTERNAL void m0_dix_layout_iter_goto(struct m0_dix_layout_iter *iter, uint64_t unit)
Definition: layout.c:302
uint32_t pa_P
Definition: pdclust.h:115
M0_INTERNAL uint32_t m0_dix_liter_N(struct m0_dix_layout_iter *iter)
Definition: layout.c:270
M0_INTERNAL void m0_dix_imask_fini(struct m0_dix_imask *mask)
Definition: imask.c:118
M0_INTERNAL enum m0_pdclust_unit_type m0_pdclust_unit_classify(const struct m0_pdclust_layout *pl, int unit)
Definition: pdclust.c:425
uint32_t ld_hash_fnc
Definition: layout.h:77
static int layout_create(struct m0_layout_domain *domain, const struct m0_fid *fid, uint64_t layout_id, struct m0_pool_version *pver, struct m0_dix_linst *dli)
Definition: layout.c:47
static const struct m0_dtm_history_type htype
Definition: dtx.c:131
uint32_t dit_W
Definition: layout.h:138
struct m0_pdclust_layout * li_pl
Definition: layout.h:115
#define M0_ASSERT_INFO(cond, fmt,...)
M0_INTERNAL void m0_layout_instance_fini(struct m0_layout_instance *li)
Definition: layout.c:1123
M0_INTERNAL struct m0_pdclust_instance * m0_layout_instance_to_pdi(const struct m0_layout_instance *li)
Definition: pdclust.c:400
M0_INTERNAL void m0_layout_put(struct m0_layout *l)
Definition: layout.c:893
M0_INTERNAL void m0_fd_fwd_map(struct m0_pdclust_instance *pi, const struct m0_pdclust_src_addr *src, struct m0_pdclust_tgt_addr *tgt)
Definition: fd.c:838
static struct m0_layout_domain domain
Definition: layout.c:49
struct m0_buf dit_key
Definition: layout.h:147
M0_INTERNAL int m0_dix_layout_init(struct m0_dix_linst *dli, struct m0_layout_domain *domain, const struct m0_fid *fid, uint64_t layout_id, struct m0_pool_version *pver, struct m0_dix_ldesc *dld)
Definition: layout.c:86
M0_INTERNAL uint32_t m0_dix_devices_nr(struct m0_dix_linst *linst)
Definition: layout.c:68
struct m0_pdclust_src_addr src
Definition: fd.c:108
M0_INTERNAL uint32_t m0_dix_liter_P(struct m0_dix_layout_iter *iter)
Definition: layout.c:275
M0_INTERNAL struct m0_pooldev * m0_dix_tgt2sdev(struct m0_dix_linst *linst, uint64_t tgt)
Definition: layout.c:76
m0_dix_hash_fnc_type
Definition: layout.h:70
Definition: idx_mock.c:47
#define M0_IMPOSSIBLE(fmt,...)