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, 2016, 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_INIT_BUFFER_SIZE 4096
38 #define OUT_UPDATE_REPLY_SIZE 4096
39 #define OUT_BULK_BUFFER_SIZE 4096
43 struct object_update_param;
44 struct llog_update_record;
46 static inline size_t update_params_size(const struct update_params *params,
47 unsigned int param_count)
49 struct object_update_param *param;
50 size_t total_size = sizeof(*params);
53 param = (struct object_update_param *)¶ms->up_params[0];
54 for (i = 0; i < param_count; i++) {
55 size_t size = object_update_param_size(param);
57 param = (struct object_update_param *)((char *)param + size);
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)
68 struct object_update_param *param;
71 if (index > param_count)
74 param = (struct object_update_param *)¶ms->up_params[0];
75 for (i = 0; i < index; i++)
76 param = (struct object_update_param *)((char *)param +
77 object_update_param_size(param));
83 update_params_get_param_buf(const struct update_params *params, __u16 index,
84 unsigned int param_count, __u16 *size)
86 struct object_update_param *param;
88 param = update_params_get_param(params, (unsigned int)index,
94 *size = param->oup_len;
96 return param->oup_buf;
100 update_op_size(unsigned int param_count)
102 return offsetof(struct update_op, uop_params_off[param_count]);
105 static inline struct update_op *
106 update_op_next_op(const struct update_op *uop)
108 return (struct update_op *)((char *)uop +
109 update_op_size(uop->uop_param_count));
112 static inline size_t update_ops_size(const struct update_ops *ops,
113 unsigned int update_count)
115 struct update_op *op;
116 size_t total_size = sizeof(*ops);
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);
126 static inline struct update_params *
127 update_records_get_params(const struct update_records *record)
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));
134 static inline struct update_param *
135 update_param_next_param(const struct update_param *param)
137 return (struct update_param *)((char *)param +
138 object_update_param_size(
139 (struct object_update_param *)param));
143 __update_records_size(size_t raw_size)
145 return cfs_size_round(offsetof(struct update_records, ur_ops) +
150 update_records_size(const struct update_records *record)
153 size_t param_size = 0;
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;
161 params = update_records_get_params(record);
162 param_size = update_params_size(params, record->ur_param_count);
165 return __update_records_size(op_size + param_size);
169 __llog_update_record_size(size_t records_size)
171 return cfs_size_round(sizeof(struct llog_rec_hdr) + records_size +
172 sizeof(struct llog_rec_tail));
176 llog_update_record_size(const struct llog_update_record *lur)
178 return __llog_update_record_size(
179 update_records_size(&lur->lur_update_rec));
182 static inline struct update_op *
183 update_ops_get_op(const struct update_ops *ops, unsigned int index,
184 unsigned int update_count)
186 struct update_op *op;
189 if (index > update_count)
192 op = (struct update_op *)&ops->uops_op[0];
193 for (i = 0; i < index; i++)
194 op = update_op_next_op(op);
200 *object_update_param_get(const struct object_update *update, size_t index,
203 const struct object_update_param *param;
206 if (index >= update->ou_params_count)
207 return ERR_PTR(-EINVAL);
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));
215 *size = param->oup_len;
217 if (param->oup_len == 0)
218 return ERR_PTR(-ENODATA);
220 return (void *)¶m->oup_buf[0];
223 static inline unsigned long
224 object_update_request_size(const struct object_update_request *our)
229 size = offsetof(struct object_update_request, ourq_updates[0]);
230 for (i = 0; i < our->ourq_count; i++) {
231 struct object_update *update;
233 update = (struct object_update *)((char *)our + size);
234 size += object_update_size(update);
240 object_update_result_insert(struct object_update_reply *reply,
241 void *data, size_t data_len, size_t index,
244 struct object_update_result *update_result;
247 update_result = object_update_result_get(reply, index, NULL);
248 LASSERT(update_result);
250 update_result->our_rc = ptlrpc_status_hton(rc);
255 ptr = (char *)update_result +
256 cfs_size_round(sizeof(struct object_update_reply));
257 memcpy(ptr, data, data_len);
259 update_result->our_datalen = data_len;
262 reply->ourp_lens[index] = cfs_size_round(data_len +
263 sizeof(struct object_update_result));
267 object_update_result_data_get(const struct object_update_reply *reply,
268 struct lu_buf *lbuf, size_t index)
270 struct object_update_result *update_result;
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)
281 result = ptlrpc_status_ntoh(update_result->our_rc);
285 lbuf->lb_buf = update_result->our_data;
286 lbuf->lb_len = update_result->our_datalen;
292 * Attached in the thandle to record the updates for distribute
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;
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;
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;
314 struct list_head tmt_commit_list;
315 /* All of update records will packed here */
316 struct thandle_update_records *tmt_update_records;
318 wait_queue_head_t tmt_stop_waitq;
322 size_t tmt_record_size;
323 __u32 tmt_committed:1;
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. */
330 struct thandle tt_super;
331 /* The master sub transaction. */
332 struct thandle *tt_master_sub_thandle;
334 struct top_multiple_thandle *tt_multiple_thandle;
337 struct sub_thandle_cookie {
338 struct llog_cookie stc_cookie;
339 struct list_head stc_list;
342 /* Sub thandle is used to track multiple sub thandles under one parent
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;
352 /* linked to top_thandle */
353 struct list_head st_sub_list;
355 /* If this sub thandle is committed */
362 typedef int (*tx_exec_func_t)(const struct lu_env *env, struct thandle *th,
365 /* Structure for holding one update execution */
367 tx_exec_func_t exec_fn;
368 tx_exec_func_t undo_fn;
369 struct dt_object *object;
371 struct object_update_reply *reply;
376 struct dt_insert_rec rec;
377 const struct dt_key *key;
392 struct dt_allocation_hint hint;
393 struct dt_object_format dof;
401 struct ost_body *body;
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;
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,
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_object_destroy_pack(const struct lu_env *env,
425 struct object_update *update,
426 size_t *max_update_size,
427 const struct lu_fid *fid);
428 int out_index_delete_pack(const struct lu_env *env,
429 struct object_update *update, size_t *max_update_size,
430 const struct lu_fid *fid, const struct dt_key *key);
431 int out_index_insert_pack(const struct lu_env *env,
432 struct object_update *update, size_t *max_update_size,
433 const struct lu_fid *fid, const struct dt_rec *rec,
434 const struct dt_key *key);
435 int out_xattr_set_pack(const struct lu_env *env,
436 struct object_update *update, size_t *max_update_size,
437 const struct lu_fid *fid, const struct lu_buf *buf,
438 const char *name, __u32 flag);
439 int out_xattr_del_pack(const struct lu_env *env,
440 struct object_update *update, size_t *max_update_size,
441 const struct lu_fid *fid, const char *name);
442 int out_attr_set_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_attr *attr);
445 int out_ref_add_pack(const struct lu_env *env,
446 struct object_update *update, size_t *max_update_size,
447 const struct lu_fid *fid);
448 int out_ref_del_pack(const struct lu_env *env,
449 struct object_update *update, size_t *max_update_size,
450 const struct lu_fid *fid);
451 int out_write_pack(const struct lu_env *env,
452 struct object_update *update, size_t *max_update_size,
453 const struct lu_fid *fid, const struct lu_buf *buf,
455 int out_attr_get_pack(const struct lu_env *env,
456 struct object_update *update, size_t *max_update_size,
457 const struct lu_fid *fid);
458 int out_index_lookup_pack(const struct lu_env *env,
459 struct object_update *update, size_t *max_update_size,
460 const struct lu_fid *fid, struct dt_rec *rec,
461 const struct dt_key *key);
462 int out_xattr_get_pack(const struct lu_env *env,
463 struct object_update *update, size_t *max_update_size,
464 const struct lu_fid *fid, const char *name,
466 int out_read_pack(const struct lu_env *env, struct object_update *update,
467 size_t *max_update_length, const struct lu_fid *fid,
468 size_t size, loff_t pos);
470 const char *update_op_str(__u16 opcode);
472 /* target/update_trans.c */
473 struct thandle *thandle_get_sub_by_dt(const struct lu_env *env,
475 struct dt_device *sub_dt);
477 static inline struct thandle *
478 thandle_get_sub(const struct lu_env *env, struct thandle *th,
479 const struct dt_object *sub_obj)
481 return thandle_get_sub_by_dt(env, th, lu2dt_dev(sub_obj->do_lu.lo_dev));
485 top_trans_create(const struct lu_env *env, struct dt_device *master_dev);
486 int top_trans_start(const struct lu_env *env, struct dt_device *master_dev,
488 int top_trans_stop(const struct lu_env *env, struct dt_device *master_dev,
490 void top_multiple_thandle_destroy(struct top_multiple_thandle *tmt);
492 static inline void top_multiple_thandle_get(struct top_multiple_thandle *tmt)
494 atomic_inc(&tmt->tmt_refcount);
497 static inline void top_multiple_thandle_put(struct top_multiple_thandle *tmt)
499 if (atomic_dec_and_test(&tmt->tmt_refcount))
500 top_multiple_thandle_destroy(tmt);
503 struct sub_thandle *lookup_sub_thandle(struct top_multiple_thandle *tmt,
504 struct dt_device *dt_dev);
505 int sub_thandle_trans_create(const struct lu_env *env,
506 struct top_thandle *top_th,
507 struct sub_thandle *st);
509 /* update_records.c */
510 size_t update_records_create_size(const struct lu_env *env,
511 const struct lu_fid *fid,
512 const struct lu_attr *attr,
513 const struct dt_allocation_hint *hint,
514 struct dt_object_format *dof);
515 size_t update_records_attr_set_size(const struct lu_env *env,
516 const struct lu_fid *fid,
517 const struct lu_attr *attr);
518 size_t update_records_ref_add_size(const struct lu_env *env,
519 const struct lu_fid *fid);
520 size_t update_records_ref_del_size(const struct lu_env *env,
521 const struct lu_fid *fid);
522 size_t update_records_object_destroy_size(const struct lu_env *env,
523 const struct lu_fid *fid);
524 size_t update_records_index_insert_size(const struct lu_env *env,
525 const struct lu_fid *fid,
526 const struct dt_rec *rec,
527 const struct dt_key *key);
528 size_t update_records_index_delete_size(const struct lu_env *env,
529 const struct lu_fid *fid,
530 const struct dt_key *key);
531 size_t update_records_xattr_set_size(const struct lu_env *env,
532 const struct lu_fid *fid,
533 const struct lu_buf *buf,
536 size_t update_records_xattr_del_size(const struct lu_env *env,
537 const struct lu_fid *fid,
539 size_t update_records_write_size(const struct lu_env *env,
540 const struct lu_fid *fid,
541 const struct lu_buf *buf,
543 size_t update_records_punch_size(const struct lu_env *env,
544 const struct lu_fid *fid,
545 __u64 start, __u64 end);
547 int update_records_create_pack(const struct lu_env *env,
548 struct update_ops *ops,
549 unsigned int *op_count,
550 size_t *max_ops_size,
551 struct update_params *params,
552 unsigned int *param_count,
553 size_t *max_param_size,
554 const struct lu_fid *fid,
555 const struct lu_attr *attr,
556 const struct dt_allocation_hint *hint,
557 struct dt_object_format *dof);
558 int update_records_attr_set_pack(const struct lu_env *env,
559 struct update_ops *ops,
560 unsigned int *op_count,
561 size_t *max_ops_size,
562 struct update_params *params,
563 unsigned int *param_count,
564 size_t *max_param_size,
565 const struct lu_fid *fid,
566 const struct lu_attr *attr);
567 int update_records_ref_add_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 int update_records_ref_del_pack(const struct lu_env *env,
576 struct update_ops *ops,
577 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_object_destroy_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 int update_records_index_insert_pack(const struct lu_env *env,
592 struct update_ops *ops,
593 unsigned int *op_count,
594 size_t *max_ops_size,
595 struct update_params *params,
596 unsigned int *param_count,
597 size_t *max_param_size,
598 const struct lu_fid *fid,
599 const struct dt_rec *rec,
600 const struct dt_key *key);
601 int update_records_index_delete_pack(const struct lu_env *env,
602 struct update_ops *ops,
603 unsigned int *op_count,
604 size_t *max_ops_size,
605 struct update_params *params,
606 unsigned int *param_count,
607 size_t *max_param_size,
608 const struct lu_fid *fid,
609 const struct dt_key *key);
610 int update_records_xattr_set_pack(const struct lu_env *env,
611 struct update_ops *ops,
612 unsigned int *op_count,
613 size_t *max_ops_size,
614 struct update_params *params,
615 unsigned int *param_count,
616 size_t *max_param_size,
617 const struct lu_fid *fid,
618 const struct lu_buf *buf, const char *name,
620 int update_records_xattr_del_pack(const struct lu_env *env,
621 struct update_ops *ops,
622 unsigned int *op_count,
623 size_t *max_ops_size,
624 struct update_params *params,
625 unsigned int *param_count,
626 size_t *max_param_size,
627 const struct lu_fid *fid,
629 int update_records_write_pack(const struct lu_env *env,
630 struct update_ops *ops,
631 unsigned int *op_count,
632 size_t *max_ops_size,
633 struct update_params *params,
634 unsigned int *param_count,
635 size_t *max_param_size,
636 const struct lu_fid *fid,
637 const struct lu_buf *buf,
639 int update_records_punch_pack(const struct lu_env *env,
640 struct update_ops *ops,
641 unsigned int *op_count,
642 size_t *max_ops_size,
643 struct update_params *params,
644 unsigned int *param_count,
645 size_t *max_param_size,
646 const struct lu_fid *fid,
647 __u64 start, __u64 end);
648 int update_records_noop_pack(const struct lu_env *env,
649 struct update_ops *ops,
650 unsigned int *op_count,
651 size_t *max_ops_size,
652 struct update_params *params,
653 unsigned int *param_count,
654 size_t *max_param_size,
655 const struct lu_fid *fid);
657 int tur_update_records_extend(struct thandle_update_records *tur,
659 int tur_update_params_extend(struct thandle_update_records *tur,
661 int tur_update_extend(struct thandle_update_records *tur,
662 size_t new_op_size, size_t new_param_size);
664 #define update_record_pack(name, th, ...) \
666 struct top_thandle *top_th; \
667 struct top_multiple_thandle *tmt; \
668 struct thandle_update_records *tur; \
669 struct llog_update_record *lur; \
670 size_t avail_param_size; \
671 size_t avail_op_size; \
675 top_th = container_of(th, struct top_thandle, tt_super);\
676 tmt = top_th->tt_multiple_thandle; \
677 tur = tmt->tmt_update_records; \
678 lur = tur->tur_update_records; \
679 avail_param_size = tur->tur_update_params_buf_size - \
680 update_params_size(tur->tur_update_params, \
681 tur->tur_update_param_count); \
682 avail_op_size = tur->tur_update_records_buf_size - \
683 llog_update_record_size(lur); \
684 ret = update_records_##name##_pack(env, \
685 &lur->lur_update_rec.ur_ops, \
686 &lur->lur_update_rec.ur_update_count, \
688 tur->tur_update_params, \
689 &tur->tur_update_param_count, \
690 &avail_param_size, __VA_ARGS__); \
691 if (ret == -E2BIG) { \
692 ret = tur_update_extend(tur, avail_op_size, \
704 #define update_record_size(env, name, th, ...) \
706 struct top_thandle *top_th; \
707 struct top_multiple_thandle *tmt; \
709 top_th = container_of(th, struct top_thandle, tt_super); \
711 LASSERT(top_th->tt_multiple_thandle != NULL); \
712 tmt = top_th->tt_multiple_thandle; \
713 tmt->tmt_record_size += \
714 update_records_##name##_size(env, __VA_ARGS__); \