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