Motr  M0
storage.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2015-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 
63 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_ADDB
64 
65 #include "lib/misc.h" /* ARRAY_SIZE, M0_FIELD_VALUE, M0_BITS */
66 #include "lib/vec.h"
67 #include "lib/chan.h"
68 #include "lib/trace.h"
69 #include "lib/assert.h"
70 #include "lib/memory.h"
71 #include "lib/errno.h" /* -ENOMEM */
72 #include "lib/tlist.h"
73 #include "lib/mutex.h"
74 #include "lib/memory.h"
75 #include "xcode/xcode.h"
76 #include "stob/stob.h"
77 #include "stob/domain.h"
78 #include "stob/io.h"
79 #include "addb2/addb2.h"
80 #include "addb2/storage.h"
81 #include "addb2/internal.h"
82 #include "addb2/addb2_xc.h"
83 #include "addb2/storage_xc.h"
84 
85 enum {
97  IO_FRAG = 2
98 };
99 
103 struct frame {
120  struct m0_stob_io f_io;
125  void *f_area;
140  void *f_buf[IO_FRAG];
145  uint64_t f_magix;
146 };
147 
160  struct m0_stob *as_stob;
168  unsigned as_bshift;
180  uint64_t as_seqno;
189  struct m0_tl as_queue;
195  struct m0_tl as_idle;
215  void *as_cookie;
220  bool as_idled;
221 };
222 
227 M0_TL_DESCR_DEFINE(frame, "addb2 frames",
228  static, struct frame, f_linkage, f_magix,
230 M0_TL_DEFINE(frame, static, struct frame);
231 
232 static bool trace_tryadd(struct m0_addb2_storage *stor,
233  struct m0_addb2_trace *trace);
234 static bool trace_fits (const struct frame *frame,
235  const struct m0_addb2_trace *trace);
236 static void trace_add (struct frame *frame,
237  struct m0_addb2_trace *trace);
238 
239 static int frame_init (struct frame *frame, struct m0_addb2_storage *stor);
240 static void frame_fini (struct frame *frame);
241 static void frame_clear (struct frame *frame);
242 static void frame_submit (struct frame *frame);
243 static void frame_idle (struct frame *frame);
244 static void frame_done (struct frame *frame);
245 static int frame_try (struct frame *frame);
246 static void frame_io_pack (struct frame *frame);
247 static void frame_io_open (struct frame *frame);
248 static bool frame_invariant(const struct frame *frame);
249 static bool frame_endio (struct m0_clink *link);
250 
251 static struct frame *frame_cur (const struct m0_addb2_storage *stor);
252 
253 static bool stor_invariant(const struct m0_addb2_storage *stor);
254 static void stor_fini (struct m0_addb2_storage *stor);
255 static void stor_balance (struct m0_addb2_storage *stor, int delta);
256 static void stor_drain (struct m0_addb2_storage *stor);
257 static void stor_update (struct m0_addb2_storage *stor,
258  const struct m0_addb2_frame_header *header);
259 static m0_bindex_t stor_round (const struct m0_addb2_storage *stor,
261 static bool stor_rounded (const struct m0_addb2_storage *stor,
263 
264 static const struct m0_format_tag frame_tag;
265 
266 enum {
268 };
269 
270 M0_INTERNAL const uint64_t m0_addb2_stob_key = M0_ADDB2_STOB_KEY;
271 
272 static int stor_dom_init(struct m0_addb2_storage *stor, const char *location,
273  uint64_t key, bool mkfs, bool force)
274 {
275  struct m0_stob_domain *dom;
276  const char *str_cfg_init;
277  int rc;
278  int rc1 = 0;
279 
280  M0_ENTRY();
281 
282  str_cfg_init = "directio=true";
283  stor->as_stob_dom = NULL;
284  rc = m0_stob_domain_init(location, str_cfg_init, &dom);
285  if (mkfs) {
286  /* Found existing stob domain, kill it. */
287  if ((rc == 0 && force) || !M0_IN(rc, (0, -ENOENT))) {
288  rc1 = rc == 0 ?
291  if (rc1 != 0)
292  goto out;
293  }
294  if (rc != 0 || force)
295  rc = m0_stob_domain_create(location, str_cfg_init, key,
296  NULL, &dom);
297  }
298  if (rc != 0)
299  return M0_ERR(rc);
300 out:
301  if (rc != 0)
303  rc = (rc1 == 0 ? rc : rc1);
304  if (rc == 0)
305  stor->as_stob_dom = dom;
306  return M0_RC(rc);
307 }
308 
309 static void stor_dom_fini(struct m0_addb2_storage *stor)
310 {
312 }
313 
314 static int stor_stob_init(struct m0_addb2_storage *stor, uint64_t key)
315 {
316  struct m0_stob_domain *dom = stor->as_stob_dom;
317  struct m0_stob *stob;
318  int rc;
319  struct m0_stob_id stob_id;
320 
321  M0_PRE(dom != NULL);
322  stor->as_stob = NULL;
323 
324  m0_stob_id_make(0, key, &dom->sd_id, &stob_id);
325  rc = m0_stob_find(&stob_id, &stob);
326  if (rc == 0) {
328  if (rc == 0 && m0_stob_state_get(stob) != CSS_EXISTS)
330  if (rc == 0)
331  stor->as_stob = stob;
332  else
333  m0_stob_put(stob);
334  }
335  return M0_RC(rc);
336 }
337 
339 {
341 }
342 
343 M0_INTERNAL struct m0_addb2_storage *
344 m0_addb2_storage_init(const char *location, uint64_t key, bool mkfs, bool force,
345  const struct m0_addb2_storage_ops *ops, m0_bcount_t size,
346  void *cookie)
347 {
348  struct m0_addb2_storage *stor;
349  int rc;
350  struct m0_addb2_frame_header h;
351  int i;
352 
353 
355  M0_CASSERT(sizeof(struct m0_addb2_frame_header) <= BSIZE);
356 
358  if (stor == NULL)
359  return NULL;
360  rc = stor_dom_init(stor, location, key, mkfs, force);
361  if (rc != 0)
362  goto cleanup_stor;
364  if (rc != 0)
365  goto cleanup_stob_domain;
366  if (mkfs) {
367  h = (struct m0_addb2_frame_header) {
368  .he_seqno= 0,
369  .he_offset = 0,
370  .he_size = BSIZE
371  };
372  } else if (m0_addb2_storage_header(stor->as_stob, &h) == 0 &&
373  size != h.he_stob_size)
374  goto cleanup_stob;
375 
377  stor->as_ops = ops;
378  stor->as_size = size;
380  /*
381  * For disk format compatibility, make block size a constant
382  * independent of stob block size. Use 64KB.
383  */
385  stor->as_cookie = cookie;
387  /*
388  * Initialized "h" lets stor_update() below set up the first
389  * frame.
390  */
391  stor_update(stor, &h);
392  tr_tlist_init(&stor->as_queue);
393  frame_tlist_init(&stor->as_inflight);
394  frame_tlist_init(&stor->as_idle);
395  frame_tlist_init(&stor->as_pending);
396 
397  for (i = 0; i < ARRAY_SIZE(stor->as_prealloc); ++i) {
399  if (rc != 0) {
400  stor_fini(stor);
401  return NULL;
402  }
403  }
404  stor->as_marker = (struct m0_addb2_trace_obj) {
405  .o_tr = {
407  .tr_body = m0_addb2__dummy_payload
408  }
409  };
411 
413  return stor;
414 
415 cleanup_stob:
417 cleanup_stob_domain:
419 cleanup_stor:
420  m0_free(stor);
421  return NULL;
422 }
423 
424 M0_INTERNAL void m0_addb2_storage_fini(struct m0_addb2_storage *stor)
425 {
429  stor_fini(stor);
430 }
431 
432 M0_INTERNAL void *m0_addb2_storage_cookie(const struct m0_addb2_storage *stor)
433 {
434  return stor->as_cookie;
435 }
436 
437 M0_INTERNAL void m0_addb2_storage_stop(struct m0_addb2_storage *stor)
438 {
442  stor->as_stopped = true;
443  stor_balance(stor, 0);
446 }
447 
448 M0_INTERNAL int m0_addb2_storage_submit(struct m0_addb2_storage *stor,
449  struct m0_addb2_trace_obj *obj)
450 {
454  tr_tlink_init_at_tail(obj, &stor->as_queue);
455  stor_balance(stor, 0);
458  return +1;
459 }
460 
461 M0_INTERNAL bool
463 {
465 }
466 
467 static void stor_fini(struct m0_addb2_storage *stor)
468 {
469  struct frame *frame;
470 
471  /*
472  * This lock-unlock is a barrier against concurrently finishing last
473  * frame_endio(), which signalled ->sto_idle().
474  *
475  * It *is* valid to acquire and finalise a lock in the same function in
476  * this particular case.
477  */
480 
482  frame_fini(frame);
483  }
484  frame_tlist_fini(&stor->as_idle);
485  frame_tlist_fini(&stor->as_inflight);
486  frame_tlist_fini(&stor->as_pending);
487  tr_tlist_fini(&stor->as_queue);
491  m0_free(stor);
492 }
493 
499 static void stor_balance(struct m0_addb2_storage *stor, int delta)
500 {
501  struct m0_addb2_trace_obj *obj = tr_tlist_head(&stor->as_queue);
502  bool force = false;
503 
504  while (obj != NULL && trace_tryadd(stor, &obj->o_tr)) {
505  tr_tlist_del(obj);
506  force |= obj->o_force;
507  obj = tr_tlist_head(&stor->as_queue);
508  }
509  if (obj == NULL && (stor->as_stopped || force)) {
510  struct frame *frame = frame_cur(stor);
511 
512  if (frame != NULL && frame->f_header.he_trace_nr > 0)
514  stor_drain(stor);
515  /*
516  * "delta" accounts for the frame for which IO completion is
517  * executed. This frame cannot be moved to the idle list before
518  * calling stor_balance(), because then there will be a
519  * situation when inflight and pending lists are empty, storage
520  * lock is released (in frame_endio()->...->frame_try()) and
521  * frame_endio() is still running---racing with stor_fini().
522  */
523  if (frame_tlist_length(&stor->as_inflight) == delta &&
524  stor->as_stopped && !stor->as_idled &&
525  stor->as_ops->sto_idle != NULL) {
526  stor->as_idled = true;
528  }
529  }
530  stor_drain(stor);
531 }
532 
537 static bool trace_tryadd(struct m0_addb2_storage *stor,
538  struct m0_addb2_trace *trace)
539 {
540  struct frame *fr = frame_cur(stor);
541 
542  if (fr != NULL) {
543  if (!trace_fits(fr, trace)) {
544  frame_submit(fr);
545  fr = frame_cur(stor);
546  if (fr == NULL)
547  return false;
548  }
549  trace_add(fr, trace);
550  return true;
551  } else
552  return false;
553 }
554 
558 static bool trace_fits(const struct frame *frame,
559  const struct m0_addb2_trace *trace)
560 {
564 }
565 
569 static void trace_add(struct frame *frame, struct m0_addb2_trace *trace)
570 {
571  M0_PRE(trace_fits(frame, trace));
572 
573  frame->f_trace[frame->f_header.he_trace_nr ++] = trace;
575 }
576 
580 static int frame_init(struct frame *frame, struct m0_addb2_storage *stor)
581 {
582  int result;
583 
584  frame->f_stor = stor;
585  /*
586  * Allocate a buffer to contain both the storage header and the frame.
587  */
589  if (frame->f_area != NULL) {
590  struct m0_stob_io *io = &frame->f_io;
591 
594  frame->f_count[0] = BSIZE;
595  frame->f_index[0] = 0;
596  frame->f_buf[0] = frame->f_area;
597  frame->f_buf[1] = frame->f_area + BSIZE;
599  io->si_user = (struct m0_bufvec) {
600  .ov_vec = {
602  .v_count = frame->f_count
603  },
604  .ov_buf = frame->f_buf
605  };
606  io->si_stob = (struct m0_indexvec) {
607  .iv_vec = {
609  .v_count = frame->f_count
610  },
611  .iv_index = frame->f_index
612  };
615  frame_tlink_init_at_tail(frame, &stor->as_idle);
616  result = 0;
617  } else
618  result = M0_ERR(-ENOMEM);
619  return M0_RC(result);
620 }
621 
622 static void frame_fini(struct frame *frame)
623 {
624  if (frame->f_area != NULL) {
625  frame_tlist_remove(frame);
626  frame_tlink_fini(frame);
631  }
632 }
633 
637 static void frame_submit(struct frame *frame)
638 {
639  struct m0_addb2_frame_header *h = &frame->f_header;
640  struct m0_addb2_storage *stor = frame->f_stor;
641 
642  frame_tlist_move_tail(&stor->as_pending, frame);
643  h->he_size = stor_round(stor, h->he_size);
644  h->he_seqno = stor->as_seqno;
645  h->he_offset = stor->as_pos;
647  stor_update(stor, h);
648 }
649 
653 static void stor_drain(struct m0_addb2_storage *stor)
654 {
655  struct frame *frame;
656 
657  /* Cannot used m0_tl_for() because of concurrent frame insertions. */
658  while ((frame = frame_tlist_head(&stor->as_pending)) != NULL) {
659  if (frame_try(frame) != 0) {
660  frame_done(frame);
661  /* Not much else we can do here. */
662  frame_idle(frame);
663  }
664  }
665 }
666 
671 static void stor_update(struct m0_addb2_storage *stor,
672  const struct m0_addb2_frame_header *header)
673 {
674  stor->as_seqno = header->he_seqno + 1;
675  stor->as_prev_offset = header->he_offset;
676  stor->as_pos = header->he_offset + header->he_size;
678  stor->as_pos = BSIZE; /* wrap around */
679 }
680 
689 static int frame_try(struct frame *frame)
690 {
691 
692 #define PLACE(cur, obj, count) \
693 do { \
694  M0_PRE(M0_IS_8ALIGNED(cur)); \
695  size_t __nob = (count) * sizeof *(obj); \
696  memcpy((cur), (obj), __nob); \
697  (cur) += __nob; \
698  M0_POST(M0_IS_8ALIGNED(cur)); \
699 } while (0)
700 
701  struct m0_addb2_frame_header *h = &frame->f_header;
702  struct m0_addb2_storage *stor = frame->f_stor;
703  void *cur;
704  int result;
705  int i;
706 
707  M0_PRE(!frame_tlist_contains(&stor->as_inflight, frame));
708  M0_PRE( frame_tlist_contains(&stor->as_pending, frame));
710 
711  frame_tlist_move(&stor->as_inflight, frame);
714  h->he_time = m0_time_now();
716  frame->f_count[1] = h->he_size;
717  frame->f_index[1] = h->he_offset;
718  cur = frame->f_buf[0];
719  PLACE(cur, h, 1);
720  cur = frame->f_buf[1];
721  PLACE(cur, h, 1);
722  for (i = 0; i < h->he_trace_nr; ++i) {
723  struct m0_addb2_trace *tr = frame->f_trace[i];
724 
725  PLACE(cur, &tr->tr_nr, 1);
726  PLACE(cur, tr->tr_body, tr->tr_nr);
727  }
729  frame->f_io.si_obj = NULL;
731  NULL, NULL);
732  if (result != 0) {
734  M0_LOG(M0_ERROR, "Failed to launch: %i.", M0_ERR(result));
735  }
737  return M0_RC(result);
738 #undef PLACE
739 }
740 
742 static struct frame *frame_cur(const struct m0_addb2_storage *stor)
743 {
744  return frame_tlist_head(&stor->as_idle);
745 }
746 
753 static void frame_idle(struct frame *frame)
754 {
756  frame_tlist_move_tail(&frame->f_stor->as_idle, frame);
757 }
758 
762 static void frame_clear(struct frame *frame)
763 {
764  struct m0_addb2_frame_header *h = &frame->f_header;
765 
766  M0_SET0(&frame->f_trace);
767  *h = (typeof (*h)) {
768  .he_size = sizeof *h,
770  .he_fid = *m0_stob_fid_get(frame->f_stor->as_stob),
771  .he_magix = M0_ADDB2_FRAME_HEADER_MAGIX
772  };
773 }
774 
781 static bool frame_endio(struct m0_clink *link)
782 {
783  struct frame *frame = container_of(link, struct frame, f_clink);
784  struct m0_addb2_storage *stor = frame->f_stor;
785 
786  /* Call back outside of the mutex to avoid deadlock. */
787  if (stor->as_ops->sto_commit != NULL)
789  frame_done(frame);
792  stor_balance(stor, 1);
794  frame_idle(frame);
797  return true;
798 }
799 
803 static void frame_io_pack(struct frame *frame)
804 {
805  unsigned shift = frame->f_stor->as_bshift;
806  int i;
807 
808  for (i = 0; i < IO_FRAG; ++i) {
809  frame->f_buf[i] = m0_stob_addr_pack(frame->f_buf[i], shift);
810  frame->f_count[i] >>= shift;
811  frame->f_index[i] >>= shift;
812  }
813 }
814 
818 static void frame_io_open(struct frame *frame)
819 {
820  unsigned shift = frame->f_stor->as_bshift;
821  int i;
822 
823  for (i = 0; i < IO_FRAG; ++i) {
824  frame->f_buf[i] = m0_stob_addr_open(frame->f_buf[i], shift);
825  frame->f_count[i] <<= shift;
826  frame->f_index[i] <<= shift;
827  }
828 }
829 
833 static void frame_done(struct frame *frame)
834 {
835  struct m0_addb2_storage *stor = frame->f_stor;
836  int i;
837 
838  for (i = 0; i < frame->f_header.he_trace_nr; ++i) {
839  struct m0_addb2_trace *trace = frame->f_trace[i];
840  struct m0_addb2_trace_obj *obj;
841 
842  obj = M0_AMB(obj, frame->f_trace[i], o_tr);
843  if (stor->as_ops->sto_done != NULL)
845  if (obj->o_done != NULL)
846  obj->o_done(obj);
847  else
848  m0_addb2_trace_done(trace);
849  }
850 }
851 
854 {
855  return m0_round_up(index, BSIZE);
856 }
857 
859 {
860  return stor_round(stor, index) == index;
861 }
862 
863 static bool frame_invariant(const struct frame *frame)
864 {
865  const struct m0_addb2_frame_header *h = &frame->f_header;
866  const struct m0_addb2_storage *stor = frame->f_stor;
867 
868  return _0C(frame_tlink_is_in(frame)) &&
869  _0C(frame_tlist_contains(&stor->as_idle, frame) ||
870  frame_tlist_contains(&stor->as_pending, frame) ||
871  frame_tlist_contains(&stor->as_inflight, frame)) &&
872  _0C(ergo(frame_tlist_contains(&stor->as_inflight, frame) ||
873  frame_tlist_contains(&stor->as_pending, frame),
874  h->he_size > 0 && h->he_trace_nr > 0 &&
875  stor_rounded(stor, h->he_offset) &&
876  stor_rounded(stor, h->he_size))) &&
877  _0C(ergo(frame_tlist_contains(&stor->as_idle, frame) &&
878  h->he_trace_nr > 0, frame == frame_cur(stor))) &&
881  _0C(h->he_size <= FRAME_SIZE_MAX);
882 }
883 
884 static bool stor_invariant(const struct m0_addb2_storage *stor)
885 {
886  return _0C(frame_tlist_length(&stor->as_idle) +
887  frame_tlist_length(&stor->as_pending) +
888  frame_tlist_length(&stor->as_inflight) ==
890  _0C(stor_rounded(stor, BSIZE)) &&
894 }
895 
896 static const struct m0_format_tag frame_tag = {
899  .ot_footer_offset = offsetof(struct m0_addb2_frame_header, he_footer)
900 };
901 
902 #undef M0_TRACE_SUBSYSTEM
903 
906 /*
907  * Local variables:
908  * c-indentation-style: "K&R"
909  * c-basic-offset: 8
910  * tab-width: 8
911  * fill-column: 80
912  * scroll-step: 1
913  * End:
914  */
915 /*
916  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
917  */
static struct frame * frame_cur(const struct m0_addb2_storage *stor)
Definition: storage.c:742
m0_bindex_t f_index[IO_FRAG]
Definition: storage.c:136
static struct m0_addb2_storage * stor
Definition: storage.c:41
struct m0_stob_domain * as_stob_dom
Definition: storage.c:152
M0_TL_DEFINE(frame, static, struct frame)
#define M0_PRE(cond)
static void frame_io_pack(struct frame *frame)
Definition: storage.c:803
static bool stor_rounded(const struct m0_addb2_storage *stor, m0_bindex_t index)
Definition: storage.c:858
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
uint64_t he_prev_offset
Definition: storage.h:135
M0_INTERNAL void m0_stob_io_fini(struct m0_stob_io *io)
Definition: io.c:122
M0_INTERNAL void m0_format_header_pack(struct m0_format_header *dest, const struct m0_format_tag *src)
Definition: format.c:40
const struct m0_addb2_storage_ops * as_ops
Definition: storage.c:209
static void stor_stob_fini(struct m0_addb2_storage *stor)
Definition: storage.c:338
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_clink_init(struct m0_clink *link, m0_chan_cb_t cb)
Definition: chan.c:201
m0_bindex_t as_prev_offset
Definition: storage.c:184
Definition: io.h:230
M0_INTERNAL int m0_stob_locate(struct m0_stob *stob)
Definition: stob.c:128
M0_INTERNAL void m0_clink_del_lock(struct m0_clink *link)
Definition: chan.c:293
static struct buffer * cur(struct m0_addb2_mach *mach, m0_bcount_t space)
Definition: addb2.c:791
#define ergo(a, b)
Definition: misc.h:293
Definition: storage.c:103
uint64_t he_stob_size
Definition: storage.h:139
#define M0_LOG(level,...)
Definition: trace.h:167
M0_INTERNAL bool m0_mutex_is_not_locked(const struct m0_mutex *mutex)
Definition: mutex.c:101
M0_INTERNAL int m0_stob_domain_destroy(struct m0_stob_domain *dom)
Definition: domain.c:227
#define M0_CASSERT(cond)
void(* sto_idle)(struct m0_addb2_storage *stor)
Definition: storage.h:74
struct m0_format_header he_header
Definition: storage.h:132
Definition: internal.h:78
struct m0_vec ov_vec
Definition: vec.h:147
uint64_t f_magix
Definition: storage.c:145
struct m0_mutex as_lock
Definition: storage.c:164
struct m0_tl as_idle
Definition: storage.c:195
M0_INTERNAL void * m0_addb2_storage_cookie(const struct m0_addb2_storage *stor)
Definition: kaddb2.c:57
void * as_cookie
Definition: storage.c:215
M0_INTERNAL void m0_addb2_storage_stop(struct m0_addb2_storage *stor)
Definition: kaddb2.c:66
M0_INTERNAL void m0_free_aligned(void *data, size_t size, unsigned shift)
Definition: memory.c:192
uint64_t m0_bindex_t
Definition: types.h:80
static bool frame_invariant(const struct frame *frame)
Definition: storage.c:863
struct m0_chan si_wait
Definition: io.h:318
uint64_t m0_bcount_t
Definition: types.h:77
M0_INTERNAL const struct m0_fid * m0_stob_fid_get(struct m0_stob *stob)
Definition: stob.c:255
#define container_of(ptr, type, member)
Definition: misc.h:33
#define M0_SET0(obj)
Definition: misc.h:64
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
M0_INTERNAL const uint64_t m0_addb2_stob_key
Definition: storage.c:270
struct m0_clink f_clink
Definition: storage.c:144
M0_INTERNAL uint64_t m0_addb2__dummy_payload[1]
Definition: addb2.c:1096
M0_INTERNAL bool m0_addb2_storage__is_not_locked(const struct m0_addb2_storage *stor)
Definition: kaddb2.c:70
static int stor_stob_init(struct m0_addb2_storage *stor, uint64_t key)
Definition: storage.c:314
static bool trace_fits(const struct frame *frame, const struct m0_addb2_trace *trace)
Definition: storage.c:558
struct frame as_prealloc[MAX_INFLIGHT+1]
Definition: storage.c:208
static struct foo * obj
Definition: tlist.c:302
const char * location
Definition: storage.c:50
M0_INTERNAL uint64_t m0_round_up(uint64_t val, uint64_t size)
Definition: misc.c:181
static void stor_drain(struct m0_addb2_storage *stor)
Definition: storage.c:653
struct m0_addb2_trace o_tr
Definition: addb2.h:451
struct m0_vec iv_vec
Definition: vec.h:139
return M0_RC(rc)
M0_INTERNAL uint32_t m0_stob_block_shift(struct m0_stob *stob)
Definition: stob.c:270
struct m0_stob_io f_io
Definition: storage.c:120
struct m0_bufvec si_user
Definition: io.h:300
#define M0_ENTRY(...)
Definition: trace.h:170
static void stor_dom_fini(struct m0_addb2_storage *stor)
Definition: storage.c:309
M0_TL_DESCR_DEFINE(frame, "addb2 frames", static, struct frame, f_linkage, f_magix, M0_ADDB2_FRAME_MAGIC, M0_ADDB2_FRAME_HEAD_MAGIC)
int i
Definition: dir.c:1033
uint16_t ot_version
Definition: format.h:63
M0_INTERNAL int m0_stob_domain_create(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:217
#define PLACE(cur, obj, count)
void m0_addb2_trace_done(const struct m0_addb2_trace *ctrace)
Definition: addb2.c:650
M0_INTERNAL void m0_addb2_storage_fini(struct m0_addb2_storage *stor)
Definition: kaddb2.c:63
return M0_ERR(-EOPNOTSUPP)
#define M0_AMB(obj, ptr, field)
Definition: misc.h:320
#define m0_tl_teardown(name, head, obj)
Definition: tlist.h:708
static int frame_init(struct frame *frame, struct m0_addb2_storage *stor)
Definition: storage.c:580
M0_INTERNAL int m0_stob_io_prepare_and_launch(struct m0_stob_io *io, struct m0_stob *obj, struct m0_dtx *tx, struct m0_io_scope *scope)
Definition: io.c:219
Definition: stob.h:163
static void frame_done(struct frame *frame)
Definition: storage.c:833
static void frame_idle(struct frame *frame)
Definition: storage.c:753
struct m0_indexvec si_stob
Definition: io.h:311
static struct m0_stob * stob
Definition: storage.c:39
#define M0_ASSERT(cond)
static int stor_dom_init(struct m0_addb2_storage *stor, const char *location, uint64_t key, bool mkfs, bool force)
Definition: storage.c:272
struct m0_addb2_frame_header f_header
Definition: storage.c:108
uint64_t he_offset
Definition: storage.h:134
m0_time_t m0_time_now(void)
Definition: time.c:134
Definition: tlist.h:251
m0_bindex_t as_pos
Definition: storage.c:176
M0_INTERNAL uint64_t m0_addb2__dummy_payload_size
Definition: addb2.c:1098
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
M0_INTERNAL void * m0_stob_addr_pack(const void *buf, uint32_t shift)
Definition: io.c:293
struct m0_tl as_pending
Definition: storage.c:203
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
#define M0_POST(cond)
static m0_bindex_t stor_round(const struct m0_addb2_storage *stor, m0_bindex_t index)
Definition: storage.c:852
struct m0_addb2_storage * f_stor
Definition: storage.c:104
uint32_t v_nr
Definition: vec.h:51
static bool frame_endio(struct m0_clink *link)
Definition: storage.c:781
Definition: io.h:285
void(* sto_commit)(struct m0_addb2_storage *stor, const struct m0_addb2_frame_header *anchor)
Definition: storage.h:84
void * f_area
Definition: storage.c:125
struct m0_addb2_trace * f_trace[FRAME_TRACE_MAX]
Definition: storage.c:116
void * f_buf[IO_FRAG]
Definition: storage.c:140
static struct m0_stob_io io
Definition: ad.c:59
static bool stor_invariant(const struct m0_addb2_storage *stor)
Definition: storage.c:884
struct m0_stob * as_stob
Definition: storage.c:160
struct m0_stob * si_obj
Definition: io.h:326
static void frame_submit(struct frame *frame)
Definition: storage.c:637
unsigned as_bshift
Definition: storage.c:168
static void trace_add(struct frame *frame, struct m0_addb2_trace *trace)
Definition: storage.c:569
M0_INTERNAL void m0_stob_domain_fini(struct m0_stob_domain *dom)
Definition: domain.c:204
uint32_t he_trace_nr
Definition: storage.h:136
M0_INTERNAL int m0_stob_create(struct m0_stob *stob, struct m0_dtx *dtx, const char *str_cfg)
Definition: stob.c:154
#define m0_forall(var, nr,...)
Definition: misc.h:112
void(* sto_done)(struct m0_addb2_storage *stor, struct m0_addb2_trace_obj *obj)
Definition: storage.h:78
void m0_clink_add_lock(struct m0_chan *chan, struct m0_clink *link)
Definition: chan.c:255
M0_INTERNAL int m0_stob_domain_destroy_location(const char *location)
Definition: domain.c:242
struct m0_fid sd_id
Definition: domain.h:96
M0_INTERNAL enum m0_stob_state m0_stob_state_get(struct m0_stob *stob)
Definition: stob.c:265
M0_INTERNAL struct m0_addb2_storage * m0_addb2_storage_init(const char *location, uint64_t key, bool mkfs, bool force, const struct m0_addb2_storage_ops *ops, m0_bcount_t size, void *cookie)
Definition: kaddb2.c:42
M0_INTERNAL int m0_stob_domain_init(const char *location, const char *str_cfg_init, struct m0_stob_domain **out)
Definition: domain.c:195
static void stor_update(struct m0_addb2_storage *stor, const struct m0_addb2_frame_header *header)
Definition: storage.c:671
M0_INTERNAL void m0_format_footer_update(const void *buffer)
Definition: format.c:95
static void frame_clear(struct frame *frame)
Definition: storage.c:762
M0_INTERNAL void * m0_stob_addr_open(const void *buf, uint32_t shift)
Definition: io.c:302
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
M0_INTERNAL m0_bcount_t m0_addb2_trace_size(const struct m0_addb2_trace *trace)
Definition: addb2.c:683
M0_INTERNAL int m0_addb2_storage_submit(struct m0_addb2_storage *stor, struct m0_addb2_trace_obj *obj)
Definition: kaddb2.c:50
struct m0_tl as_queue
Definition: storage.c:189
m0_bcount_t size
Definition: di.c:39
#define _0C(exp)
Definition: assert.h:311
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
M0_INTERNAL void m0_clink_fini(struct m0_clink *link)
Definition: chan.c:208
struct m0_addb2_trace_obj as_marker
Definition: storage.c:219
M0_INTERNAL void m0_stob_io_init(struct m0_stob_io *io)
Definition: io.c:111
M0_INTERNAL int m0_stob_find(const struct m0_stob_id *id, struct m0_stob **out)
Definition: stob.c:92
static int frame_try(struct frame *frame)
Definition: storage.c:689
struct m0_tlink f_linkage
Definition: storage.c:112
static void stor_balance(struct m0_addb2_storage *stor, int delta)
Definition: storage.c:499
m0_bcount_t f_count[IO_FRAG]
Definition: storage.c:132
static void frame_io_open(struct frame *frame)
Definition: storage.c:818
#define out(...)
Definition: gen.c:41
uint64_t as_seqno
Definition: storage.c:180
M0_INTERNAL void * m0_alloc_aligned(size_t size, unsigned shift)
Definition: memory.c:168
uint64_t tr_nr
Definition: addb2.h:442
static bool trace_tryadd(struct m0_addb2_storage *stor, struct m0_addb2_trace *trace)
Definition: storage.c:537
struct m0_fom_ops ops
Definition: io_foms.c:623
void m0_free(void *data)
Definition: memory.c:146
Definition: mutex.h:47
static const struct m0_format_tag frame_tag
Definition: storage.c:264
int32_t rc
Definition: trigger_fop.h:47
struct m0_tl as_inflight
Definition: storage.c:199
#define ARRAY_SIZE(a)
Definition: misc.h:45
#define offsetof(typ, memb)
Definition: misc.h:29
M0_INTERNAL void m0_stob_put(struct m0_stob *stob)
Definition: stob.c:291
static void stor_fini(struct m0_addb2_storage *stor)
Definition: storage.c:467
static void frame_fini(struct frame *frame)
Definition: storage.c:622
Definition: vec.h:145
M0_INTERNAL int m0_addb2_storage_header(struct m0_stob *stob, struct m0_addb2_frame_header *h)
Definition: sit.c:179
Definition: idx_mock.c:47
enum m0_stob_io_opcode si_opcode
Definition: io.h:286
m0_bcount_t as_size
Definition: storage.c:172
uint64_t * tr_body
Definition: addb2.h:443