Motr  M0
tx_desc.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2021 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 #include "dtm0/clk_src.h"
31 #include "lib/misc.h"
32 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_DTM0
33 #include "dtm0/tx_desc.h"
34 #include "lib/assert.h" /* M0_PRE */
35 #include "lib/memory.h" /* M0_ALLOC */
36 #include "lib/errno.h" /* ENOMEM */
37 #include "lib/trace.h" /* M0_ERR */
38 
39 M0_INTERNAL void m0_dtm0_tx_desc_init_none(struct m0_dtm0_tx_desc *td)
40 {
41  M0_SET0(td);
42 }
43 
44 M0_INTERNAL bool m0_dtm0_tx_desc_is_none(const struct m0_dtm0_tx_desc *td)
45 {
46  return M0_IS0(td);
47 }
48 
49 M0_INTERNAL bool m0_dtm0_tx_desc__invariant(const struct m0_dtm0_tx_desc *td)
50 {
51  /*
52  * Assumption: a valid tx_desc should have
53  * pre-allocated array of participants AND
54  * the states should be inside the range [0, nr) AND
55  * if all PAs are moved past INIT state then
56  * the descriptor should have a valid ID.
57  */
58  return _0C(td->dtd_ps.dtp_pa != NULL) &&
60  td->dtd_ps.dtp_pa[i].p_state >= 0 &&
61  td->dtd_ps.dtp_pa[i].p_state < M0_DTPS_NR)) &&
63  td->dtd_ps.dtp_pa[i].p_state > M0_DTPS_INIT),
65 }
66 
67 M0_INTERNAL bool m0_dtm0_tid__invariant(const struct m0_dtm0_tid *tid)
68 {
69  return _0C(m0_dtm0_ts__invariant(&tid->dti_ts)) &&
70  _0C(m0_fid_is_set(&tid->dti_fid)) &&
71  _0C(m0_fid_is_valid(&tid->dti_fid));
72 }
73 
74 /* Writes a deep copy of "src" into "dst". */
75 M0_INTERNAL int m0_dtm0_tx_desc_copy(const struct m0_dtm0_tx_desc *src,
76  struct m0_dtm0_tx_desc *dst)
77 {
78  int rc;
79 
80  M0_ENTRY();
81 
83 
84  rc = m0_dtm0_tx_desc_init(dst, src->dtd_ps.dtp_nr);
85  if (rc == 0) {
86  dst->dtd_id = src->dtd_id;
87  memcpy(dst->dtd_ps.dtp_pa, src->dtd_ps.dtp_pa,
88  sizeof(src->dtd_ps.dtp_pa[0]) * src->dtd_ps.dtp_nr);
89 
91  }
92 
93  return M0_RC(rc);
94 }
95 
96 M0_INTERNAL int m0_dtm0_tx_desc_init(struct m0_dtm0_tx_desc *td,
97  uint32_t nr_pa)
98 {
99  M0_ENTRY();
100 
101  M0_ALLOC_ARR(td->dtd_ps.dtp_pa, nr_pa);
102  if (td->dtd_ps.dtp_pa == NULL)
103  return M0_ERR(-ENOMEM);
104  td->dtd_ps.dtp_nr = nr_pa;
106 
107  return M0_RC(0);
108 }
109 
110 M0_INTERNAL void m0_dtm0_tx_desc_fini(struct m0_dtm0_tx_desc *td)
111 {
112  M0_ENTRY();
113  m0_free(td->dtd_ps.dtp_pa);
114  M0_SET0(td);
115  M0_LEAVE();
116 }
117 
118 M0_INTERNAL int m0_dtm0_tid_cmp(struct m0_dtm0_clk_src *cs,
119  const struct m0_dtm0_tid *left,
120  const struct m0_dtm0_tid *right)
121 {
122  return m0_dtm0_ts_cmp(cs, &left->dti_ts, &right->dti_ts) ?:
123  m0_fid_cmp(&left->dti_fid, &right->dti_fid);
124 }
125 
126 M0_INTERNAL void m0_dtm0_tx_desc_apply(struct m0_dtm0_tx_desc *tgt,
127  const struct m0_dtm0_tx_desc *upd)
128 {
129  int i;
130  struct m0_dtm0_tx_pa *tgt_pa;
131  struct m0_dtm0_tx_pa *upd_pa;
132 
133  M0_ENTRY();
134 
137  M0_PRE(memcmp(&tgt->dtd_id, &upd->dtd_id, sizeof(tgt->dtd_id)) == 0);
138  M0_PRE(upd->dtd_ps.dtp_nr == tgt->dtd_ps.dtp_nr);
139  M0_PRE(m0_forall(i, upd->dtd_ps.dtp_nr,
140  m0_fid_cmp(&tgt->dtd_ps.dtp_pa[i].p_fid,
141  &upd->dtd_ps.dtp_pa[i].p_fid) == 0));
142 
143  for (i = 0; i < upd->dtd_ps.dtp_nr; ++i) {
144  tgt_pa = &tgt->dtd_ps.dtp_pa[i];
145  upd_pa = &upd->dtd_ps.dtp_pa[i];
146 
147  tgt_pa->p_state = max_check(tgt_pa->p_state,
148  upd_pa->p_state);
149  }
150 
151  M0_LEAVE();
152 }
153 
154 M0_INTERNAL bool m0_dtm0_tx_desc_state_eq(const struct m0_dtm0_tx_desc *txd,
155  enum m0_dtm0_tx_pa_state state)
156 {
157  return m0_forall(i, txd->dtd_ps.dtp_nr,
158  txd->dtd_ps.dtp_pa[i].p_state == state);
159 }
160 
161 M0_INTERNAL
163  enum m0_dtm0_tx_pa_state state)
164 {
165  return m0_exists(i, txd->dtd_ps.dtp_nr,
166  txd->dtd_ps.dtp_pa[i].p_state == state);
167 }
168 
169 /* XXX: This function has only one purpose -- to aid debugging with GDB */
170 M0_INTERNAL void m0_dtm0_tx_desc_print(const struct m0_dtm0_tx_desc *txd)
171 {
172  int i;
173 
174  static const struct {
175  char name;
176  } smap[M0_DTPS_NR] = {
177  [M0_DTPS_INIT ] = { .name = '0' },
178  [M0_DTPS_INPROGRESS ] = { .name = 'I' },
179  [M0_DTPS_EXECUTED ] = { .name = 'E' },
180  [M0_DTPS_PERSISTENT ] = { .name = 'P' },
181  };
182 
183  M0_LOG(M0_ALWAYS, "txid=" DTID0_F, DTID0_P(&txd->dtd_id));
184 
185  for (i = 0; i < txd->dtd_ps.dtp_nr; ++i) {
186  M0_LOG(M0_ALWAYS, "\tpa=" FID_F ", %c",
187  FID_P(&txd->dtd_ps.dtp_pa[i].p_fid),
188  smap[txd->dtd_ps.dtp_pa[i].p_state].name);
189  }
190 }
191 
192 #undef M0_TRACE_SUBSYSTEM
193 
196 /*
197  * Local variables:
198  * c-indentation-style: "K&R"
199  * c-basic-offset: 8
200  * tab-width: 8
201  * fill-column: 80
202  * scroll-step: 1
203  * End:
204  */
205 /*
206  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
207  */
M0_INTERNAL enum m0_dtm0_ts_ord m0_dtm0_ts_cmp(const struct m0_dtm0_clk_src *cs, const struct m0_dtm0_ts *left, const struct m0_dtm0_ts *right)
Definition: clk_src.c:61
M0_INTERNAL int m0_dtm0_tx_desc_init(struct m0_dtm0_tx_desc *td, uint32_t nr_pa)
Definition: tx_desc.c:96
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
#define NULL
Definition: misc.h:38
static struct m0_bufvec dst
Definition: xform.c:61
#define ergo(a, b)
Definition: misc.h:293
#define M0_LOG(level,...)
Definition: trace.h:167
M0_LEAVE()
#define max_check(a, b)
Definition: arith.h:95
struct m0_dtm0_ts dti_ts
Definition: tx_desc.h:94
M0_DTPS_INPROGRESS
Definition: tx_desc.h:171
#define m0_exists(var, nr,...)
Definition: misc.h:134
static int left
Definition: locality.c:280
M0_INTERNAL bool m0_dtm0_tx_desc__invariant(const struct m0_dtm0_tx_desc *td)
Definition: tx_desc.c:49
#define M0_SET0(obj)
Definition: misc.h:64
M0_INTERNAL int m0_fid_cmp(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:170
M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
Definition: fid.c:106
M0_INTERNAL void m0_dtm0_tx_desc_print(const struct m0_dtm0_tx_desc *txd)
Definition: tx_desc.c:170
M0_INTERNAL void m0_dtm0_tx_desc_init_none(struct m0_dtm0_tx_desc *td)
Definition: tx_desc.c:39
return M0_RC(rc)
M0_INTERNAL void m0_dtm0_tx_desc_apply(struct m0_dtm0_tx_desc *tgt, const struct m0_dtm0_tx_desc *upd)
Definition: tx_desc.c:126
struct m0_dtm0_tid dtd_id
Definition: tx_desc.h:121
#define M0_ENTRY(...)
Definition: trace.h:170
int i
Definition: dir.c:1033
static void upd(void)
Definition: client_ut.c:2974
return M0_ERR(-EOPNOTSUPP)
const char * name
Definition: trace.c:110
M0_INTERNAL bool m0_dtm0_tid__invariant(const struct m0_dtm0_tid *tid)
Definition: tx_desc.c:67
M0_INTERNAL bool m0_dtm0_tx_desc_state_exists(const struct m0_dtm0_tx_desc *txd, enum m0_dtm0_tx_pa_state state)
Definition: tx_desc.c:162
M0_DTPS_NR
Definition: tx_desc.h:171
M0_DTPS_EXECUTED
Definition: tx_desc.h:171
#define M0_POST(cond)
struct m0_fid p_fid
Definition: tx_desc.h:110
#define FID_P(f)
Definition: fid.h:77
#define m0_forall(var, nr,...)
Definition: misc.h:112
M0_INTERNAL int m0_dtm0_tx_desc_copy(const struct m0_dtm0_tx_desc *src, struct m0_dtm0_tx_desc *dst)
Definition: tx_desc.c:75
struct m0_dtm0_tx_pa * dtp_pa
Definition: tx_desc.h:117
struct m0_pdclust_tgt_addr tgt
Definition: fd.c:110
M0_INTERNAL bool m0_dtm0_tx_desc_is_none(const struct m0_dtm0_tx_desc *td)
Definition: tx_desc.c:44
#define M0_IS0(obj)
Definition: misc.h:70
M0_DTPS_PERSISTENT
Definition: tx_desc.h:171
m0_dtm0_tx_pa_state
Definition: tx_desc.h:101
struct m0_fid dti_fid
Definition: tx_desc.h:95
#define _0C(exp)
Definition: assert.h:311
M0_INTERNAL int m0_dtm0_tid_cmp(struct m0_dtm0_clk_src *cs, const struct m0_dtm0_tid *left, const struct m0_dtm0_tid *right)
Definition: tx_desc.c:118
M0_INTERNAL bool m0_dtm0_tx_desc_state_eq(const struct m0_dtm0_tx_desc *txd, enum m0_dtm0_tx_pa_state state)
Definition: tx_desc.c:154
struct m0_dtm0_tx_participants dtd_ps
Definition: tx_desc.h:122
#define DTID0_P(__tid)
Definition: tx_desc.h:99
M0_INTERNAL bool m0_dtm0_ts__invariant(const struct m0_dtm0_ts *ts)
Definition: clk_src.c:79
M0_DTPS_INIT
Definition: tx_desc.h:171
M0_INTERNAL bool m0_fid_is_valid(const struct m0_fid *fid)
Definition: fid.c:96
#define DTID0_F
Definition: tx_desc.h:98
void m0_free(void *data)
Definition: memory.c:146
M0_INTERNAL void m0_dtm0_tx_desc_fini(struct m0_dtm0_tx_desc *td)
Definition: tx_desc.c:110
struct m0_pdclust_src_addr src
Definition: fd.c:108
int32_t rc
Definition: trigger_fop.h:47
#define FID_F
Definition: fid.h:75