4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
23 * Copyright (c) 2013, 2017, Intel Corporation.
26 * lustre/include/lustre_update.h
28 * Author: Di Wang <di.wang@intel.com>
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>
37 #define OUT_UPDATE_REPLY_SIZE 4096
38 #define OUT_BULK_BUFFER_SIZE 4096
42 struct object_update_param;
43 struct llog_update_record;
45 static inline size_t update_params_size(const struct update_params *params,
46 unsigned int param_count)
48 struct object_update_param *param;
49 size_t total_size = sizeof(*params);
52 param = (struct object_update_param *)¶ms->up_params[0];
53 for (i = 0; i < param_count; i++) {
54 size_t size = object_update_param_size(param);
56 param = (struct object_update_param *)((char *)param + size);
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)
67 struct object_update_param *param;
70 if (index > param_count)
73 param = (struct object_update_param *)¶ms->up_params[0];
74 for (i = 0; i < index; i++)
75 param = (struct object_update_param *)((char *)param +
76 object_update_param_size(param));
82 update_params_get_param_buf(const struct update_params *params, __u16 index,
83 unsigned int param_count, __u16 *size)
85 struct object_update_param *param;
87 param = update_params_get_param(params, (unsigned int)index,
93 *size = param->oup_len;
95 return param->oup_buf;
99 update_op_size(unsigned int param_count)
101 return offsetof(struct update_op, uop_params_off[param_count]);
104 static inline struct update_op *
105 update_op_next_op(const struct update_op *uop)
107 return (struct update_op *)((char *)uop +
108 update_op_size(uop->uop_param_count));
111 static inline size_t update_ops_size(const struct update_ops *ops,
112 unsigned int update_count)
114 struct update_op *op;
115 size_t total_size = sizeof(*ops);
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);
125 static inline struct update_params *
126 update_records_get_params(const struct update_records *record)
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));
133 static inline struct update_param *
134 update_param_next_param(const struct update_param *param)
136 return (struct update_param *)((char *)param +
137 object_update_param_size(
138 (struct object_update_param *)param));
142 __update_records_size(size_t raw_size)
144 return round_up(offsetof(struct update_records, ur_ops) + raw_size, 8);
148 update_records_size(const struct update_records *record)
151 size_t param_size = 0;
153 if (record->ur_update_count > 0)
154 op_size = update_ops_size(&record->ur_ops,
155 record->ur_update_count);
156 if (record->ur_param_count > 0) {
157 struct update_params *params;
159 params = update_records_get_params(record);
160 param_size = update_params_size(params, record->ur_param_count);
163 return __update_records_size(op_size + param_size);
167 __llog_update_record_size(size_t records_size)
169 return round_up(sizeof(struct llog_rec_hdr) + records_size +
170 sizeof(struct llog_rec_tail), 8);
174 llog_update_record_size(const struct llog_update_record *lur)
176 return __llog_update_record_size(
177 update_records_size(&lur->lur_update_rec));
180 static inline struct update_op *
181 update_ops_get_op(const struct update_ops *ops, unsigned int index,
182 unsigned int update_count)
184 struct update_op *op;
187 if (index > update_count)
190 op = (struct update_op *)&ops->uops_op[0];
191 for (i = 0; i < index; i++)
192 op = update_op_next_op(op);
198 *object_update_param_get(const struct object_update *update, size_t index,
201 const struct object_update_param *param;
204 if (index >= update->ou_params_count)
205 return ERR_PTR(-EINVAL);
207 param = &update->ou_params[0];
208 for (i = 0; i < index; i++)
209 param = (struct object_update_param *)((char *)param +
210 object_update_param_size(param));
213 *size = param->oup_len;
215 if (param->oup_len == 0)
216 return ERR_PTR(-ENODATA);
218 return (void *)¶m->oup_buf[0];
221 static inline unsigned long
222 object_update_request_size(const struct object_update_request *our)
227 size = offsetof(struct object_update_request, ourq_updates[0]);
228 for (i = 0; i < our->ourq_count; i++) {
229 struct object_update *update;
231 update = (struct object_update *)((char *)our + size);
232 size += object_update_size(update);
238 object_update_result_insert(struct object_update_reply *reply,
239 void *data, size_t data_len, size_t index,
242 struct object_update_result *update_result;
244 update_result = object_update_result_get(reply, index, NULL);
245 LASSERT(update_result);
247 update_result->our_rc = ptlrpc_status_hton(rc);
249 if (data_len > 0 && data)
250 memcpy(update_result->our_data, data, data_len);
251 update_result->our_datalen = data_len;
254 reply->ourp_lens[index] = round_up(data_len +
255 sizeof(struct object_update_result),
260 object_update_result_data_get(const struct object_update_reply *reply,
261 struct lu_buf *lbuf, size_t index)
263 struct object_update_result *update_result;
267 LASSERT(lbuf != NULL);
268 update_result = object_update_result_get(reply, index, &size);
269 if (update_result == NULL ||
270 size < round_up(sizeof(struct object_update_reply), 8) ||
271 update_result->our_datalen > size)
274 result = ptlrpc_status_ntoh(update_result->our_rc);
278 lbuf->lb_buf = update_result->our_data;
279 lbuf->lb_len = update_result->our_datalen;
285 * Attached in the thandle to record the updates for distribute
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;
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;
299 #define TOP_THANDLE_MAGIC 0x20140917
300 struct top_multiple_thandle {
301 struct dt_device *tmt_master_sub_dt;
302 struct kref tmt_refcount;
303 /* Other sub transactions will be listed here. */
304 struct list_head tmt_sub_thandle_list;
305 spinlock_t tmt_sub_lock;
307 struct list_head tmt_commit_list;
308 /* All of update records will packed here */
309 struct thandle_update_records *tmt_update_records;
311 wait_queue_head_t tmt_stop_waitq;
315 size_t tmt_record_size;
316 __u32 tmt_committed:1;
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.
324 struct thandle tt_super;
325 /* The master sub transaction. */
326 struct thandle *tt_master_sub_thandle;
328 struct top_multiple_thandle *tt_multiple_thandle;
331 struct sub_thandle_cookie {
332 struct llog_cookie stc_cookie;
333 struct list_head stc_list;
336 /* Sub thandle used to track multiple sub thandles under one parent 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;
345 /* linked to top_thandle */
346 struct list_head st_sub_list;
348 /* If this sub thandle is committed */
355 typedef int (*tx_exec_func_t)(const struct lu_env *env, struct thandle *th,
358 /* Structure for holding one update execution */
360 tx_exec_func_t exec_fn;
361 tx_exec_func_t undo_fn;
362 struct dt_object *object;
364 struct object_update_reply *reply;
369 struct dt_insert_rec rec;
370 const struct dt_key *key;
385 struct dt_allocation_hint hint;
386 struct dt_object_format dof;
394 struct ost_body *body;
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;
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,
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,
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,
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,
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);
464 const char *update_op_str(__u16 opcode);
466 /* target/update_trans.c */
467 struct thandle *thandle_get_sub_by_dt(const struct lu_env *env,
469 struct dt_device *sub_dt);
471 static inline struct thandle *
472 thandle_get_sub(const struct lu_env *env, struct thandle *th,
473 const struct dt_object *sub_obj)
475 return thandle_get_sub_by_dt(env, th, lu2dt_dev(sub_obj->do_lu.lo_dev));
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,
482 int top_trans_stop(const struct lu_env *env, struct dt_device *master_dev,
484 void top_multiple_thandle_destroy(struct kref *kref);
486 static inline void top_multiple_thandle_get(struct top_multiple_thandle *tmt)
488 kref_get(&tmt->tmt_refcount);
491 static inline void top_multiple_thandle_put(struct top_multiple_thandle *tmt)
493 kref_put(&tmt->tmt_refcount, top_multiple_thandle_destroy);
496 struct sub_thandle *lookup_sub_thandle(struct top_multiple_thandle *tmt,
497 struct dt_device *dt_dev);
498 int sub_thandle_trans_create(const struct lu_env *env,
499 struct top_thandle *top_th,
500 struct sub_thandle *st);
502 /* update_records.c */
503 size_t update_records_create_size(const struct lu_env *env,
504 const struct lu_fid *fid,
505 const struct lu_attr *attr,
506 const struct dt_allocation_hint *hint,
507 struct dt_object_format *dof);
508 size_t update_records_attr_set_size(const struct lu_env *env,
509 const struct lu_fid *fid,
510 const struct lu_attr *attr);
511 size_t update_records_ref_add_size(const struct lu_env *env,
512 const struct lu_fid *fid);
513 size_t update_records_ref_del_size(const struct lu_env *env,
514 const struct lu_fid *fid);
515 size_t update_records_destroy_size(const struct lu_env *env,
516 const struct lu_fid *fid);
517 size_t update_records_index_insert_size(const struct lu_env *env,
518 const struct lu_fid *fid,
519 const struct dt_rec *rec,
520 const struct dt_key *key);
521 size_t update_records_index_delete_size(const struct lu_env *env,
522 const struct lu_fid *fid,
523 const struct dt_key *key);
524 size_t update_records_xattr_set_size(const struct lu_env *env,
525 const struct lu_fid *fid,
526 const struct lu_buf *buf,
529 size_t update_records_xattr_del_size(const struct lu_env *env,
530 const struct lu_fid *fid,
532 size_t update_records_write_size(const struct lu_env *env,
533 const struct lu_fid *fid,
534 const struct lu_buf *buf,
536 size_t update_records_punch_size(const struct lu_env *env,
537 const struct lu_fid *fid,
538 __u64 start, __u64 end);
540 int update_records_create_pack(const struct lu_env *env,
541 struct update_ops *ops,
542 unsigned int *op_count,
543 size_t *max_ops_size,
544 struct update_params *params,
545 unsigned int *param_count,
546 size_t *max_param_size,
547 const struct lu_fid *fid,
548 const struct lu_attr *attr,
549 const struct dt_allocation_hint *hint,
550 struct dt_object_format *dof);
551 int update_records_attr_set_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 const struct lu_attr *attr);
560 int update_records_ref_add_pack(const struct lu_env *env,
561 struct update_ops *ops,
562 unsigned int *op_count,
563 size_t *max_ops_size,
564 struct update_params *params,
565 unsigned int *param_count,
566 size_t *max_param_size,
567 const struct lu_fid *fid);
568 int update_records_ref_del_pack(const struct lu_env *env,
569 struct update_ops *ops,
570 unsigned int *op_count,
571 size_t *max_ops_size,
572 struct update_params *params,
573 unsigned int *param_count,
574 size_t *max_param_size,
575 const struct lu_fid *fid);
576 int update_records_destroy_pack(const struct lu_env *env,
577 struct update_ops *ops, unsigned int *op_count,
578 size_t *max_ops_size,
579 struct update_params *params,
580 unsigned int *param_count,
581 size_t *max_param_size,
582 const struct lu_fid *fid);
583 int update_records_index_insert_pack(const struct lu_env *env,
584 struct update_ops *ops,
585 unsigned int *op_count,
586 size_t *max_ops_size,
587 struct update_params *params,
588 unsigned int *param_count,
589 size_t *max_param_size,
590 const struct lu_fid *fid,
591 const struct dt_rec *rec,
592 const struct dt_key *key);
593 int update_records_index_delete_pack(const struct lu_env *env,
594 struct update_ops *ops,
595 unsigned int *op_count,
596 size_t *max_ops_size,
597 struct update_params *params,
598 unsigned int *param_count,
599 size_t *max_param_size,
600 const struct lu_fid *fid,
601 const struct dt_key *key);
602 int update_records_xattr_set_pack(const struct lu_env *env,
603 struct update_ops *ops,
604 unsigned int *op_count,
605 size_t *max_ops_size,
606 struct update_params *params,
607 unsigned int *param_count,
608 size_t *max_param_size,
609 const struct lu_fid *fid,
610 const struct lu_buf *buf, const char *name,
612 int update_records_xattr_del_pack(const struct lu_env *env,
613 struct update_ops *ops,
614 unsigned int *op_count,
615 size_t *max_ops_size,
616 struct update_params *params,
617 unsigned int *param_count,
618 size_t *max_param_size,
619 const struct lu_fid *fid,
621 int update_records_write_pack(const struct lu_env *env,
622 struct update_ops *ops,
623 unsigned int *op_count,
624 size_t *max_ops_size,
625 struct update_params *params,
626 unsigned int *param_count,
627 size_t *max_param_size,
628 const struct lu_fid *fid,
629 const struct lu_buf *buf,
631 int update_records_punch_pack(const struct lu_env *env,
632 struct update_ops *ops,
633 unsigned int *op_count,
634 size_t *max_ops_size,
635 struct update_params *params,
636 unsigned int *param_count,
637 size_t *max_param_size,
638 const struct lu_fid *fid,
639 __u64 start, __u64 end);
640 int update_records_noop_pack(const struct lu_env *env,
641 struct update_ops *ops,
642 unsigned int *op_count,
643 size_t *max_ops_size,
644 struct update_params *params,
645 unsigned int *param_count,
646 size_t *max_param_size,
647 const struct lu_fid *fid);
649 int tur_update_records_extend(struct thandle_update_records *tur,
651 int tur_update_params_extend(struct thandle_update_records *tur,
653 int tur_update_extend(struct thandle_update_records *tur,
654 size_t new_op_size, size_t new_param_size);
656 #define update_record_pack(name, th, ...) \
658 struct top_thandle *top_th; \
659 struct top_multiple_thandle *tmt; \
660 struct thandle_update_records *tur; \
661 struct llog_update_record *lur; \
662 size_t avail_param_size; \
663 size_t avail_op_size; \
667 top_th = container_of(th, struct top_thandle, tt_super);\
668 tmt = top_th->tt_multiple_thandle; \
669 tur = tmt->tmt_update_records; \
670 lur = tur->tur_update_records; \
671 avail_param_size = tur->tur_update_params_buf_size - \
672 update_params_size(tur->tur_update_params, \
673 tur->tur_update_param_count); \
674 avail_op_size = tur->tur_update_records_buf_size - \
675 llog_update_record_size(lur); \
676 ret = update_records_##name##_pack(env, \
677 &lur->lur_update_rec.ur_ops, \
678 &lur->lur_update_rec.ur_update_count, \
680 tur->tur_update_params, \
681 &tur->tur_update_param_count, \
682 &avail_param_size, __VA_ARGS__); \
683 if (ret == -E2BIG) { \
684 ret = tur_update_extend(tur, avail_op_size, \
696 #define update_record_size(env, name, th, ...) \
698 struct top_thandle *top_th; \
699 struct top_multiple_thandle *tmt; \
701 top_th = container_of(th, struct top_thandle, tt_super); \
703 LASSERT(top_th->tt_multiple_thandle != NULL); \
704 tmt = top_th->tt_multiple_thandle; \
705 tmt->tmt_record_size += \
706 update_records_##name##_size(env, __VA_ARGS__); \