Motr  M0
pver.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2020 Seagate Technology LLC and/or its Affiliates
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  *
19  */
20 
21 
22 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CONF
23 #include "lib/trace.h"
24 
25 #include "conf/objs/common.h"
26 #include "conf/onwire_xc.h" /* m0_confx_pver_xc */
27 #include "conf/pvers.h" /* M0_CONF_PVER_FORMULAIC */
28 #include "motr/magic.h" /* M0_CONF_PVER_MAGIC */
29 #include "layout/pdclust.h" /* m0_pdclust_attr_check */
30 
31 #define XCAST(xobj) ((struct m0_confx_pver *)(&(xobj)->xo_u))
33 
34 static bool pver_check(const void *bob)
35 {
36  const struct m0_conf_pver *self = bob;
37  const struct m0_conf_obj *self_obj = &self->pv_obj;
38  enum m0_conf_pver_kind kind;
39 
40  return m0_conf_obj_is_stub(self_obj) ||
42  &self_obj->co_id, &kind, NULL, NULL) == 0) &&
43  _0C(kind == self->pv_kind) &&
44  ergo(kind == M0_CONF_PVER_ACTUAL,
46  &self->pv_u.subtree.pvs_attr))) &&
48  /* at least one of the numbers != 0 */
49  _0C(!M0_IS0(&self->pv_u.formulaic.pvf_allowance))) &&
50  ergo(kind == M0_CONF_PVER_VIRTUAL,
51  self_obj->co_parent == NULL));
52 }
53 
56 
57 static int
58 pver_decode(struct m0_conf_obj *dest, const struct m0_confx_obj *src)
59 {
61  const struct m0_confx_pver_u *sa = &XCAST(src)->xv_u;
62  int rc;
63 
64  M0_ENTRY("dest="FID_F, FID_P(&dest->co_id));
65 
66  rc = m0_conf_pver_fid_read(&src->xo_u.u_header.ch_id, &da->pv_kind,
67  NULL, NULL);
68  if (rc != 0)
69  return M0_ERR(rc);
71  return M0_ERR(-EINVAL);
72 
73  switch (da->pv_kind) {
74  case M0_CONF_PVER_ACTUAL: {
75  struct m0_conf_pver_subtree *d = &da->pv_u.subtree;
76  const struct m0_confx_pver_actual *s = &sa->u.xpv_actual;
77 
78  *d = (struct m0_conf_pver_subtree){
79  .pvs_attr = (struct m0_pdclust_attr){
80  .pa_N = s->xva_N,
81  .pa_K = s->xva_K,
82  .pa_S = s->xva_S,
83  .pa_P = s->xva_P
84  }
85  };
86  if (s->xva_tolerance.au_count != ARRAY_SIZE(d->pvs_tolerance))
87  return M0_ERR(-EINVAL);
88  memcpy(d->pvs_tolerance, s->xva_tolerance.au_elems,
89  sizeof(d->pvs_tolerance));
90  return M0_RC(m0_conf_dir_new(dest, &M0_CONF_PVER_SITEVS_FID,
91  &M0_CONF_OBJV_TYPE, &s->xva_sitevs,
92  &d->pvs_sitevs));
93  }
95  struct m0_conf_pver_formulaic *d = &da->pv_u.formulaic;
96  const struct m0_confx_pver_formulaic *s = &sa->u.xpv_formulaic;
97 
98  *d = (struct m0_conf_pver_formulaic){
99  .pvf_id = s->xvf_id,
100  .pvf_base = s->xvf_base
101  };
102  if (s->xvf_allowance.au_count != ARRAY_SIZE(d->pvf_allowance))
103  return M0_ERR(-EINVAL);
104  memcpy(d->pvf_allowance, s->xvf_allowance.au_elems,
105  sizeof(d->pvf_allowance));
106  return M0_RC(0);
107  }
108  default:
109  return M0_ERR(-EINVAL);
110  }
111 }
112 
113 static int
114 pver_encode(struct m0_confx_obj *dest, const struct m0_conf_obj *src)
115 {
116  const struct m0_conf_pver *sa = M0_CONF_CAST(src, m0_conf_pver);
117  struct m0_confx_pver_u *da = &XCAST(dest)->xv_u;
118  int rc;
119 
121  da->xpv_is_formulaic = sa->pv_kind;
122  switch (sa->pv_kind) {
123  case M0_CONF_PVER_ACTUAL: {
124  const struct m0_conf_pver_subtree *s = &sa->pv_u.subtree;
125  struct m0_confx_pver_actual *d = &da->u.xpv_actual;
126 
127  *d = (struct m0_confx_pver_actual) {
128  .xva_N = s->pvs_attr.pa_N,
129  .xva_K = s->pvs_attr.pa_K,
130  .xva_S = s->pvs_attr.pa_S,
131  .xva_P = s->pvs_attr.pa_P
132  };
133  rc = u32arr_encode(&d->xva_tolerance, s->pvs_tolerance,
134  ARRAY_SIZE(s->pvs_tolerance));
135  if (rc != 0)
136  return M0_ERR(rc);
137 
138  rc = arrfid_from_dir(&d->xva_sitevs, s->pvs_sitevs);
139  if (rc != 0)
141  return M0_RC(rc);
142  }
143  case M0_CONF_PVER_FORMULAIC: {
144  const struct m0_conf_pver_formulaic *s = &sa->pv_u.formulaic;
145  struct m0_confx_pver_formulaic *d = &da->u.xpv_formulaic;
146 
147  *d = (struct m0_confx_pver_formulaic) {
148  .xvf_id = s->pvf_id,
149  .xvf_base = s->pvf_base
150  };
151  return M0_RC(u32arr_encode(&d->xvf_allowance, s->pvf_allowance,
152  ARRAY_SIZE(s->pvf_allowance)));
153  }
154  default:
155  M0_IMPOSSIBLE("");
156  }
157 }
158 
159 static bool
160 pver_match(const struct m0_conf_obj *cached, const struct m0_confx_obj *flat)
161 {
162  const struct m0_confx_pver_u *xobj = &XCAST(flat)->xv_u;
163  const struct m0_conf_pver *obj = M0_CONF_CAST(cached, m0_conf_pver);
164  /*
165  * This check will fail if the "kind" bits of the confx_obj's fid
166  * do not correspond to those of actual or formulaic pver.
167  */
168  M0_PRE(M0_IN(obj->pv_kind,
170  return
171  xobj->xpv_is_formulaic ==
172  (obj->pv_kind == M0_CONF_PVER_FORMULAIC) &&
173  (xobj->xpv_is_formulaic ? ({
174  const struct m0_confx_pver_formulaic *x =
175  &xobj->u.xpv_formulaic;
176  const struct m0_conf_pver_formulaic *c =
177  &obj->pv_u.formulaic;
178 
179  c->pvf_id == x->xvf_id &&
180  m0_fid_eq(&c->pvf_base, &x->xvf_base) &&
181  u32arr_cmp(&x->xvf_allowance, c->pvf_allowance,
182  ARRAY_SIZE(c->pvf_allowance));
183  }) : ({
184  const struct m0_confx_pver_actual *x =
185  &xobj->u.xpv_actual;
186  const struct m0_conf_pver_subtree *c =
187  &obj->pv_u.subtree;
188 
189  c->pvs_attr.pa_N == x->xva_N &&
190  c->pvs_attr.pa_K == x->xva_K &&
191  c->pvs_attr.pa_S == x->xva_S &&
192  c->pvs_attr.pa_P == x->xva_P &&
193  u32arr_cmp(&x->xva_tolerance, c->pvs_tolerance,
194  ARRAY_SIZE(c->pvs_tolerance)) &&
195  m0_conf_dir_elems_match(c->pvs_sitevs, &x->xva_sitevs);
196  }));
197 }
198 
199 static int pver_lookup(const struct m0_conf_obj *parent,
200  const struct m0_fid *name, struct m0_conf_obj **out)
201 {
202  const struct m0_conf_pver *pver = M0_CONF_CAST(parent, m0_conf_pver);
203 
204  M0_PRE(parent->co_status == M0_CS_READY);
205 
206  if (!m0_fid_eq(name, &M0_CONF_PVER_SITEVS_FID))
207  return M0_ERR(-ENOENT);
208 
209  if (pver->pv_kind == M0_CONF_PVER_FORMULAIC) {
210  /*
211  * XXX FIXME: ->coo_lookup() must not be called for
212  * formulaic pvers.
213  */
214  struct m0_conf_obj *obj;
215  int rc;
216 
217  rc = m0_conf_obj_find(parent->co_cache,
218  &pver->pv_u.formulaic.pvf_base, &obj) ?:
219  obj->co_ops->coo_lookup(obj, name, out);
220  if (rc != 0)
221  return M0_ERR(rc);
222  } else
223  *out = &pver->pv_u.subtree.pvs_sitevs->cd_obj;
225  return M0_RC(0);
226 }
227 
228 static const struct m0_fid **pver_downlinks(const struct m0_conf_obj *obj)
229 {
230  static const struct m0_fid *rels[] = { &M0_CONF_PVER_SITEVS_FID,
231  NULL };
232  const struct m0_conf_pver *pver = M0_CONF_CAST(obj, m0_conf_pver);
233 
234  return pver->pv_kind == M0_CONF_PVER_FORMULAIC
235  ? &rels[1] /* formulaic pver has no downlinks */
236  : rels;
237 }
238 
239 static void pver_delete(struct m0_conf_obj *obj)
240 {
242 
243  m0_conf_pver_bob_fini(x);
244  m0_free(x);
245 }
246 
247 static const struct m0_conf_obj_ops pver_ops = {
248  .coo_invariant = pver_invariant,
249  .coo_decode = pver_decode,
250  .coo_encode = pver_encode,
251  .coo_match = pver_match,
252  .coo_lookup = pver_lookup,
253  .coo_readdir = NULL,
254  .coo_downlinks = pver_downlinks,
255  .coo_delete = pver_delete
256 };
257 
259 
261  .cot_ftype = {
262  .ft_id = M0_CONF__PVER_FT_ID,
263  .ft_name = "conf_pver"
264  },
265  .cot_create = &pver_create,
266  .cot_xt = &m0_confx_pver_xc,
267  .cot_branch = "u_pver",
268  .cot_xc_init = &m0_xc_m0_confx_pver_struct_init,
269  .cot_magic = M0_CONF_PVER_MAGIC
270 };
271 
272 #undef XCAST
273 #undef M0_TRACE_SUBSYSTEM
274 
275 /*
276  * Local variables:
277  * c-indentation-style: "K&R"
278  * c-basic-offset: 8
279  * tab-width: 8
280  * fill-column: 80
281  * scroll-step: 1
282  * End:
283  */
284 /*
285  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
286  */
struct m0_fid co_id
Definition: obj.h:208
#define M0_PRE(cond)
const struct m0_conf_obj_type M0_CONF_OBJV_TYPE
Definition: objv.c:151
struct m0_conf_dir * pvs_sitevs
Definition: obj.h:478
static const struct m0_conf_obj_ops pver_ops
Definition: pver.c:247
struct m0_pdclust_attr pvs_attr
Definition: obj.h:481
#define NULL
Definition: misc.h:38
static bool pver_match(const struct m0_conf_obj *cached, const struct m0_confx_obj *flat)
Definition: pver.c:160
#define ergo(a, b)
Definition: misc.h:293
static bool x
Definition: sm.c:168
uint32_t pa_N
Definition: pdclust.h:104
union m0_confx_pver_u::@125 u
const struct m0_conf_obj_type M0_CONF_PVER_TYPE
Definition: pver.c:260
uint8_t ft_id
Definition: fid.h:101
M0_CONF__INVARIANT_DEFINE(pver_invariant, m0_conf_pver)
bool(* coo_invariant)(const struct m0_conf_obj *obj)
Definition: obj_ops.h:79
static bool pver_check(const void *bob)
Definition: pver.c:34
M0_BASSERT(offsetof(struct m0_confx_pver, xv_header)==0)
struct m0_conf_cache * co_cache
Definition: obj.h:251
struct arr_u32 xva_tolerance
Definition: onwire.h:98
uint32_t pvf_allowance[M0_CONF_PVER_HEIGHT]
Definition: obj.h:512
struct m0_conf_obj * co_parent
Definition: obj.h:223
M0_INTERNAL bool m0_conf_obj_is_stub(const struct m0_conf_obj *obj)
Definition: obj.c:302
uint8_t xpv_is_formulaic
Definition: onwire.h:118
m0_conf_pver_kind
Definition: obj.h:516
static struct foo * obj
Definition: tlist.c:302
enum m0_conf_pver_kind pv_kind
Definition: obj.h:535
return M0_RC(rc)
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL int m0_conf_dir_new(struct m0_conf_obj *parent, const struct m0_fid *relfid, const struct m0_conf_obj_type *children_type, const struct m0_fid_arr *children_ids, struct m0_conf_dir **out)
Definition: dir.c:159
M0_CONF__BOB_DEFINE(m0_conf_pver, M0_CONF_PVER_MAGIC, pver_check)
M0_CONF__CTOR_DEFINE(pver_create, m0_conf_pver, &pver_ops)
return M0_ERR(-EOPNOTSUPP)
const char * name
Definition: trace.c:110
const struct m0_fid_type cot_ftype
Definition: obj.h:314
struct m0_fid pver
Definition: idx_dix.c:74
static struct m0_addb2_callback c
Definition: consumer.c:41
union m0_conf_pver::@122 pv_u
uint32_t pvs_tolerance[M0_CONF_PVER_HEIGHT]
Definition: obj.h:487
struct arr_u32 xvf_allowance
Definition: onwire.h:112
M0_INTERNAL void confx_encode(struct m0_confx_obj *dest, const struct m0_conf_obj *src)
Definition: common.c:110
uint32_t pvf_id
Definition: obj.h:493
#define M0_POST(cond)
M0_INTERNAL int m0_conf_pver_fid_read(const struct m0_fid *fid, enum m0_conf_pver_kind *kind, uint64_t *container, uint64_t *key)
Definition: pvers.c:352
struct m0_confx_header xv_header
Definition: onwire.h:120
M0_INTERNAL int m0_conf_obj_find(struct m0_conf_cache *cache, const struct m0_fid *id, struct m0_conf_obj **out)
Definition: obj_ops.c:136
static int pver_encode(struct m0_confx_obj *dest, const struct m0_conf_obj *src)
Definition: pver.c:114
#define M0_CONF_CAST(ptr, type)
Definition: obj.h:780
M0_INTERNAL int arrfid_from_dir(struct m0_fid_arr *dest, const struct m0_conf_dir *dir)
Definition: common.c:82
static void pver_delete(struct m0_conf_obj *obj)
Definition: pver.c:239
#define FID_P(f)
Definition: fid.h:77
static int pver_lookup(const struct m0_conf_obj *parent, const struct m0_fid *name, struct m0_conf_obj **out)
Definition: pver.c:199
struct m0_conf_pver_subtree subtree
Definition: obj.h:537
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
M0_INTERNAL void u32arr_free(struct arr_u32 *arr)
Definition: common.c:151
static int pver_decode(struct m0_conf_obj *dest, const struct m0_confx_obj *src)
Definition: pver.c:58
Definition: fid.h:38
#define M0_IS0(obj)
Definition: misc.h:70
struct m0_conf_pver_formulaic formulaic
Definition: obj.h:538
M0_INTERNAL int u32arr_encode(struct arr_u32 *dest, const uint32_t *src, uint32_t src_nr)
Definition: common.c:129
#define _0C(exp)
Definition: assert.h:311
uint32_t xva_N
Definition: onwire.h:88
enum m0_conf_status co_status
Definition: obj.h:210
#define out(...)
Definition: gen.c:41
M0_INTERNAL bool u32arr_cmp(const struct arr_u32 *a1, const uint32_t *a2, uint32_t a2_nr)
Definition: common.c:145
void m0_free(void *data)
Definition: memory.c:146
static struct m0_addb2_source * s
Definition: consumer.c:39
M0_INTERNAL bool m0_conf_dir_elems_match(const struct m0_conf_dir *dir, const struct m0_fid_arr *fids)
Definition: dir.c:63
struct m0_pdclust_src_addr src
Definition: fd.c:108
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
#define offsetof(typ, memb)
Definition: misc.h:29
M0_INTERNAL bool m0_conf_obj_invariant(const struct m0_conf_obj *obj)
Definition: obj_ops.c:52
static const struct m0_fid ** pver_downlinks(const struct m0_conf_obj *obj)
Definition: pver.c:228
struct m0_fid_arr xva_sitevs
Definition: onwire.h:99
#define FID_F
Definition: fid.h:75
#define XCAST(xobj)
Definition: pver.c:31
#define M0_IMPOSSIBLE(fmt,...)
M0_INTERNAL bool m0_pdclust_attr_check(const struct m0_pdclust_attr *attr)
Definition: pdclust.c:340