Whamcloud - gitweb
f6e1d2beacc761be69d427c793698fbff65f31f6
[fs/lustre-release.git] / lustre / include / lustre_update.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.htm
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2013, 2015, Intel Corporation.
24  */
25 /*
26  * lustre/include/lustre_update.h
27  *
28  * Author: Di Wang <di.wang@intel.com>
29  */
30
31 #ifndef _LUSTRE_UPDATE_H
32 #define _LUSTRE_UPDATE_H
33 #include <lustre_net.h>
34 #include <dt_object.h>
35
36 #define OUT_UPDATE_INIT_BUFFER_SIZE     4096
37 #define OUT_UPDATE_REPLY_SIZE           4096
38 #define OUT_BULK_BUFFER_SIZE            4096
39
40 struct dt_key;
41 struct dt_rec;
42 struct object_update_param;
43 struct llog_update_record;
44
45 static inline size_t update_params_size(const struct update_params *params,
46                                         unsigned int param_count)
47 {
48         struct object_update_param      *param;
49         size_t total_size = sizeof(*params);
50         unsigned int i;
51
52         param = (struct object_update_param *)&params->up_params[0];
53         for (i = 0; i < param_count; i++) {
54                 size_t size = object_update_param_size(param);
55
56                 param = (struct object_update_param *)((char *)param + size);
57                 total_size += size;
58         }
59
60         return total_size;
61 }
62
63 static inline struct object_update_param *
64 update_params_get_param(const struct update_params *params,
65                         unsigned int index, unsigned int param_count)
66 {
67         struct object_update_param *param;
68         unsigned int            i;
69
70         if (index > param_count)
71                 return NULL;
72
73         param = (struct object_update_param *)&params->up_params[0];
74         for (i = 0; i < index; i++)
75                 param = (struct object_update_param *)((char *)param +
76                         object_update_param_size(param));
77
78         return param;
79 }
80
81 static inline void*
82 update_params_get_param_buf(const struct update_params *params, __u16 index,
83                             unsigned int param_count, __u16 *size)
84 {
85         struct object_update_param *param;
86
87         param = update_params_get_param(params, (unsigned int)index,
88                                         param_count);
89         if (param == NULL)
90                 return NULL;
91
92         if (size != NULL)
93                 *size = param->oup_len;
94
95         return param->oup_buf;
96 }
97
98 static inline size_t
99 update_op_size(unsigned int param_count)
100 {
101         return offsetof(struct update_op, uop_params_off[param_count]);
102 }
103
104 static inline struct update_op *
105 update_op_next_op(const struct update_op *uop)
106 {
107         return (struct update_op *)((char *)uop +
108                                 update_op_size(uop->uop_param_count));
109 }
110
111 static inline size_t update_ops_size(const struct update_ops *ops,
112                                      unsigned int update_count)
113 {
114         struct update_op *op;
115         size_t total_size = sizeof(*ops);
116         unsigned int i;
117
118         op = (struct update_op *)&ops->uops_op[0];
119         for (i = 0; i < update_count; i++, op = update_op_next_op(op))
120                 total_size += update_op_size(op->uop_param_count);
121
122         return total_size;
123 }
124
125 static inline struct update_params *
126 update_records_get_params(const struct update_records *record)
127 {
128         return (struct update_params *)((char *)record +
129                 offsetof(struct update_records, ur_ops) +
130                 update_ops_size(&record->ur_ops, record->ur_update_count));
131 }
132
133 static inline size_t
134 update_records_size(const struct update_records *record)
135 {
136         size_t op_size = 0;
137         size_t param_size = 0;
138
139         if (record->ur_update_count > 0)
140                 op_size = update_ops_size(&record->ur_ops,
141                                           record->ur_update_count);
142         if (record->ur_param_count > 0) {
143                 struct update_params *params;
144
145                 params = update_records_get_params(record);
146                 param_size = update_params_size(params, record->ur_param_count);
147         }
148
149         return cfs_size_round(offsetof(struct update_records, ur_ops) +
150                               op_size + param_size);
151 }
152
153 static inline size_t
154 llog_update_record_size(const struct llog_update_record *lur)
155 {
156         return cfs_size_round(sizeof(lur->lur_hdr) +
157                               update_records_size(&lur->lur_update_rec) +
158                               sizeof(struct llog_rec_tail));
159 }
160
161 static inline struct update_op *
162 update_ops_get_op(const struct update_ops *ops, unsigned int index,
163                   unsigned int update_count)
164 {
165         struct update_op *op;
166         unsigned int i;
167
168         if (index > update_count)
169                 return NULL;
170
171         op = (struct update_op *)&ops->uops_op[0];
172         for (i = 0; i < index; i++)
173                 op = update_op_next_op(op);
174
175         return op;
176 }
177
178 static inline void
179 *object_update_param_get(const struct object_update *update, size_t index,
180                          size_t *size)
181 {
182         const struct    object_update_param *param;
183         size_t          i;
184
185         if (index >= update->ou_params_count)
186                 return ERR_PTR(-EINVAL);
187
188         param = &update->ou_params[0];
189         for (i = 0; i < index; i++)
190                 param = (struct object_update_param *)((char *)param +
191                         object_update_param_size(param));
192
193         if (size != NULL)
194                 *size = param->oup_len;
195
196         if (param->oup_len == 0)
197                 return ERR_PTR(-ENODATA);
198
199         return (void *)&param->oup_buf[0];
200 }
201
202 static inline unsigned long
203 object_update_request_size(const struct object_update_request *our)
204 {
205         unsigned long   size;
206         size_t          i = 0;
207
208         size = offsetof(struct object_update_request, ourq_updates[0]);
209         for (i = 0; i < our->ourq_count; i++) {
210                 struct object_update *update;
211
212                 update = (struct object_update *)((char *)our + size);
213                 size += object_update_size(update);
214         }
215         return size;
216 }
217
218 static inline void
219 object_update_result_insert(struct object_update_reply *reply,
220                             void *data, size_t data_len, size_t index,
221                             int rc)
222 {
223         struct object_update_result *update_result;
224         char *ptr;
225
226         update_result = object_update_result_get(reply, index, NULL);
227         LASSERT(update_result != NULL);
228
229         update_result->our_rc = ptlrpc_status_hton(rc);
230         if (data != NULL && data_len > 0) {
231                 LASSERT(data != NULL);
232                 ptr = (char *)update_result +
233                         cfs_size_round(sizeof(struct object_update_reply));
234                 update_result->our_datalen = data_len;
235                 memcpy(ptr, data, data_len);
236         }
237
238         reply->ourp_lens[index] = cfs_size_round(data_len +
239                                         sizeof(struct object_update_result));
240 }
241
242 static inline int
243 object_update_result_data_get(const struct object_update_reply *reply,
244                               struct lu_buf *lbuf, size_t index)
245 {
246         struct object_update_result *update_result;
247         size_t size = 0;
248         int    result;
249
250         LASSERT(lbuf != NULL);
251         update_result = object_update_result_get(reply, index, &size);
252         if (update_result == NULL ||
253             size < cfs_size_round(sizeof(struct object_update_reply)) ||
254             update_result->our_datalen > size)
255                 RETURN(-EFAULT);
256
257         result = ptlrpc_status_ntoh(update_result->our_rc);
258         if (result < 0)
259                 return result;
260
261         lbuf->lb_buf = update_result->our_data;
262         lbuf->lb_len = update_result->our_datalen;
263
264         return result;
265 }
266
267 /**
268  * Attached in the thandle to record the updates for distribute
269  * distribution.
270  */
271 struct thandle_update_records {
272         /* All of updates for the cross-MDT operation. */
273         struct llog_update_record       *tur_update_records;
274         size_t                          tur_update_records_buf_size;
275
276         /* All of parameters for the cross-MDT operation */
277         struct update_params    *tur_update_params;
278         unsigned int            tur_update_param_count;
279         size_t                  tur_update_params_buf_size;
280 };
281
282 #define TOP_THANDLE_MAGIC       0x20140917
283 struct top_multiple_thandle {
284         struct dt_device        *tmt_master_sub_dt;
285         atomic_t                tmt_refcount;
286         /* Other sub transactions will be listed here. */
287         struct list_head        tmt_sub_thandle_list;
288         spinlock_t              tmt_sub_lock;
289
290         struct list_head        tmt_commit_list;
291         /* All of update records will packed here */
292         struct thandle_update_records *tmt_update_records;
293
294         wait_queue_head_t       tmt_stop_waitq;
295         __u64                   tmt_batchid;
296         int                     tmt_result;
297         __u32                   tmt_magic;
298         size_t                  tmt_record_size;
299         __u32                   tmt_committed:1;
300 };
301
302 /* {top,sub}_thandle are used to manage distributed transactions which
303  * include updates on several nodes. A top_handle represents the
304  * whole operation, and sub_thandle represents updates on each node. */
305 struct top_thandle {
306         struct thandle          tt_super;
307         /* The master sub transaction. */
308         struct thandle          *tt_master_sub_thandle;
309
310         struct top_multiple_thandle *tt_multiple_thandle;
311 };
312
313 struct sub_thandle_cookie {
314         struct llog_cookie      stc_cookie;
315         struct list_head        stc_list;
316 };
317
318 /* Sub thandle is used to track multiple sub thandles under one parent
319  * thandle */
320 struct sub_thandle {
321         struct thandle          *st_sub_th;
322         struct dt_device        *st_dt;
323         struct list_head        st_cookie_list;
324         struct dt_txn_commit_cb st_commit_dcb;
325         struct dt_txn_commit_cb st_stop_dcb;
326         int                     st_result;
327
328         /* linked to top_thandle */
329         struct list_head        st_sub_list;
330
331         /* If this sub thandle is committed */
332         bool                    st_committed:1,
333                                 st_stopped:1,
334                                 st_started:1;
335 };
336
337 struct tx_arg;
338 typedef int (*tx_exec_func_t)(const struct lu_env *env, struct thandle *th,
339                               struct tx_arg *ta);
340
341 /* Structure for holding one update execution */
342 struct tx_arg {
343         tx_exec_func_t           exec_fn;
344         tx_exec_func_t           undo_fn;
345         struct dt_object        *object;
346         const char              *file;
347         struct object_update_reply *reply;
348         int                      line;
349         int                      index;
350         union {
351                 struct {
352                         struct dt_insert_rec     rec;
353                         const struct dt_key     *key;
354                 } insert;
355                 struct {
356                 } ref;
357                 struct {
358                         struct lu_attr   attr;
359                 } attr_set;
360                 struct {
361                         struct lu_buf    buf;
362                         const char      *name;
363                         int              flags;
364                         __u32            csum;
365                 } xattr_set;
366                 struct {
367                         struct lu_attr                  attr;
368                         struct dt_allocation_hint       hint;
369                         struct dt_object_format         dof;
370                         struct lu_fid                   fid;
371                 } create;
372                 struct {
373                         struct lu_buf   buf;
374                         loff_t          pos;
375                 } write;
376                 struct {
377                         struct ost_body     *body;
378                 } destroy;
379         } u;
380 };
381
382 /* Structure for holding all update executations of one transaction */
383 struct thandle_exec_args {
384         struct thandle          *ta_handle;
385         int                     ta_argno;   /* used args */
386         int                     ta_alloc_args; /* allocated args count */
387         struct tx_arg           **ta_args;
388 };
389
390 /* target/out_lib.c */
391 int out_update_pack(const struct lu_env *env, struct object_update *update,
392                     size_t *max_update_size, enum update_type op,
393                     const struct lu_fid *fid, unsigned int params_count,
394                     __u16 *param_sizes, const void **param_bufs,
395                     __u32 reply_size);
396 int out_create_pack(const struct lu_env *env, struct object_update *update,
397                     size_t *max_update_size, const struct lu_fid *fid,
398                     const struct lu_attr *attr, struct dt_allocation_hint *hint,
399                     struct dt_object_format *dof);
400 int out_object_destroy_pack(const struct lu_env *env,
401                             struct object_update *update,
402                             size_t *max_update_size,
403                             const struct lu_fid *fid);
404 int out_index_delete_pack(const struct lu_env *env,
405                           struct object_update *update, size_t *max_update_size,
406                           const struct lu_fid *fid, const struct dt_key *key);
407 int out_index_insert_pack(const struct lu_env *env,
408                           struct object_update *update, size_t *max_update_size,
409                           const struct lu_fid *fid, const struct dt_rec *rec,
410                           const struct dt_key *key);
411 int out_xattr_set_pack(const struct lu_env *env,
412                        struct object_update *update, size_t *max_update_size,
413                        const struct lu_fid *fid, const struct lu_buf *buf,
414                        const char *name, __u32 flag);
415 int out_xattr_del_pack(const struct lu_env *env,
416                        struct object_update *update, size_t *max_update_size,
417                        const struct lu_fid *fid, const char *name);
418 int out_attr_set_pack(const struct lu_env *env,
419                       struct object_update *update, size_t *max_update_size,
420                       const struct lu_fid *fid, const struct lu_attr *attr);
421 int out_ref_add_pack(const struct lu_env *env,
422                      struct object_update *update, size_t *max_update_size,
423                      const struct lu_fid *fid);
424 int out_ref_del_pack(const struct lu_env *env,
425                      struct object_update *update, size_t *max_update_size,
426                      const struct lu_fid *fid);
427 int out_write_pack(const struct lu_env *env,
428                    struct object_update *update, size_t *max_update_size,
429                    const struct lu_fid *fid, const struct lu_buf *buf,
430                    __u64 pos);
431 int out_attr_get_pack(const struct lu_env *env,
432                       struct object_update *update, size_t *max_update_size,
433                       const struct lu_fid *fid);
434 int out_index_lookup_pack(const struct lu_env *env,
435                           struct object_update *update, size_t *max_update_size,
436                           const struct lu_fid *fid, struct dt_rec *rec,
437                           const struct dt_key *key);
438 int out_xattr_get_pack(const struct lu_env *env,
439                        struct object_update *update, size_t *max_update_size,
440                        const struct lu_fid *fid, const char *name,
441                        const int bufsize);
442 int out_read_pack(const struct lu_env *env, struct object_update *update,
443                   size_t *max_update_length, const struct lu_fid *fid,
444                   size_t size, loff_t pos);
445
446 const char *update_op_str(__u16 opcode);
447
448 /* target/update_trans.c */
449 struct thandle *thandle_get_sub_by_dt(const struct lu_env *env,
450                                       struct thandle *th,
451                                       struct dt_device *sub_dt);
452
453 static inline struct thandle *
454 thandle_get_sub(const struct lu_env *env, struct thandle *th,
455                  const struct dt_object *sub_obj)
456 {
457         return thandle_get_sub_by_dt(env, th, lu2dt_dev(sub_obj->do_lu.lo_dev));
458 }
459
460 struct thandle *
461 top_trans_create(const struct lu_env *env, struct dt_device *master_dev);
462 int top_trans_start(const struct lu_env *env, struct dt_device *master_dev,
463                     struct thandle *th);
464 int top_trans_stop(const struct lu_env *env, struct dt_device *master_dev,
465                    struct thandle *th);
466 void top_multiple_thandle_destroy(struct top_multiple_thandle *tmt);
467
468 static inline void top_multiple_thandle_get(struct top_multiple_thandle *tmt)
469 {
470         atomic_inc(&tmt->tmt_refcount);
471 }
472
473 static inline void top_multiple_thandle_put(struct top_multiple_thandle *tmt)
474 {
475         if (atomic_dec_and_test(&tmt->tmt_refcount))
476                 top_multiple_thandle_destroy(tmt);
477 }
478
479 struct sub_thandle *lookup_sub_thandle(struct top_multiple_thandle *tmt,
480                                        struct dt_device *dt_dev);
481 int sub_thandle_trans_create(const struct lu_env *env,
482                              struct top_thandle *top_th,
483                              struct sub_thandle *st);
484
485 /* update_records.c */
486 size_t update_records_create_size(const struct lu_env *env,
487                                   const struct lu_fid *fid,
488                                   const struct lu_attr *attr,
489                                   const struct dt_allocation_hint *hint,
490                                   struct dt_object_format *dof);
491 size_t update_records_attr_set_size(const struct lu_env *env,
492                                     const struct lu_fid *fid,
493                                     const struct lu_attr *attr);
494 size_t update_records_ref_add_size(const struct lu_env *env,
495                                    const struct lu_fid *fid);
496 size_t update_records_ref_del_size(const struct lu_env *env,
497                                    const struct lu_fid *fid);
498 size_t update_records_object_destroy_size(const struct lu_env *env,
499                                           const struct lu_fid *fid);
500 size_t update_records_index_insert_size(const struct lu_env *env,
501                                         const struct lu_fid *fid,
502                                         const struct dt_rec *rec,
503                                         const struct dt_key *key);
504 size_t update_records_index_delete_size(const struct lu_env *env,
505                                         const struct lu_fid *fid,
506                                         const struct dt_key *key);
507 size_t update_records_xattr_set_size(const struct lu_env *env,
508                                      const struct lu_fid *fid,
509                                      const struct lu_buf *buf,
510                                      const char *name,
511                                      __u32 flag);
512 size_t update_records_xattr_del_size(const struct lu_env *env,
513                                      const struct lu_fid *fid,
514                                      const char *name);
515 size_t update_records_write_size(const struct lu_env *env,
516                                  const struct lu_fid *fid,
517                                  const struct lu_buf *buf,
518                                  __u64 pos);
519 size_t update_records_punch_size(const struct lu_env *env,
520                                  const struct lu_fid *fid,
521                                  __u64 start, __u64 end);
522
523 int update_records_create_pack(const struct lu_env *env,
524                                struct update_ops *ops,
525                                unsigned int *op_count,
526                                size_t *max_ops_size,
527                                struct update_params *params,
528                                unsigned int *param_count,
529                                size_t *max_param_size,
530                                const struct lu_fid *fid,
531                                const struct lu_attr *attr,
532                                const struct dt_allocation_hint *hint,
533                                struct dt_object_format *dof);
534 int update_records_attr_set_pack(const struct lu_env *env,
535                                  struct update_ops *ops,
536                                  unsigned int *op_count,
537                                  size_t *max_ops_size,
538                                  struct update_params *params,
539                                  unsigned int *param_count,
540                                  size_t *max_param_size,
541                                  const struct lu_fid *fid,
542                                  const struct lu_attr *attr);
543 int update_records_ref_add_pack(const struct lu_env *env,
544                                 struct update_ops *ops,
545                                 unsigned int *op_count,
546                                 size_t *max_ops_size,
547                                 struct update_params *params,
548                                 unsigned int *param_count,
549                                 size_t *max_param_size,
550                                 const struct lu_fid *fid);
551 int update_records_ref_del_pack(const struct lu_env *env,
552                                 struct update_ops *ops,
553                                 unsigned int *op_count,
554                                 size_t *max_ops_size,
555                                 struct update_params *params,
556                                 unsigned int *param_count,
557                                 size_t *max_param_size,
558                                 const struct lu_fid *fid);
559 int update_records_object_destroy_pack(const struct lu_env *env,
560                                        struct update_ops *ops,
561                                        unsigned int *op_count,
562                                        size_t *max_ops_size,
563                                        struct update_params *params,
564                                        unsigned int *param_count,
565                                        size_t *max_param_size,
566                                        const struct lu_fid *fid);
567 int update_records_index_insert_pack(const struct lu_env *env,
568                                      struct update_ops *ops,
569                                      unsigned int *op_count,
570                                      size_t *max_ops_size,
571                                      struct update_params *params,
572                                      unsigned int *param_count,
573                                      size_t *max_param_size,
574                                      const struct lu_fid *fid,
575                                      const struct dt_rec *rec,
576                                      const struct dt_key *key);
577 int update_records_index_delete_pack(const struct lu_env *env,
578                                      struct update_ops *ops,
579                                      unsigned int *op_count,
580                                      size_t *max_ops_size,
581                                      struct update_params *params,
582                                      unsigned int *param_count,
583                                      size_t *max_param_size,
584                                      const struct lu_fid *fid,
585                                      const struct dt_key *key);
586 int update_records_xattr_set_pack(const struct lu_env *env,
587                                   struct update_ops *ops,
588                                   unsigned int *op_count,
589                                   size_t *max_ops_size,
590                                   struct update_params *params,
591                                   unsigned int *param_count,
592                                   size_t *max_param_size,
593                                   const struct lu_fid *fid,
594                                   const struct lu_buf *buf, const char *name,
595                                   __u32 flag);
596 int update_records_xattr_del_pack(const struct lu_env *env,
597                                   struct update_ops *ops,
598                                   unsigned int *op_count,
599                                   size_t *max_ops_size,
600                                   struct update_params *params,
601                                   unsigned int *param_count,
602                                   size_t *max_param_size,
603                                   const struct lu_fid *fid,
604                                   const char *name);
605 int update_records_write_pack(const struct lu_env *env,
606                               struct update_ops *ops,
607                               unsigned int *op_count,
608                               size_t *max_ops_size,
609                               struct update_params *params,
610                               unsigned int *param_count,
611                               size_t *max_param_size,
612                               const struct lu_fid *fid,
613                               const struct lu_buf *buf,
614                               __u64 pos);
615 int update_records_punch_pack(const struct lu_env *env,
616                               struct update_ops *ops,
617                               unsigned int *op_count,
618                               size_t *max_ops_size,
619                               struct update_params *params,
620                               unsigned int *param_count,
621                               size_t *max_param_size,
622                               const struct lu_fid *fid,
623                               __u64 start, __u64 end);
624 int update_records_noop_pack(const struct lu_env *env,
625                              struct update_ops *ops,
626                              unsigned int *op_count,
627                              size_t *max_ops_size,
628                              struct update_params *params,
629                              unsigned int *param_count,
630                              size_t *max_param_size,
631                              const struct lu_fid *fid);
632
633 int tur_update_records_extend(struct thandle_update_records *tur,
634                               size_t new_size);
635 int tur_update_params_extend(struct thandle_update_records *tur,
636                              size_t new_size);
637 int tur_update_extend(struct thandle_update_records *tur,
638                       size_t new_op_size, size_t new_param_size);
639
640 #define update_record_pack(name, th, ...)                               \
641 ({                                                                      \
642         struct top_thandle *top_th;                                     \
643         struct top_multiple_thandle *tmt;                               \
644         struct thandle_update_records *tur;                             \
645         struct llog_update_record     *lur;                             \
646         size_t          avail_param_size;                               \
647         size_t          avail_op_size;                                  \
648         int             ret;                                            \
649                                                                         \
650         while (1) {                                                     \
651                 top_th = container_of(th, struct top_thandle, tt_super);\
652                 tmt = top_th->tt_multiple_thandle;                      \
653                 tur = tmt->tmt_update_records;                          \
654                 lur = tur->tur_update_records;                          \
655                 avail_param_size = tur->tur_update_params_buf_size -    \
656                              update_params_size(tur->tur_update_params, \
657                                         tur->tur_update_param_count);   \
658                 avail_op_size = tur->tur_update_records_buf_size -      \
659                                 llog_update_record_size(lur);           \
660                 ret = update_records_##name##_pack(env,                 \
661                                           &lur->lur_update_rec.ur_ops,  \
662                                   &lur->lur_update_rec.ur_update_count, \
663                                   &avail_op_size,                       \
664                                   tur->tur_update_params,               \
665                                   &tur->tur_update_param_count,         \
666                                   &avail_param_size, __VA_ARGS__);      \
667                 if (ret == -E2BIG) {                                    \
668                         ret = tur_update_extend(tur, avail_op_size,     \
669                                                    avail_param_size);   \
670                         if (ret != 0)                                   \
671                                 break;                                  \
672                         continue;                                       \
673                 } else {                                                \
674                         break;                                          \
675                 }                                                       \
676         }                                                               \
677         ret;                                                            \
678 })
679
680 #define update_record_size(env, name, th, ...)                          \
681 ({                                                                      \
682         struct top_thandle *top_th;                                     \
683         struct top_multiple_thandle *tmt;                               \
684                                                                         \
685         top_th = container_of(th, struct top_thandle, tt_super);        \
686                                                                         \
687         LASSERT(top_th->tt_multiple_thandle != NULL);                   \
688         tmt = top_th->tt_multiple_thandle;                              \
689         tmt->tmt_record_size +=                                         \
690                 update_records_##name##_size(env, __VA_ARGS__);         \
691 })
692 #endif