Motr  M0
layout.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 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 #include "lib/errno.h"
24 #include "fid/fid.h" /* m0_fid */
25 #include "lib/locality.h" /* m0_locality_here() */
26 
27 #include "motr/client.h"
28 #include "motr/client_internal.h"
29 #include "motr/layout.h"
30 #include "dix/layout.h"
31 #include "cob/cob.h"
32 
33 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_CLIENT
34 #include "lib/trace.h"
35 #include "lib/finject.h"
36 
37 const struct m0_bob_type ol_bobtype;
38 M0_BOB_DEFINE(M0_INTERNAL, &ol_bobtype, m0_op_layout);
39 const struct m0_bob_type ol_bobtype = {
40  .bt_name = "ol_bobtype",
41  .bt_magix_offset = offsetof(struct m0_op_layout, ol_magic),
42  .bt_magix = M0_OL_MAGIC,
43  .bt_check = NULL,
44 };
45 
48 
52 static int pdclust_layout_get(struct m0_client_layout *layout)
53 {
54  return 0;
55 }
56 
57 static void pdclust_layout_put(struct m0_client_layout *layout)
58 {
59  return;
60 }
61 
63 {
64  struct m0_client_layout *layout;
65 
66  M0_ENTRY();
67 
68  *out = NULL;
69  layout = m0_alloc(sizeof(struct m0_client_pdclust_layout));
70  if (layout == NULL)
71  return M0_ERR(-ENOMEM);
72  layout->ml_type = M0_LT_PDCLUST;
73  layout->ml_ops = &layout_pdclust_ops;
74  *out = layout;
75 
76  return M0_RC(0);
77 }
78 
79 static const struct m0_client_layout_ops layout_pdclust_ops = {
81  .lo_get = pdclust_layout_get,
82  .lo_put = pdclust_layout_put,
83  .lo_io_build = m0__obj_io_build
84 };
85 
87  void *from)
88 {
89  struct m0_cob_attr *attr;
90  struct m0_client_pdclust_layout *pdclust;
91 
92  M0_PRE(from != NULL);
93  M0_PRE(to != NULL);
94 
95  attr = (struct m0_cob_attr*)from;
96  pdclust = M0_AMB(pdclust, to, pl_layout);
97  pdclust->pl_pver = attr->ca_pver;
98  pdclust->pl_lid = attr->ca_lid;
99  pdclust->pl_fid = attr->ca_tfid;
100 
101  return M0_RC(0);
102 }
103 
105  void *to)
106 {
107  struct m0_cob_attr *attr;
108  struct m0_client_pdclust_layout *pdclust;
109 
110  M0_PRE(from != NULL);
111 
112  attr = (struct m0_cob_attr*)to;
113  pdclust = M0_AMB(pdclust, from, pl_layout);
114  /* Only layout id is allowed to be changed. */
115  attr->ca_lid = pdclust->pl_lid;
116 
117  return M0_RC(0);
118 }
119 
120 static int pdclust_layout_launch(struct m0_op_layout *ol)
121 {
122  struct m0_obj *obj;
123 
125  return m0__obj_layout_send(obj, ol);
126 }
127 
130  .olo_copy_to_app = pdclust_layout_copy_to_app,
131  .olo_copy_from_app = pdclust_layout_copy_from_app,
132 };
133 
139  struct m0_obj *obj,
140  struct m0_client_layout **out)
141 {
142  struct m0_client_pdclust_layout *pdlayout;
143  struct m0_capture_layout *cap_layout;
144 
145  M0_PRE(obj != NULL);
146  M0_PRE(layout->ml_type == M0_LT_PDCLUST);
147  pdlayout = M0_AMB(pdlayout, layout, pl_layout);
148  M0_PRE(m0_fid_eq(&pdlayout->pl_pver, &obj->ob_attr.oa_pver));
149  M0_PRE(pdlayout->pl_lid == obj->ob_attr.oa_layout_id);
150 
152  if (*out == NULL)
153  return M0_ERR(-ENOMEM);
154  cap_layout = M0_AMB(cap_layout, *out, cl_layout);
155  cap_layout->cl_pver = pdlayout->pl_pver;
156  cap_layout->cl_lid = pdlayout->pl_lid;
157  cap_layout->cl_orig_id = obj->ob_entity.en_id;
158  return M0_RC(0);
159 }
160 M0_EXPORTED(m0_client_layout_capture);
161 
162 static int capture_layout_copy_to_app(struct m0_client_layout *to, void *from)
163 {
164  struct m0_dix_layout *dix_layout;
165  struct m0_dix_capture_ldesc *dix_cap_ldesc;
166  struct m0_capture_layout *cap_layout;
167 
168  M0_ENTRY();
169  M0_PRE(to != NULL);
170 
171  cap_layout = M0_AMB(cap_layout, to, cl_layout);
172  dix_layout = (struct m0_dix_layout *)from;
173  dix_cap_ldesc = &dix_layout->u.dl_cap_desc;
174  cap_layout->cl_orig_id = dix_cap_ldesc->ca_orig_id;
175  cap_layout->cl_pver = dix_cap_ldesc->ca_pver;
176  cap_layout->cl_lid = dix_cap_ldesc->ca_lid;
177 
178  return M0_RC(0);
179 }
180 
182  void *to)
183 {
184  struct m0_dix_layout *dix_layout;
185  struct m0_dix_capture_ldesc *dix_cap_ldesc;
186  struct m0_capture_layout *cap_layout;
187 
188  M0_ENTRY();
189  M0_PRE(from != NULL);
190 
191  cap_layout = M0_AMB(cap_layout, from, cl_layout);
192  dix_layout = (struct m0_dix_layout *)to;
193  dix_layout->dl_type = DIX_LTYPE_CAPTURE_DESCR;
194  dix_cap_ldesc = &dix_layout->u.dl_cap_desc;
195  dix_cap_ldesc->ca_orig_id = cap_layout->cl_orig_id;
196  dix_cap_ldesc->ca_pver = cap_layout->cl_pver;
197  dix_cap_ldesc->ca_lid = cap_layout->cl_lid;
198 
199  return M0_RC(0);
200 }
201 
204  .olo_copy_to_app = capture_layout_copy_to_app,
205  .olo_copy_from_app = capture_layout_copy_from_app,
206 };
207 
208 static int capture_layout_get_sync(struct m0_obj *obj)
209 {
210  struct m0_dix_layout dlayout;
211 
212  M0_ENTRY();
213  m0__dix_layout_get_sync(obj, &dlayout);
214  return M0_RC(capture_layout_copy_to_app(obj->ob_layout, &dlayout));
215 }
216 
217 static int capture_layout_get(struct m0_client_layout *layout)
218 {
219  struct m0_obj *obj;
220 
221  M0_ENTRY();
222 
223  /* Retrieve layout for the object this layout associated with. */
224  obj = layout->ml_obj;
226 }
227 
228 static void capture_layout_put(struct m0_client_layout *layout)
229 {
230  struct m0_capture_layout *cap_layout;
231 
232  cap_layout = M0_AMB(cap_layout, layout, cl_layout);
233  M0_SET0(cap_layout);
234 }
235 
237  struct m0_op **op)
238 {
239  struct m0_obj *obj;
240  struct m0_capture_layout *cap_layout;
241 
242  obj = args->ia_obj;
243  cap_layout = M0_AMB(cap_layout, obj->ob_layout, cl_layout);
244  /* Navigate IO to original object. */
245  obj->ob_entity.en_id = cap_layout->cl_orig_id;
246  return M0_RC(m0__obj_io_build(args, op));
247 };
248 
250 {
251  struct m0_client_layout *layout;
252 
253  M0_ENTRY();
254 
255  *out = NULL;
256  layout = m0_alloc(sizeof(struct m0_capture_layout));
257  if (layout == NULL)
258  return M0_ERR(-ENOMEM);
259  layout->ml_type = M0_LT_CAPTURE;
260  layout->ml_ops = &layout_capture_ops;
261  *out = layout;
262 
263  return M0_RC(0);
264 }
265 
266 static const struct m0_client_layout_ops layout_capture_ops = {
268  .lo_get = capture_layout_get,
269  .lo_put = capture_layout_put,
270  .lo_io_build = capture_layout_io_build,
271 };
272 
276 M0_INTERNAL int m0_client__layout_get(struct m0_client_layout *layout)
277 {
278  int rc = 0;
279 
280  M0_ENTRY();
281  M0_PRE(layout != NULL);
282 
283  if (layout->ml_ops->lo_get != NULL)
284  rc = layout->ml_ops->lo_get(layout);
285  return M0_RC(rc);
286 }
287 
288 M0_INTERNAL void m0_client__layout_put(struct m0_client_layout *layout)
289 {
290  M0_ENTRY();
291  M0_PRE(layout != NULL);
292 
293  if (layout->ml_ops->lo_put != NULL)
294  layout->ml_ops->lo_put(layout);
295 
296  M0_LEAVE();
297 }
298 
302 static bool layout_op_invariant(struct m0_op_layout *ol)
303 {
304  return M0_RC(ol != NULL &&
305  m0_op_layout_bob_check(ol) &&
306  ol->ol_oc.oc_op.op_size >= sizeof *ol &&
307  ol->ol_ops != NULL &&
308  m0_ast_rc_bob_check(&ol->ol_ar) &&
309  m0_op_common_bob_check(&ol->ol_oc));
310 }
311 
312 /*
313  * Callback for an LAYOUT operation being finalised.
314  */
315 static void layout_op_cb_fini(struct m0_op_common *oc)
316 {
317  struct m0_op_layout *ol;
318 
319  M0_ENTRY();
320 
321  M0_PRE(oc != NULL);
322  M0_PRE(oc->oc_op.op_size >= sizeof *ol);
323 
324  ol = bob_of(oc, struct m0_op_layout, ol_oc, &ol_bobtype);
326 
327  m0_op_common_bob_fini(&ol->ol_oc);
328  m0_ast_rc_bob_fini(&ol->ol_ar);
329  m0_op_layout_bob_fini(ol);
330 
331  M0_LEAVE();
332 }
333 
334 /*
335  * 'free entry' on the operations vector for LAYOUT operations.
336  */
337 static void layout_op_cb_free(struct m0_op_common *oc)
338 {
339  struct m0_op_layout *ol;
340 
341  M0_ENTRY();
342 
343  M0_PRE(oc != NULL);
344  M0_PRE((oc->oc_op.op_size >= sizeof *ol));
345 
346  /* By now, fini() has been called and bob_of cannot be used */
347  ol = M0_AMB(ol, oc, ol_oc);
348  m0_free(ol);
349 
350  M0_LEAVE();
351 }
352 
353 /*
354  * Callback for an LAYOUT operation being launched.
355  */
356 static void layout_op_cb_launch(struct m0_op_common *oc)
357 {
358  int rc;
359  struct m0_op *op = &oc->oc_op;
360  struct m0_op_layout *ol = bob_of(oc, struct m0_op_layout,
361  ol_oc, &ol_bobtype);
362 
363  M0_ENTRY();
364  M0_PRE(oc != NULL);
365  M0_PRE(M0_IN(op->op_code, (M0_EO_LAYOUT_GET,
366  M0_EO_LAYOUT_SET)));
367  M0_PRE(m0_sm_group_is_locked(&op->op_sm_group));
369 
370  rc = ol->ol_ops->olo_launch(ol);
371  if (rc == 0)
372  m0_sm_move(&op->op_sm, 0, M0_OS_LAUNCHED);
373  else {
374  /* m0_op_launch() has held the lock. */
375  m0_sm_fail(&op->op_sm, M0_OS_FAILED, rc);
376  m0_op_failed(op);
377  }
378  M0_LEAVE();
379 }
380 
381 static int layout_op_init(struct m0_obj *obj,
382  struct m0_client_layout *layout,
384  struct m0_op *op)
385 {
386  int rc;
387  struct m0_op_common *oc;
388  struct m0_op_layout *ol;
389  struct m0_locality *locality;
390 
391  M0_ENTRY();
392 
393  op->op_code = opcode;
394  rc = m0_op_init(op, &m0_op_conf, &obj->ob_entity);
395  if (rc != 0)
396  return M0_RC(rc);
397  /*
398  * Initialise m0_op_common part.
399  */
400  oc = M0_AMB(oc, op, oc_op);
401  m0_op_common_bob_init(oc);
405 
406  /* Initialise the rest of m0_op_layout. */
407  ol = M0_AMB(ol, oc, ol_oc);
408  ol->ol_entity = &obj->ob_entity;
409  ol->ol_layout = layout;
410  switch(ol->ol_layout->ml_type) {
411  case M0_LT_PDCLUST:
413  break;
414  case M0_LT_CAPTURE:
416  break;
417  case M0_LT_COMPOSITE:
419  break;
420  default:
421  M0_IMPOSSIBLE("layout type not implemented");
422  }
423 
424  /* Pick a locality thread for this op. */
426  M0_ASSERT(locality != NULL);
427  ol->ol_sm_grp = locality->lo_grp;
428  M0_SET0(&ol->ol_ar);
429 
430  m0_op_layout_bob_init(ol);
431  m0_ast_rc_bob_init(&ol->ol_ar);
432 
433  return M0_RC(0);
434 }
435 
438  struct m0_client_layout *layout,
439  struct m0_op **op)
440 {
441  int rc = 0;
442  struct m0_op_common *oc;
443  struct m0_op_layout *ol;
444 
445  M0_ENTRY();
446 
447  M0_PRE(layout != NULL);
448  M0_PRE(op != NULL);
450  M0_EO_LAYOUT_SET)));
451 
452  rc = m0_op_get(op, sizeof(struct m0_op_layout))?:
453  layout_op_init(obj, layout, opcode, *op);
454  if (rc != 0)
455  goto error;
456 
457  M0_POST(rc == 0);
458  M0_POST(*op != NULL);
459  oc = bob_of(*op, struct m0_op_common, oc_op, &oc_bobtype);
460  ol = bob_of(oc, struct m0_op_layout, ol_oc, &ol_bobtype);
462  m0_sm_group_lock(&(*op)->op_sm_group);
463  M0_POST((*op)->op_sm.sm_rc == 0);
464  m0_sm_group_unlock(&(*op)->op_sm_group);
465 
466  return M0_RC(0);
467 error:
468  M0_ASSERT(rc != 0);
469  return M0_ERR(rc);
470 }
471 M0_EXPORTED(m0_client_layout_op);
472 
474 {
475  int rc;
476  struct m0_client_layout *layout;
477  const struct m0_client_layout_ops *ops;
478 
479  M0_ENTRY();
480  M0_PRE(type >= 0 && type < M0_LT_NR);
481 
482  switch(type) {
483  case M0_LT_PDCLUST:
485  break;
486  case M0_LT_COMPOSITE:
488  break;
489  case M0_LT_CAPTURE:
491  break;
492  default:
493  M0_IMPOSSIBLE("Layout type not supported yet.");
494  }
495  rc = ops->lo_alloc(&layout);
496  if (rc != 0)
497  M0_ASSERT(layout == NULL);
498 
499  M0_LEAVE();
500  return layout;
501 }
502 M0_EXPORTED(m0_client_layout_alloc);
503 
505 {
506  m0_free(layout);
507 }
508 M0_EXPORTED(m0_client_layout_free);
509 
510 #undef M0_TRACE_SUBSYSTEM
511 
512 /*
513  * Local variables:
514  * c-indentation-style: "K&R"
515 
516  * c-basic-offset: 8
517  * tab-width: 8
518  * fill-column: 80
519  * scroll-step: 1
520  * End:
521  */
522 /*
523  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
524  */
const struct m0_client_layout_ops layout_composite_ops
struct m0_entity * ol_entity
Definition: layout.h:183
#define M0_PRE(cond)
M0_INTERNAL void m0_sm_fail(struct m0_sm *mach, int fail_state, int32_t rc)
Definition: sm.c:468
M0_INTERNAL int m0__obj_layout_send(struct m0_obj *obj, struct m0_op_layout *ol)
Definition: cob.c:2043
M0_INTERNAL int m0_op_get(struct m0_op **op, size_t size)
Definition: client.c:568
static int pdclust_layout_get(struct m0_client_layout *layout)
Definition: layout.c:52
Definition: client.h:788
static void layout_op_cb_free(struct m0_op_common *oc)
Definition: layout.c:337
struct m0_sm_group * ol_sm_grp
Definition: layout.h:178
#define NULL
Definition: misc.h:38
M0_INTERNAL int m0_layout_op_launch(struct m0_op_layout *ol)
m0_entity_opcode
Definition: client.h:523
static size_t locality(const struct m0_fom *fom)
Definition: rm_foms.c:269
static void capture_layout_put(struct m0_client_layout *layout)
Definition: layout.c:228
M0_INTERNAL int m0_client__layout_get(struct m0_client_layout *layout)
Definition: layout.c:276
M0_LEAVE()
struct m0_fid pl_fid
Definition: layout.h:128
static int capture_layout_alloc(struct m0_client_layout **out)
Definition: layout.c:249
static int pdclust_layout_copy_from_app(struct m0_client_layout *from, void *to)
Definition: layout.c:104
static int capture_layout_get(struct m0_client_layout *layout)
Definition: layout.c:217
static int pdclust_layout_launch(struct m0_op_layout *ol)
Definition: layout.c:120
struct m0_op oc_op
M0_INTERNAL int m0_op_init(struct m0_op *op, const struct m0_sm_conf *conf, struct m0_entity *entity)
Definition: client.c:806
static int pdclust_layout_alloc(struct m0_client_layout **out)
Definition: layout.c:62
static int error
Definition: mdstore.c:64
#define M0_SET0(obj)
Definition: misc.h:64
static const struct m0_client_layout_ops layout_pdclust_ops
Definition: layout.c:46
Definition: ub.c:49
static const struct m0_op_layout_ops m0_op_layout_capture_ops
Definition: layout.c:202
struct m0_uint128 ca_orig_id
Definition: layout.h:83
uint64_t cl_lid
Definition: layout.h:121
static struct foo * obj
Definition: tlist.c:302
const char * bt_name
Definition: bob.h:73
static const struct m0_client_layout_ops layout_capture_ops
Definition: layout.c:47
struct m0_fid pl_pver
Definition: layout.h:126
return M0_RC(rc)
struct m0_fid ca_pver
Definition: layout.h:84
op
Definition: libdemo.c:64
int(* olo_launch)(struct m0_op_layout *ol)
Definition: layout.h:167
M0_INTERNAL struct m0_obj * m0__obj_entity(struct m0_entity *entity)
Definition: obj.c:51
#define M0_ENTRY(...)
Definition: trace.h:170
M0_INTERNAL void m0_sm_group_unlock(struct m0_sm_group *grp)
Definition: sm.c:96
int opcode
Definition: crate.c:301
enum m0_client_layout_type ml_type
Definition: client.h:798
M0_INTERNAL int m0__dix_layout_get_sync(struct m0_obj *obj, struct m0_dix_layout *dlayout)
size_t op_size
Definition: client.h:664
M0_INTERNAL void m0_client__layout_put(struct m0_client_layout *layout)
Definition: layout.c:288
Definition: client.h:641
const struct m0_bob_type oc_bobtype
Definition: client.c:44
void(* oc_cb_free)(struct m0_op_common *oc)
return M0_ERR(-EOPNOTSUPP)
struct m0_client_layout * m0_client_layout_alloc(enum m0_client_layout_type type)
Definition: layout.c:473
struct m0_uint128 cl_orig_id
Definition: layout.h:119
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
static void attr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
Definition: dump.c:949
static void layout_op_cb_launch(struct m0_op_common *oc)
Definition: layout.c:356
void m0_client_layout_free(struct m0_client_layout *layout)
Definition: layout.c:504
#define M0_ASSERT(cond)
static int capture_layout_copy_from_app(struct m0_client_layout *from, void *to)
Definition: layout.c:181
static int capture_layout_copy_to_app(struct m0_client_layout *to, void *from)
Definition: layout.c:162
struct m0_client_layout * ol_layout
Definition: layout.h:181
#define bob_of(ptr, type, field, bt)
Definition: bob.h:140
struct m0_fid cl_pver
Definition: layout.h:120
struct m0_op_common ol_oc
Definition: layout.h:175
uint64_t ca_lid
Definition: layout.h:85
void * m0_alloc(size_t size)
Definition: memory.c:126
#define M0_POST(cond)
M0_BOB_DEFINE(static, &layout_bob, m0_layout)
uint32_t dl_type
Definition: layout.h:100
int(* lo_alloc)(struct m0_client_layout **)
void(* oc_cb_fini)(struct m0_op_common *oc)
void(* lo_put)(struct m0_client_layout *)
union m0_dix_layout::@145 u
struct m0_ast_rc ol_ar
Definition: layout.h:179
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
struct m0_client_layout cl_layout
Definition: layout.h:118
const struct m0_bob_type ol_bobtype
Definition: layout.c:37
static void pdclust_layout_put(struct m0_client_layout *layout)
Definition: layout.c:57
struct m0_obj * ml_obj
Definition: client.h:800
static int rc
Definition: layout.c:51
const struct m0_op_layout_ops m0_op_layout_composite_ops
static int capture_layout_io_build(struct m0_io_args *args, struct m0_op **op)
Definition: layout.c:236
M0_INTERNAL int m0_op_failed(struct m0_op *op)
Definition: client.c:548
M0_INTERNAL struct m0_locality * m0__locality_pick(struct m0_client *cinst)
Definition: client.c:290
static void layout_op_cb_fini(struct m0_op_common *oc)
Definition: layout.c:315
static int pdclust_layout_copy_to_app(struct m0_client_layout *to, void *from)
Definition: layout.c:86
const struct m0_op_layout_ops * ol_ops
Definition: layout.h:185
int m0_client_layout_op(struct m0_obj *obj, enum m0_entity_opcode opcode, struct m0_client_layout *layout, struct m0_op **op)
Definition: layout.c:436
M0_INTERNAL void m0_sm_move(struct m0_sm *mach, int32_t rc, int state)
Definition: sm.c:485
const struct m0_client_layout_ops * ml_ops
Definition: client.h:801
m0_client_layout_type
Definition: client.h:776
M0_INTERNAL void m0_sm_group_lock(struct m0_sm_group *grp)
Definition: sm.c:83
int m0_client_layout_capture(struct m0_client_layout *layout, struct m0_obj *obj, struct m0_client_layout **out)
Definition: layout.c:138
M0_INTERNAL int m0__obj_io_build(struct m0_io_args *args, struct m0_op **op)
Definition: io.c:677
#define out(...)
Definition: gen.c:41
static int capture_layout_get_sync(struct m0_obj *obj)
Definition: layout.c:208
int type
Definition: dir.c:1031
int(* lo_get)(struct m0_client_layout *)
void(* oc_cb_launch)(struct m0_op_common *oc)
struct m0_fom_ops ops
Definition: io_foms.c:623
static int layout_op_init(struct m0_obj *obj, struct m0_client_layout *layout, enum m0_entity_opcode opcode, struct m0_op *op)
Definition: layout.c:381
static bool layout_op_invariant(struct m0_op_layout *ol)
Definition: layout.c:302
static const struct m0_op_layout_ops m0_op_layout_pdclust_ops
Definition: layout.c:128
void m0_free(void *data)
Definition: memory.c:146
#define offsetof(typ, memb)
Definition: misc.h:29
M0_INTERNAL bool m0_sm_group_is_locked(const struct m0_sm_group *grp)
Definition: sm.c:107
struct m0_sm_conf m0_op_conf
Definition: client.c:145
#define M0_IMPOSSIBLE(fmt,...)