Motr  M0
log_discard.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 
23 
30 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_BE
31 #include "lib/trace.h"
32 
33 #include "be/log_discard.h"
34 
35 #include "lib/errno.h" /* ENOMEM */
36 #include "lib/ext.h" /* m0_ext */
37 #include "lib/locality.h" /* m0_locality_call */
38 #include "lib/memory.h" /* M0_ALLOC_ARR */
39 #include "lib/misc.h" /* container_of */
40 
41 #include "sm/sm.h" /* m0_sm_ast */
42 
43 #include "be/op.h" /* m0_be_op_active */
44 #include "be/pool.h" /* m0_be_pool_item */
45 
46 #include "motr/magic.h" /* M0_BE_LOG_DISCARD_POOL_MAGIC */
47 
54 };
55 
62  bool ldi_synced;
63  struct m0_ext ldi_ext;
65  uint64_t ldi_magic;
67  uint64_t ldi_pool_magic;
68 };
69 
70 
71 M0_TL_DESCR_DEFINE(ld_start, "m0_be_log_discard::lds_start_q", static,
72  struct m0_be_log_discard_item, ldi_start_link, ldi_magic,
74 M0_TL_DEFINE(ld_start, static, struct m0_be_log_discard_item);
75 
76 M0_BE_POOL_DESCR_DEFINE(ld, "m0_be_log_discard::lds_item_pool", static,
77  struct m0_be_log_discard_item, ldi_pool_item,
78  ldi_pool_magic, M0_BE_LOG_DISCARD_POOL_MAGIC);
79 M0_BE_POOL_DEFINE(ld, static, struct m0_be_log_discard_item);
80 
81 static void be_log_discard_sync_done_cb(struct m0_be_op *op, void *param);
82 static void be_log_discard_timer_start(struct m0_be_log_discard *ld);
83 static void be_log_discard_timer_cancel(struct m0_be_log_discard *ld);
84 
85 M0_INTERNAL int m0_be_log_discard_init(struct m0_be_log_discard *ld,
86  struct m0_be_log_discard_cfg *ld_cfg)
87 {
88  struct m0_be_log_discard_item *ldi;
89  uint32_t i;
90  int rc;
91  struct m0_be_pool_cfg pool_cfg = {
93  };
94 
95  ld->lds_cfg = *ld_cfg;
96 
98  if (ld->lds_item == NULL)
99  return M0_ERR(-ENOMEM);
100  rc = ld_be_pool_init(&ld->lds_item_pool, &pool_cfg);
101  if (rc != 0) {
102  m0_free(ld->lds_item);
103  return rc;
104  }
105  m0_mutex_init(&ld->lds_lock);
106  ld_start_tlist_init(&ld->lds_start_q);
107  for (i = 0; i < ld->lds_cfg.ldsc_items_max; ++i) {
108  ldi = &ld->lds_item[i];
109  *ldi = (struct m0_be_log_discard_item){
110  .ldi_ld = ld,
111  .ldi_state = LDI_INIT,
112  .ldi_synced = false,
113  };
114  ld_be_pool_add(&ld->lds_item_pool, ldi);
115  ld_start_tlink_init(ldi);
116  }
117  ld->lds_need_sync = false;
118  ld->lds_sync_in_progress = false;
120  ld->lds_discard_waiting = false;
123  ld, M0_BOS_GC);
124  ld->lds_flush_op = NULL;
126  ld->lds_stopping = false;
127  ld->lds_discard_ast_posted = false;
130  return 0;
131 }
132 
133 static void be_log_discard_wait(struct m0_be_log_discard *ld);
134 
135 M0_INTERNAL void m0_be_log_discard_fini(struct m0_be_log_discard *ld)
136 {
137  struct m0_be_log_discard_item *ldi;
138  uint32_t nr = 0;
139 
141 
142  M0_PRE(!ld->lds_need_sync);
144 
149  ldi = ld_be_pool_del(&ld->lds_item_pool);
150  while (ldi != NULL) {
151  ++nr;
152  M0_ASSERT(ldi->ldi_state == LDI_INIT);
153  ld_start_tlink_fini(ldi);
154  ldi = ld_be_pool_del(&ld->lds_item_pool);
155  }
157  ld_start_tlist_fini(&ld->lds_start_q);
158  m0_mutex_fini(&ld->lds_lock);
159  ld_be_pool_fini(&ld->lds_item_pool);
160  m0_free(ld->lds_item);
161 }
162 
163 static void be_log_discard_lock(struct m0_be_log_discard *ld)
164 {
165  m0_mutex_lock(&ld->lds_lock);
166 }
167 
169 {
171 }
172 
174 {
175  return m0_mutex_is_locked(&ld->lds_lock);
176 }
177 
179 {
181  M0_PRE(ld->lds_flush_op != NULL);
182  M0_PRE(ld_start_tlist_is_empty(&ld->lds_start_q));
183 
186  ld->lds_flush_op = NULL;
187 }
188 
190  bool force)
191 {
192  struct m0_be_log_discard_item *ldi;
193 
195 
196  if (ld->lds_need_sync || force ||
197  (!ld->lds_sync_in_progress &&
198  (ld_start_tlist_length(&ld->lds_start_q) >=
200  (!ld_start_tlist_is_empty(&ld->lds_start_q) &&
201  ld->lds_sync_deadline <= m0_time_now()))))
202  ld->lds_need_sync = true;
203  if (ld->lds_need_sync && !ld->lds_sync_in_progress) {
204  ld->lds_need_sync = false;
205  ld->lds_sync_item = NULL;
206  m0_tl_for(ld_start, &ld->lds_start_q, ldi) {
207  if (ldi->ldi_state == LDI_STARTING)
208  break;
209  ld->lds_sync_item = ldi;
210  } m0_tl_endfor;
211  if (ld->lds_sync_item == NULL && ld->lds_flush_op != NULL)
213  if (ld->lds_sync_item != NULL) {
214  ld->lds_sync_in_progress = true;
215  M0_LOG(M0_DEBUG, "ld=%p lds_sync_item=%p",
216  ld, ld->lds_sync_item);
217  /* be_log_discard_sync_done_cb() locks ld */
219  ld->lds_cfg.ldsc_sync(ld, &ld->lds_sync_op,
220  ld->lds_sync_item);
222  }
223  }
224 }
225 
227  struct m0_be_log_discard_item *ldi)
228 {
229 
230  M0_ENTRY("ld=%p ldi=%p", ld, ldi);
231 
232  ld->lds_cfg.ldsc_discard(ld, ldi);
233  ldi->ldi_state = LDI_DISCARDED;
237 }
238 
240  struct m0_be_log_discard_item *ldi)
241 {
242  M0_PRE(M0_IN(ldi->ldi_state, (LDI_STARTING, LDI_FINISHED)));
243 
244  if (ldi->ldi_state == LDI_FINISHED && ldi->ldi_synced)
245  ldi->ldi_state = LDI_SYNCED;
246  if (ldi->ldi_state == LDI_SYNCED)
248 }
249 
250 static void be_log_discard_ast(struct m0_sm_group *grp,
251  struct m0_sm_ast *ast)
252 {
253  struct m0_be_log_discard *ld = ast->sa_datum;
254  struct m0_be_log_discard_item *ldi;
255  struct m0_be_log_discard_item *sync_item;
256 
257  M0_ENTRY("ld=%p", ld);
258 
259  do {
261  sync_item = ld->lds_sync_item;
262  ldi = ld_start_tlist_pop(&ld->lds_start_q);
264 
265  M0_ASSERT(ldi != NULL && sync_item != NULL);
267  "ldi=%p state=%d", ldi, ldi->ldi_state);
268  ldi->ldi_synced = true;
270  } while (ldi != sync_item);
271 
273  ld->lds_sync_item = NULL;
274  ld->lds_sync_in_progress = false;
275  if (ld_start_tlist_is_empty(&ld->lds_start_q))
277  be_log_discard_check_sync(ld, false);
278  ld->lds_discard_ast_posted = false;
279 
280  if (ld->lds_flush_op != NULL)
282  if (ld->lds_discard_waiting)
285 }
286 
287 static void be_log_discard_sync_done_cb(struct m0_be_op *op, void *param)
288 {
289  struct m0_be_log_discard *ld = param;
290 
291  M0_LOG(M0_DEBUG, "ld=%p", ld);
293 
295  if (ld->lds_discard_ast_posted) {
297  return;
298  }
299 
300  ld->lds_discard_ast_posted = true;
301  ld->lds_discard_ast = (struct m0_sm_ast){
303  .sa_datum = ld,
304  };
306 
308 }
309 
310 static void be_log_discard_timer_cb(struct m0_sm_timer *timer);
311 
313 {
314  struct m0_be_log_discard *ld = param;
315  m0_time_t deadline = 0;
316  int rc;
317 
318  if (!ld->lds_stopping) {
320  deadline = ld->lds_sync_deadline == M0_TIME_NEVER ||
321  ld->lds_sync_deadline <= m0_time_now() ?
323  ld->lds_sync_deadline;
325  ld->lds_cfg.ldsc_loc->lo_grp,
326  &be_log_discard_timer_cb, deadline);
327  M0_ASSERT_INFO(rc == 0, "rc = %d", rc);
329  }
330  return 0;
331 }
332 
334 {
337 }
338 
340 {
341  struct m0_be_log_discard *ld = param;
342 
343  ld->lds_stopping = true;
345  return 0;
346 }
347 
349 {
352 }
353 
354 static void be_log_discard_timer_cb(struct m0_sm_timer *timer)
355 {
356  struct m0_be_log_discard *ld;
357 
358  ld = container_of(timer, struct m0_be_log_discard, lds_sync_timer);
360  be_log_discard_check_sync(ld, false);
365 }
366 
367 M0_INTERNAL void m0_be_log_discard_sync(struct m0_be_log_discard *ld)
368 {
370  be_log_discard_check_sync(ld, true);
372 }
373 
374 M0_INTERNAL void m0_be_log_discard_flush(struct m0_be_log_discard *ld,
375  struct m0_be_op *op)
376 {
378  M0_PRE(ld->lds_flush_op == NULL);
379  ld->lds_flush_op = op;
380  be_log_discard_check_sync(ld, true);
382 }
383 
384 static void be_log_discard_wait(struct m0_be_log_discard *ld)
385 {
386  bool posted;
387 
389 
391  ld->lds_discard_waiting = true;
392  posted = ld->lds_discard_ast_posted;
394 
395  if (posted)
397 }
398 
399 M0_INTERNAL void
401  struct m0_be_log_discard_item *ldi)
402 {
403  M0_LOG(M0_DEBUG, "ld=%p ldi=%p", ld, ldi);
404 
406  M0_PRE(ldi->ldi_state == LDI_INIT);
407  ldi->ldi_time_start = m0_time_now();
408  ldi->ldi_state = LDI_STARTING;
409  ld_start_tlist_add_tail(&ld->lds_start_q, ldi);
410  ld->lds_sync_deadline = ldi->ldi_time_start +
412  be_log_discard_check_sync(ld, false);
414 }
415 
416 M0_INTERNAL void
418  struct m0_be_log_discard_item *ldi)
419 {
420  M0_LOG(M0_DEBUG, "ld=%p ldi=%p", ld, ldi);
421 
423  M0_PRE(ldi->ldi_state == LDI_STARTING);
424  ldi->ldi_time_finish = m0_time_now();
425  ldi->ldi_state = LDI_FINISHED;
428 }
429 
431  struct m0_be_log_discard_item *ldi)
432 {
433  M0_PRE(M0_IN(ldi->ldi_state, (LDI_INIT, LDI_DISCARDED)));
434 
435  ldi->ldi_state = LDI_INIT;
436  ldi->ldi_synced = false;
437  ldi->ldi_time_start = 0;
438  ldi->ldi_time_finish = 0;
441 }
442 
443 M0_INTERNAL void
445  struct m0_be_op *op,
446  struct m0_be_log_discard_item **ldi)
447 {
448  ld_be_pool_get(&ld->lds_item_pool, ldi, op);
449 }
450 
451 M0_INTERNAL void m0_be_log_discard_item_put(struct m0_be_log_discard *ld,
452  struct m0_be_log_discard_item *ldi)
453 {
454  M0_LOG(M0_DEBUG, "ld=%p ldi=%p", ld, ldi);
455 
456  be_log_discard_item_reset(ld, ldi);
457  ld_be_pool_put(&ld->lds_item_pool, ldi);
458 }
459 
460 M0_INTERNAL void
462  void *data)
463 {
464  ldi->ldi_user_data = data;
465 }
466 
467 M0_INTERNAL void *
469 {
470  return ldi->ldi_user_data;
471 }
472 
473 M0_INTERNAL void
475  struct m0_ext *ext)
476 {
477  ldi->ldi_ext = *ext;
478 }
479 
480 M0_INTERNAL struct m0_ext *
482 {
483  return &ldi->ldi_ext;
484 }
485 
486 #undef M0_TRACE_SUBSYSTEM
487 
490 /*
491  * Local variables:
492  * c-indentation-style: "K&R"
493  * c-basic-offset: 8
494  * tab-width: 8
495  * fill-column: 80
496  * scroll-step: 1
497  * End:
498  */
499 /*
500  * vim: tabstop=8 shiftwidth=8 noexpandtab textwidth=80 nowrap
501  */
M0_INTERNAL void m0_be_log_discard_item_finished(struct m0_be_log_discard *ld, struct m0_be_log_discard_item *ldi)
Definition: log_discard.c:417
struct m0_tl lds_start_q
Definition: log_discard.h:103
static size_t nr
Definition: dump.c:1505
static void be_log_discard_sync_done_cb(struct m0_be_op *op, void *param)
Definition: log_discard.c:287
struct m0_be_op * lds_flush_op
Definition: log_discard.h:109
#define M0_PRE(cond)
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_TL_DESCR_DEFINE(ld_start, "m0_be_log_discard::lds_start_q", static, struct m0_be_log_discard_item, ldi_start_link, ldi_magic, M0_BE_LOG_DISCARD_MAGIC, M0_BE_LOG_DISCARD_HEAD_MAGIC)
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
#define NULL
Definition: misc.h:38
void(* sa_cb)(struct m0_sm_group *grp, struct m0_sm_ast *)
Definition: sm.h:506
struct m0_be_log_discard_item * lds_sync_item
Definition: log_discard.h:106
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
m0_time_t lds_sync_deadline
Definition: log_discard.h:107
static void be_log_discard_unlock(struct m0_be_log_discard *ld)
Definition: log_discard.c:168
static struct m0_sm_group * grp
Definition: bytecount.c:38
uint64_t m0_time_t
Definition: time.h:37
#define M0_LOG(level,...)
Definition: trace.h:167
struct m0_locality * ldsc_loc
Definition: log_discard.h:94
static void be_log_discard_flush_finished(struct m0_be_log_discard *ld)
Definition: log_discard.c:178
M0_INTERNAL void m0_sm_ast_post(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: sm.c:135
M0_INTERNAL void m0_be_log_discard_flush(struct m0_be_log_discard *ld, struct m0_be_op *op)
Definition: log_discard.c:374
void(* ldsc_sync)(struct m0_be_log_discard *ld, struct m0_be_op *op, struct m0_be_log_discard_item *ldi)
Definition: log_discard.h:81
M0_INTERNAL void m0_be_log_discard_item_starting(struct m0_be_log_discard *ld, struct m0_be_log_discard_item *ldi)
Definition: log_discard.c:400
struct m0_bufvec data
Definition: di.c:40
struct m0_semaphore lds_discard_wait_sem
Definition: log_discard.h:117
m0_time_t ldi_time_start
Definition: log_discard.c:60
Definition: sm.h:504
M0_BE_POOL_DEFINE(ld, static, struct m0_be_log_discard_item)
uint32_t ldsc_items_pending_max
Definition: log_discard.h:93
M0_INTERNAL void m0_be_op_callback_set(struct m0_be_op *op, m0_be_op_cb_t cb, void *param, enum m0_be_op_state state)
Definition: op.c:239
#define container_of(ptr, type, member)
Definition: misc.h:33
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
int m0_locality_call(struct m0_locality *loc, int(*cb)(void *), void *data)
Definition: locality.c:570
struct m0_tlink ldi_start_link
Definition: log_discard.c:64
static void be_log_discard_check_sync(struct m0_be_log_discard *ld, bool force)
Definition: log_discard.c:189
struct m0_sm_ast lds_discard_ast
Definition: log_discard.h:122
enum be_log_discard_item_state ldi_state
Definition: log_discard.c:58
M0_INTERNAL int m0_be_log_discard_init(struct m0_be_log_discard *ld, struct m0_be_log_discard_cfg *ld_cfg)
Definition: log_discard.c:85
#define m0_tl_endfor
Definition: tlist.h:700
op
Definition: libdemo.c:64
struct m0_be_pool_item ldi_pool_item
Definition: log_discard.c:66
#define M0_ENTRY(...)
Definition: trace.h:170
static struct m0_sm_ast ast[NR]
Definition: locality.c:44
int i
Definition: dir.c:1033
struct m0_be_log_discard_cfg lds_cfg
Definition: log_discard.h:99
struct m0_be_log_discard_item * lds_item
Definition: log_discard.h:100
static void be_log_discard_item_reset(struct m0_be_log_discard *ld, struct m0_be_log_discard_item *ldi)
Definition: log_discard.c:430
return M0_ERR(-EOPNOTSUPP)
void * sa_datum
Definition: sm.h:508
struct m0_be_log_discard * ldi_ld
Definition: log_discard.c:57
M0_INTERNAL void m0_be_log_discard_item_get(struct m0_be_log_discard *ld, struct m0_be_op *op, struct m0_be_log_discard_item **ldi)
Definition: log_discard.c:444
#define M0_ASSERT(cond)
M0_INTERNAL void m0_be_log_discard_item_put(struct m0_be_log_discard *ld, struct m0_be_log_discard_item *ldi)
Definition: log_discard.c:451
M0_INTERNAL bool m0_mutex_is_locked(const struct m0_mutex *mutex)
Definition: mutex.c:95
static void be_log_discard_item_trydiscard(struct m0_be_log_discard *ld, struct m0_be_log_discard_item *ldi)
Definition: log_discard.c:239
m0_time_t m0_time_now(void)
Definition: time.c:134
static int be_log_discard_timer_cancel_loc(void *param)
Definition: log_discard.c:339
uint32_t ldsc_items_threshold
Definition: log_discard.h:92
bool lds_discard_ast_posted
Definition: log_discard.h:123
static void be_log_discard_wait(struct m0_be_log_discard *ld)
Definition: log_discard.c:384
M0_INTERNAL void m0_be_log_discard_item_ext_set(struct m0_be_log_discard_item *ldi, struct m0_ext *ext)
Definition: log_discard.c:474
m0_time_t ldi_time_finish
Definition: log_discard.c:61
M0_INTERNAL int m0_semaphore_init(struct m0_semaphore *semaphore, unsigned value)
Definition: semaphore.c:38
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
struct m0_sm_group * lo_grp
Definition: locality.h:67
static bool be_log_discard_is_locked(struct m0_be_log_discard *ld)
Definition: log_discard.c:173
M0_INTERNAL void m0_be_op_done(struct m0_be_op *op)
Definition: stubs.c:104
struct m0_be_op lds_sync_op
Definition: log_discard.h:108
struct m0_be_pool lds_item_pool
Definition: log_discard.h:102
M0_INTERNAL void m0_be_log_discard_fini(struct m0_be_log_discard *ld)
Definition: log_discard.c:135
M0_INTERNAL struct m0_locality * m0_locality_here(void)
Definition: locality.c:146
void(* ldsc_discard)(struct m0_be_log_discard *ld, struct m0_be_log_discard_item *ldi)
Definition: log_discard.h:84
static void be_log_discard_item_discard(struct m0_be_log_discard *ld, struct m0_be_log_discard_item *ldi)
Definition: log_discard.c:226
unsigned bplc_q_size
Definition: pool.h:45
static void be_log_discard_timer_cancel(struct m0_be_log_discard *ld)
Definition: log_discard.c:348
M0_INTERNAL void m0_be_op_reset(struct m0_be_op *op)
Definition: op.c:152
struct m0_sm_timer lds_sync_timer
Definition: log_discard.h:110
M0_INTERNAL void m0_be_op_active(struct m0_be_op *op)
Definition: stubs.c:100
static void be_log_discard_lock(struct m0_be_log_discard *ld)
Definition: log_discard.c:163
M0_INTERNAL void m0_sm_timer_cancel(struct m0_sm_timer *timer)
Definition: sm.c:610
Definition: ext.h:37
M0_INTERNAL void m0_be_log_discard_sync(struct m0_be_log_discard *ld)
Definition: log_discard.c:367
be_log_discard_item_state
Definition: log_discard.c:48
M0_INTERNAL void m0_semaphore_fini(struct m0_semaphore *semaphore)
Definition: semaphore.c:45
Definition: op.h:64
M0_BE_POOL_DESCR_DEFINE(ld, "m0_be_log_discard::lds_item_pool", static, struct m0_be_log_discard_item, ldi_pool_item, ldi_pool_magic, M0_BE_LOG_DISCARD_POOL_MAGIC)
struct m0_ext ldi_ext
Definition: log_discard.c:63
M0_INTERNAL void m0_be_op_fini(struct m0_be_op *op)
Definition: stubs.c:92
static void be_log_discard_ast(struct m0_sm_group *grp, struct m0_sm_ast *ast)
Definition: log_discard.c:250
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
M0_TL_DEFINE(ld_start, static, struct m0_be_log_discard_item)
M0_INTERNAL void * m0_be_log_discard_item_user_data(struct m0_be_log_discard_item *ldi)
Definition: log_discard.c:468
#define M0_ASSERT_INFO(cond, fmt,...)
static int be_log_discard_timer_start_loc(void *param)
Definition: log_discard.c:312
M0_INTERNAL struct m0_ext * m0_be_log_discard_item_ext(struct m0_be_log_discard_item *ldi)
Definition: log_discard.c:481
M0_INTERNAL void m0_semaphore_down(struct m0_semaphore *semaphore)
Definition: semaphore.c:49
M0_INTERNAL void m0_semaphore_up(struct m0_semaphore *semaphore)
Definition: semaphore.c:65
M0_INTERNAL void m0_sm_timer_fini(struct m0_sm_timer *timer)
Definition: sm.c:566
M0_INTERNAL void m0_be_log_discard_item_user_data_set(struct m0_be_log_discard_item *ldi, void *data)
Definition: log_discard.c:461
Definition: op.h:74
M0_INTERNAL void m0_sm_timer_init(struct m0_sm_timer *timer)
Definition: sm.c:559
m0_time_t ldsc_sync_timeout
Definition: log_discard.h:95
#define m0_tl_for(name, head, obj)
Definition: tlist.h:695
M0_INTERNAL void m0_be_op_init(struct m0_be_op *op)
Definition: stubs.c:87
void m0_free(void *data)
Definition: memory.c:146
static void be_log_discard_timer_cb(struct m0_sm_timer *timer)
Definition: log_discard.c:354
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL int m0_sm_timer_start(struct m0_sm_timer *timer, struct m0_sm_group *group, void(*cb)(struct m0_sm_timer *), m0_time_t deadline)
Definition: sm.c:577
struct m0_mutex lds_lock
Definition: log_discard.h:101
static void be_log_discard_timer_start(struct m0_be_log_discard *ld)
Definition: log_discard.c:333