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