Motr  M0
stob.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2014-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 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_UT
24 #include "lib/trace.h"
25 
26 #include "ut/stob.h"
27 
28 #include "lib/misc.h" /* ARRAY_SIZE */
29 #include "lib/mutex.h" /* m0_mutex */
30 #include "lib/memory.h" /* M0_ALLOC_PTR */
31 #include "lib/errno.h" /* ENOMEM */
32 
33 #include "module/instance.h" /* m0_get */
34 #include "be/tx_credit.h" /* m0_be_tx_credit */
35 #include "be/ut/helper.h" /* m0_be_ut_backend_sm_group_lookup */
36 #include "dtm/dtm.h" /* m0_dtx */
37 
38 #include "stob/domain.h" /* m0_stob_domain */
39 #include "stob/stob.h" /* m0_stob_find */
40 
47 enum {
49 };
50 
53  uint64_t usm_stob_key;
55 };
56 
57 static int level_ut_stob_enter(struct m0_module *module);
58 static void level_ut_stob_leave(struct m0_module *module);
59 
61  [M0_LEVEL_UT_STOB] = {
62  .ml_name = "stob UT helper is initialised",
63  .ml_enter = level_ut_stob_enter,
64  .ml_leave = level_ut_stob_leave,
65  },
66 };
68 
69 /* linux stob domain configuratin */
70 static const char *ut_stob_domain_location = "linuxstob:./ut_stob";
71 static const uint64_t ut_stob_domain_key = 0x10000;
72 static const char *ut_stob_domain_init_cfg = "";
73 static const char *ut_stob_domain_create_cfg = "";
74 
75 static int level_ut_stob_enter(struct m0_module *module)
76 {
77  return m0_ut_stob_init();
78 }
79 
80 static void level_ut_stob_leave(struct m0_module *module)
81 {
83 }
84 
85 static struct ut_stob_module *ut_stob_module_get(void)
86 {
88  int rc;
89 
90  m0_mutex_lock(&usm->usm_lock);
91  if (usm->usm_dom_linux == NULL) {
96  &usm->usm_dom_linux);
97  if (rc != 0)
98  M0_LOG(M0_WARN, "rc = %d", rc);
99  } else {
100  rc = 0;
101  }
102  m0_mutex_unlock(&usm->usm_lock);
103  return rc == 0 ? usm : NULL;
104 }
105 
106 M0_INTERNAL int m0_ut_stob_init(void)
107 {
108  struct ut_stob_module *usm;
109  int rc;
110 
111  M0_ALLOC_PTR(usm);
112  rc = usm == NULL ? -ENOMEM : 0;
113  if (usm != NULL) {
114  m0_mutex_init(&usm->usm_lock);
116  usm->usm_dom_linux = NULL;
118  }
119  return rc;
120 }
121 M0_EXPORTED(m0_ut_stob_init);
122 
123 M0_INTERNAL void m0_ut_stob_fini(void)
124 {
126 
127  if (usm->usm_dom_linux != NULL) {
129  usm->usm_dom_linux = NULL;
130  }
131  m0_mutex_fini(&usm->usm_lock);
132  m0_free(usm);
133 }
134 M0_EXPORTED(m0_ut_stob_fini);
135 
136 static struct m0_stob *
137 ut_stob_linux_create_by_key(uint64_t stob_key, char *stob_create_cfg)
138 {
139  struct ut_stob_module *usm = ut_stob_module_get();
140  struct m0_stob *stob;
141  int rc;
142  struct m0_stob_id stob_id;
143 
144  m0_mutex_lock(&usm->usm_lock);
145 
146  m0_stob_id_make(0, stob_key, &usm->usm_dom_linux->sd_id, &stob_id);
147  rc = m0_stob_find(&stob_id, &stob);
148  M0_ASSERT(rc == 0);
150  M0_ASSERT_INFO(rc == 0, "rc = %d", rc);
152  m0_stob_create(stob, NULL, stob_create_cfg) : 0;
153  M0_ASSERT_INFO(rc == 0, "rc = %d", rc);
155 
156  m0_mutex_unlock(&usm->usm_lock);
157  return stob;
158 }
159 
160 static uint64_t ut_stob_linux_key_alloc(void)
161 {
162  struct ut_stob_module *usm = ut_stob_module_get();
163  uint64_t stob_key;
164 
165  m0_mutex_lock(&usm->usm_lock);
166  stob_key = usm->usm_stob_key++;
167  m0_mutex_unlock(&usm->usm_lock);
168  return stob_key;
169 }
170 
171 M0_INTERNAL struct m0_stob *m0_ut_stob_linux_get(void)
172 {
174 }
175 
176 M0_INTERNAL struct m0_stob *m0_ut_stob_linux_get_by_key(uint64_t stob_key)
177 {
178  return ut_stob_linux_create_by_key(stob_key, NULL);
179 }
180 
181 M0_INTERNAL struct m0_stob *m0_ut_stob_linux_create(char *stob_create_cfg)
182 {
184  stob_create_cfg);
185 }
186 
187 M0_INTERNAL void m0_ut_stob_put(struct m0_stob *stob, bool destroy)
188 {
189  struct ut_stob_module *usm = ut_stob_module_get();
190 
191  m0_mutex_lock(&usm->usm_lock);
192  m0_ut_stob_close(stob, destroy);
193  m0_mutex_unlock(&usm->usm_lock);
194 }
195 
196 static bool ut_stob_use_dtx(struct m0_stob_domain *dom)
197 {
199 
200  return !M0_IN(type_id, (m0_stob_type_id_by_name("nullstob"),
201  m0_stob_type_id_by_name("linuxstob")));
202 }
203 
204 M0_INTERNAL int m0_ut_stob_create(struct m0_stob *stob, const char *str_cfg,
205  struct m0_be_domain *be_dom)
206 {
207  struct m0_be_tx_credit cred = {};
209  struct m0_dtx *dtx = NULL;
210  bool use_dtx;
211  int rc;
212 
213  use_dtx = ut_stob_use_dtx(dom);
214  if (use_dtx) {
215  m0_stob_create_credit(dom, &cred);
216  dtx = m0_ut_dtx_open(&cred, be_dom);
217  }
218  rc = m0_stob_create(stob, dtx, str_cfg);
219  if (use_dtx)
220  m0_ut_dtx_close(dtx);
221  return rc;
222 }
223 
224 M0_INTERNAL int m0_ut_stob_destroy(struct m0_stob *stob,
225  struct m0_be_domain *be_dom)
226 {
227  struct m0_be_tx_credit cred = {};
228  struct m0_be_tx_credit accum;
229  struct m0_indexvec range;
230  struct m0_indexvec got;
231  struct m0_dtx *dtx = NULL;
232  bool use_dtx;
233  int rc;
234  int rc_c;
235 
237  rc = m0_indexvec_alloc(&range, 1);
238  M0_ASSERT(rc == 0);
239  range.iv_index[0] = 0;
240  range.iv_vec.v_count[0] = M0_BINDEX_MAX + 1;
241  if (use_dtx) {
242  rc = m0_indexvec_alloc(&got, 1);
243  M0_ASSERT(rc == 0);
244  do {
245  rc = m0_stob_punch_credit(stob, &range, &got, &cred);
246  M0_ASSERT(rc == 0);
247  range.iv_index[0] += got.iv_vec.v_count[0];
248  range.iv_vec.v_count[0] -= got.iv_vec.v_count[0];
249  rc_c = range.iv_vec.v_count[0] == 0 ? 0 : -EAGAIN;
250  dtx = m0_ut_dtx_open(&cred, be_dom);
251  rc = m0_stob_punch(stob, &got, dtx);
252  M0_ASSERT(rc == 0);
253  if (rc_c == 0) {
254  m0_stob_destroy_credit(stob, &accum);
255  m0_be_tx_credit_add(&cred, &accum);
256  rc = m0_stob_destroy(stob, dtx);
257  M0_ASSERT(rc == 0);
258  }
259  m0_ut_dtx_close(dtx);
260  } while (rc_c == -EAGAIN);
261  }
262  else {
263  /*
264  * m0_stob_punch() here is temporarily disabled.
265  * This is a quick fix that allows c/motr/+/18984 to land.
266  * On a jenkins node it returns -EFBIG for some reason.
267  */
268  /* rc = m0_stob_punch(stob, &range, dtx); */
269  /* M0_ASSERT(rc == 0); */
270  rc = m0_stob_destroy(stob, dtx);
271  M0_ASSERT(rc == 0);
272  }
273  return rc;
274 }
275 
276 M0_INTERNAL struct m0_stob *m0_ut_stob_open(struct m0_stob_domain *dom,
277  uint64_t stob_key,
278  const char *str_cfg)
279 {
280  struct m0_stob *stob;
281  int rc;
282  struct m0_stob_id stob_id;
283 
284  m0_stob_id_make(0, stob_key, &dom->sd_id, &stob_id);
285  rc = m0_stob_find(&stob_id, &stob);
286  M0_ASSERT(rc == 0);
288  M0_ASSERT_INFO(rc == 0, "rc = %d", rc);
290  m0_ut_stob_create(stob, str_cfg, NULL);
291  return stob;
292 }
293 
294 M0_INTERNAL void m0_ut_stob_close(struct m0_stob *stob, bool destroy)
295 {
296  if (destroy) {
298  } else {
299  m0_stob_put(stob);
300  }
301 }
302 
303 M0_INTERNAL int m0_ut_stob_create_by_stob_id(struct m0_stob_id *stob_id,
304  const char *str_cfg)
305 {
306  struct m0_stob *stob;
307  int rc;
308 
309  rc = m0_stob_find(stob_id, &stob);
310  if (rc == 0) {
312  m0_stob_locate(stob) : 0;
313  rc = rc ?: m0_ut_stob_create(stob, str_cfg, NULL);
314  m0_stob_put(stob);
315  }
316  return rc;
317 }
318 
319 M0_INTERNAL int m0_ut_stob_destroy_by_stob_id(struct m0_stob_id *stob_id)
320 {
321  struct m0_stob *stob;
322  int rc;
323 
324  rc = m0_stob_find(stob_id, &stob);
325  if (rc == 0) {
327  m0_stob_locate(stob) : 0;
329  if (rc != 0)
330  m0_stob_put(stob);
331  }
332  return rc;
333 }
334 
335 M0_INTERNAL struct m0_dtx *m0_ut_dtx_open(struct m0_be_tx_credit *cred,
336  struct m0_be_domain *be_dom)
337 {
338 #ifndef __KERNEL__
339  struct m0_sm_group *grp;
340  struct m0_dtx *dtx = NULL;
341  int rc;
342 
343  if (be_dom != NULL) {
344  struct m0_be_ut_backend *ut_be =
345  bob_of(be_dom, struct m0_be_ut_backend, but_dom,
347  M0_ALLOC_PTR(dtx);
348  M0_ASSERT(dtx != NULL);
350  m0_dtx_init(dtx, be_dom, grp);
351  m0_dtx_prep(dtx, cred);
352  rc = m0_dtx_open_sync(dtx);
353  M0_ASSERT_INFO(rc == 0, "rc = %d", rc);
354  }
355  return dtx;
356 #else
357  return NULL;
358 #endif
359 }
360 
361 M0_INTERNAL void m0_ut_dtx_close(struct m0_dtx *dtx)
362 {
363  int rc;
364 
365  if (dtx != NULL) {
366  rc = m0_dtx_done_sync(dtx);
367  M0_ASSERT_INFO(rc == 0, "rc = %d", rc);
368  m0_dtx_fini(dtx);
369  m0_free(dtx);
370  }
371 }
372 
375 #undef M0_TRACE_SUBSYSTEM
376 
377 /*
378  * Local variables:
379  * c-indentation-style: "K&R"
380  * c-basic-offset: 8
381  * tab-width: 8
382  * fill-column: 80
383  * scroll-step: 1
384  * End:
385  */
386 /*
387  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
388  */
M0_INTERNAL struct m0_stob_domain * m0_stob_dom_get(struct m0_stob *stob)
Definition: stob.c:338
uint64_t usm_stob_key
Definition: stob.c:53
Definition: dtm.h:554
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
M0_INTERNAL struct m0_stob * m0_ut_stob_open(struct m0_stob_domain *dom, uint64_t stob_key, const char *str_cfg)
Definition: stob.c:276
M0_INTERNAL int m0_indexvec_alloc(struct m0_indexvec *ivec, uint32_t len)
Definition: vec.c:532
#define NULL
Definition: misc.h:38
static uint64_t ut_stob_linux_key_alloc(void)
Definition: stob.c:160
M0_INTERNAL int m0_stob_locate(struct m0_stob *stob)
Definition: stob.c:128
M0_INTERNAL void m0_ut_stob_close(struct m0_stob *stob, bool destroy)
Definition: stob.c:294
static struct m0_sm_group * grp
Definition: bytecount.c:38
struct ut_stob_module * usm_private
Definition: stob.h:50
#define M0_LOG(level,...)
Definition: trace.h:167
struct m0_ut_stob_module i_ut_stob_module
Definition: instance.h:121
M0_INTERNAL const struct m0_fid * m0_stob_domain_id_get(const struct m0_stob_domain *dom)
Definition: domain.c:300
M0_INTERNAL int m0_ut_stob_destroy_by_stob_id(struct m0_stob_id *stob_id)
Definition: stob.c:319
M0_INTERNAL int m0_ut_stob_destroy(struct m0_stob *stob, struct m0_be_domain *be_dom)
Definition: stob.c:224
M0_INTERNAL void m0_dtx_init(struct m0_dtx *tx, struct m0_be_domain *be_domain, struct m0_sm_group *sm_group)
Definition: dtm.c:67
static struct m0_stob * ut_stob_linux_create_by_key(uint64_t stob_key, char *stob_create_cfg)
Definition: stob.c:137
const char * ml_name
Definition: module.h:114
M0_INTERNAL struct m0 * m0_get(void)
Definition: instance.c:41
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
M0_INTERNAL int m0_dtx_done_sync(struct m0_dtx *tx)
Definition: dtm.c:122
static void level_ut_stob_leave(struct m0_module *module)
Definition: stob.c:80
struct m0_vec iv_vec
Definition: vec.h:139
M0_INTERNAL struct m0_stob * m0_ut_stob_linux_get_by_key(uint64_t stob_key)
Definition: stob.c:176
m0_bindex_t * iv_index
Definition: vec.h:141
static const char * ut_stob_domain_create_cfg
Definition: stob.c:73
M0_INTERNAL struct m0_stob * m0_ut_stob_linux_get(void)
Definition: stob.c:171
static bool ut_stob_use_dtx(struct m0_stob_domain *dom)
Definition: stob.c:196
struct m0_be_ut_backend ut_be
Definition: ad.c:72
Definition: stob.h:163
static struct m0_stob * stob
Definition: storage.c:39
#define M0_ASSERT(cond)
struct m0_mutex usm_lock
Definition: stob.c:52
M0_INTERNAL void m0_stob_destroy_credit(struct m0_stob *stob, struct m0_be_tx_credit *accum)
Definition: stob.c:187
M0_INTERNAL void m0_be_tx_credit_add(struct m0_be_tx_credit *c0, const struct m0_be_tx_credit *c1)
Definition: tx_credit.c:44
#define bob_of(ptr, type, field, bt)
Definition: bob.h:140
static struct m0_stob_domain * dom
Definition: storage.c:38
M0_INTERNAL void m0_stob_id_make(uint64_t container, uint64_t key, const struct m0_fid *dom_id, struct m0_stob_id *stob_id)
Definition: stob.c:343
static const uint64_t ut_stob_domain_key
Definition: stob.c:71
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
M0_INTERNAL uint8_t m0_stob_type_id_by_name(const char *name)
Definition: type.c:139
M0_INTERNAL void m0_dtx_fini(struct m0_dtx *tx)
Definition: dtm.c:134
struct m0_sm_group * m0_be_ut_backend_sm_group_lookup(struct m0_be_ut_backend *ut_be)
Definition: stubs.c:277
m0_bcount_t * v_count
Definition: vec.h:53
struct m0_be_domain but_dom
Definition: helper.h:47
M0_INTERNAL void m0_ut_stob_put(struct m0_stob *stob, bool destroy)
Definition: stob.c:187
const unsigned m0_levels_ut_stob_nr
Definition: stob.c:67
M0_INTERNAL int m0_ut_stob_create_by_stob_id(struct m0_stob_id *stob_id, const char *str_cfg)
Definition: stob.c:303
M0_INTERNAL void m0_stob_domain_fini(struct m0_stob_domain *dom)
Definition: domain.c:204
M0_INTERNAL int m0_stob_create(struct m0_stob *stob, struct m0_dtx *dtx, const char *str_cfg)
Definition: stob.c:154
M0_INTERNAL void m0_ut_stob_fini(void)
Definition: stob.c:123
M0_INTERNAL int m0_stob_punch_credit(struct m0_stob *stob, struct m0_indexvec *want, struct m0_indexvec *got, struct m0_be_tx_credit *accum)
Definition: stob.c:223
struct m0_fid sd_id
Definition: domain.h:96
M0_INTERNAL int m0_stob_destroy(struct m0_stob *stob, struct m0_dtx *dtx)
Definition: stob.c:200
M0_INTERNAL enum m0_stob_state m0_stob_state_get(struct m0_stob *stob)
Definition: stob.c:265
Definition: stob.h:91
M0_INTERNAL int m0_stob_domain_create_or_init(const char *location, const char *str_cfg_init, uint64_t dom_key, const char *str_cfg_create, struct m0_stob_domain **out)
Definition: domain.c:262
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
const struct m0_bob_type m0_ut_be_backend_bobtype
Definition: helper.c:49
static struct ut_stob_module * ut_stob_module_get(void)
Definition: stob.c:85
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
struct m0_stob_domain * usm_dom_linux
Definition: stob.c:54
static const char * ut_stob_domain_init_cfg
Definition: stob.c:72
M0_INTERNAL int m0_stob_find(const struct m0_stob_id *id, struct m0_stob **out)
Definition: stob.c:92
M0_INTERNAL int m0_dtx_open_sync(struct m0_dtx *tx)
Definition: dtm.c:101
M0_INTERNAL void m0_ut_dtx_close(struct m0_dtx *dtx)
Definition: stob.c:361
#define M0_ASSERT_INFO(cond, fmt,...)
M0_INTERNAL struct m0_dtx * m0_ut_dtx_open(struct m0_be_tx_credit *cred, struct m0_be_domain *be_dom)
Definition: stob.c:335
M0_INTERNAL int m0_ut_stob_create(struct m0_stob *stob, const char *str_cfg, struct m0_be_domain *be_dom)
Definition: stob.c:204
M0_INTERNAL int m0_stob_punch(struct m0_stob *stob, struct m0_indexvec *range, struct m0_dtx *dtx)
Definition: stob.c:232
M0_INTERNAL void m0_stob_create_credit(struct m0_stob_domain *dom, struct m0_be_tx_credit *accum)
Definition: stob.c:148
void m0_free(void *data)
Definition: memory.c:146
Definition: mutex.h:47
static const char * ut_stob_domain_location
Definition: stob.c:70
M0_INTERNAL int m0_ut_stob_init(void)
Definition: stob.c:106
M0_INTERNAL uint8_t m0_stob_domain__type_id(const struct m0_fid *dom_id)
Definition: domain.c:317
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
M0_INTERNAL void m0_stob_put(struct m0_stob *stob)
Definition: stob.c:291
Definition: trace.h:478
struct m0_modlev m0_levels_ut_stob[]
Definition: stob.c:60
M0_INTERNAL void m0_dtx_prep(struct m0_dtx *tx, const struct m0_be_tx_credit *cred)
Definition: dtm.c:80
static int level_ut_stob_enter(struct m0_module *module)
Definition: stob.c:75
M0_INTERNAL struct m0_stob * m0_ut_stob_linux_create(char *stob_create_cfg)
Definition: stob.c:181