1 /* SPDX-License-Identifier: GPL-2.0 */
4 * Copyright (c) 2013, 2017, Intel Corporation.
8 * This file is part of Lustre, http://www.lustre.org/
10 * Author: Di Wang <di.wang@intel.com>
13 #ifndef _LUSTRE_UPDATE_H
14 #define _LUSTRE_UPDATE_H
15 #include <dt_object.h>
16 #include <lustre_net.h>
17 #include <obj_update.h>
19 #define OUT_UPDATE_REPLY_SIZE 4096
20 #define OUT_BULK_BUFFER_SIZE 4096
24 struct object_update_param;
25 struct llog_update_record;
27 static inline size_t update_params_size(const struct update_params *params,
28 unsigned int param_count)
30 struct object_update_param *param;
31 size_t total_size = sizeof(*params);
34 param = (struct object_update_param *)¶ms->up_params[0];
35 for (i = 0; i < param_count; i++) {
36 size_t size = object_update_param_size(param);
38 param = (struct object_update_param *)((char *)param + size);
45 static inline struct object_update_param *
46 update_params_get_param(const struct update_params *params,
47 unsigned int index, unsigned int param_count)
49 struct object_update_param *param;
52 if (index > param_count)
55 param = (struct object_update_param *)¶ms->up_params[0];
56 for (i = 0; i < index; i++)
57 param = (struct object_update_param *)((char *)param +
58 object_update_param_size(param));
64 update_params_get_param_buf(const struct update_params *params, __u16 index,
65 unsigned int param_count, __u16 *size)
67 struct object_update_param *param;
69 param = update_params_get_param(params, (unsigned int)index,
75 *size = param->oup_len;
77 return param->oup_buf;
81 update_op_size(unsigned int param_count)
83 return offsetof(struct update_op, uop_params_off[param_count]);
86 static inline struct update_op *
87 update_op_next_op(const struct update_op *uop)
89 return (struct update_op *)((char *)uop +
90 update_op_size(uop->uop_param_count));
93 static inline size_t update_ops_size(const struct update_ops *ops,
94 unsigned int update_count)
97 size_t total_size = sizeof(*ops);
100 op = (struct update_op *)&ops->uops_op[0];
101 for (i = 0; i < update_count; i++, op = update_op_next_op(op))
102 total_size += update_op_size(op->uop_param_count);
107 static inline struct update_params *
108 update_records_get_params(const struct update_records *record)
110 return (struct update_params *)((char *)record +
111 offsetof(struct update_records, ur_ops) +
112 update_ops_size(&record->ur_ops, record->ur_update_count));
115 static inline struct update_param *
116 update_param_next_param(const struct update_param *param)
118 return (struct update_param *)((char *)param +
119 object_update_param_size(
120 (struct object_update_param *)param));
124 __update_records_size(size_t raw_size)
126 return round_up(offsetof(struct update_records, ur_ops) + raw_size, 8);
130 update_records_size(const struct update_records *record)
133 size_t param_size = 0;
135 if (record->ur_update_count > 0)
136 op_size = update_ops_size(&record->ur_ops,
137 record->ur_update_count);
138 if (record->ur_param_count > 0) {
139 struct update_params *params;
141 params = update_records_get_params(record);
142 param_size = update_params_size(params, record->ur_param_count);
145 return __update_records_size(op_size + param_size);
149 __llog_update_record_size(size_t records_size)
151 return round_up(sizeof(struct llog_rec_hdr) + records_size +
152 sizeof(struct llog_rec_tail), 8);
156 llog_update_record_size(const struct llog_update_record *lur)
158 return __llog_update_record_size(
159 update_records_size(&lur->lur_update_rec));
162 static inline struct update_op *
163 update_ops_get_op(const struct update_ops *ops, unsigned int index,
164 unsigned int update_count)
166 struct update_op *op;
169 if (index > update_count)
172 op = (struct update_op *)&ops->uops_op[0];
173 for (i = 0; i < index; i++)
174 op = update_op_next_op(op);
180 *object_update_param_get(const struct object_update *update, size_t index,
183 const struct object_update_param *param;
186 if (index >= update->ou_params_count)
187 return ERR_PTR(-EINVAL);
189 param = &update->ou_params[0];
190 for (i = 0; i < index; i++)
191 param = (struct object_update_param *)((char *)param +
192 object_update_param_size(param));
195 *size = param->oup_len;
197 if (param->oup_len == 0)
198 return ERR_PTR(-ENODATA);
200 return (void *)¶m->oup_buf[0];
203 static inline unsigned long
204 object_update_request_size(const struct object_update_request *our)
209 size = offsetof(struct object_update_request, ourq_updates[0]);
210 for (i = 0; i < our->ourq_count; i++) {
211 struct object_update *update;
213 update = (struct object_update *)((char *)our + size);
214 size += object_update_size(update);
220 object_update_result_insert(struct object_update_reply *reply,
221 void *data, size_t data_len, size_t index,
224 struct object_update_result *update_result;
226 update_result = object_update_result_get(reply, index, NULL);
227 LASSERT(update_result);
229 update_result->our_rc = ptlrpc_status_hton(rc);
231 if (data_len > 0 && data)
232 memcpy(update_result->our_data, data, data_len);
233 update_result->our_datalen = data_len;
236 reply->ourp_lens[index] = round_up(data_len +
237 sizeof(struct object_update_result),
242 object_update_result_data_get(const struct object_update_reply *reply,
243 struct lu_buf *lbuf, size_t index)
245 struct object_update_result *update_result;
249 LASSERT(lbuf != NULL);
250 update_result = object_update_result_get(reply, index, &size);
251 if (update_result == NULL ||
252 size < round_up(sizeof(struct object_update_reply), 8) ||
253 update_result->our_datalen > size)
256 result = ptlrpc_status_ntoh(update_result->our_rc);
260 lbuf->lb_buf = update_result->our_data;
261 lbuf->lb_len = update_result->our_datalen;
267 * Attached in the thandle to record the updates for distribute
270 struct thandle_update_records {
271 /* All of updates for the cross-MDT operation, vmalloc'd. */
272 struct llog_update_record *tur_update_records;
273 size_t tur_update_records_buf_size;
275 /* All of parameters for the cross-MDT operation, vmalloc'd */
276 struct update_params *tur_update_params;
277 unsigned int tur_update_param_count;
278 size_t tur_update_params_buf_size;
281 #define TOP_THANDLE_MAGIC 0x20140917
282 struct top_multiple_thandle {
283 struct dt_device *tmt_master_sub_dt;
284 struct kref tmt_refcount;
285 /* Other sub transactions will be listed here. */
286 struct list_head tmt_sub_thandle_list;
287 spinlock_t tmt_sub_lock;
289 struct list_head tmt_commit_list;
290 /* All of update records will packed here */
291 struct thandle_update_records *tmt_update_records;
293 wait_queue_head_t tmt_stop_waitq;
297 size_t tmt_record_size;
298 __u32 tmt_committed:1;
301 /* {top,sub}_thandle are used to manage distributed transactions which
302 * include updates on several nodes. A top_handle represents the
303 * whole operation, and sub_thandle represents updates on each node.
306 struct thandle tt_super;
307 /* The master sub transaction. */
308 struct thandle *tt_master_sub_thandle;
310 struct top_multiple_thandle *tt_multiple_thandle;
313 struct sub_thandle_cookie {
314 struct llog_cookie stc_cookie;
315 struct list_head stc_list;
318 /* Sub thandle used to track multiple sub thandles under one parent thandle */
320 struct thandle *st_sub_th;
321 struct dt_device *st_dt;
322 struct list_head st_cookie_list;
323 struct dt_txn_commit_cb st_commit_dcb;
324 struct dt_txn_commit_cb st_stop_dcb;
327 /* linked to top_thandle */
328 struct list_head st_sub_list;
330 /* If this sub thandle is committed */
337 typedef int (*tx_exec_func_t)(const struct lu_env *env, struct thandle *th,
340 /* Structure for holding one update execution */
342 tx_exec_func_t exec_fn;
343 tx_exec_func_t undo_fn;
344 struct dt_object *object;
346 struct object_update_reply *reply;
351 struct dt_insert_rec rec;
352 const struct dt_key *key;
367 struct dt_allocation_hint hint;
368 struct dt_object_format dof;
376 struct ost_body *body;
381 /* Structure for holding all update executations of one transaction */
382 struct thandle_exec_args {
383 struct thandle *ta_handle;
384 int ta_argno; /* used args */
385 int ta_alloc_args; /* allocated args count */
386 struct tx_arg **ta_args;
389 /* target/out_lib.c */
390 int out_update_pack(const struct lu_env *env, struct object_update *update,
391 size_t *max_update_size, enum update_type op,
392 const struct lu_fid *fid, unsigned int params_count,
393 __u16 *param_sizes, const void **param_bufs,
395 int out_create_pack(const struct lu_env *env, struct object_update *update,
396 size_t *max_update_size, const struct lu_fid *fid,
397 const struct lu_attr *attr, struct dt_allocation_hint *hint,
398 struct dt_object_format *dof);
399 int out_destroy_pack(const struct lu_env *env, struct object_update *update,
400 size_t *max_update_size, const struct lu_fid *fid);
401 int out_index_delete_pack(const struct lu_env *env,
402 struct object_update *update, size_t *max_update_size,
403 const struct lu_fid *fid, const struct dt_key *key);
404 int out_index_insert_pack(const struct lu_env *env,
405 struct object_update *update, size_t *max_update_size,
406 const struct lu_fid *fid, const struct dt_rec *rec,
407 const struct dt_key *key);
408 int out_xattr_set_pack(const struct lu_env *env,
409 struct object_update *update, size_t *max_update_size,
410 const struct lu_fid *fid, const struct lu_buf *buf,
411 const char *name, __u32 flag);
412 int out_xattr_del_pack(const struct lu_env *env,
413 struct object_update *update, size_t *max_update_size,
414 const struct lu_fid *fid, const char *name);
415 int out_attr_set_pack(const struct lu_env *env,
416 struct object_update *update, size_t *max_update_size,
417 const struct lu_fid *fid, const struct lu_attr *attr);
418 int out_ref_add_pack(const struct lu_env *env,
419 struct object_update *update, size_t *max_update_size,
420 const struct lu_fid *fid);
421 int out_ref_del_pack(const struct lu_env *env,
422 struct object_update *update, size_t *max_update_size,
423 const struct lu_fid *fid);
424 int out_write_pack(const struct lu_env *env,
425 struct object_update *update, size_t *max_update_size,
426 const struct lu_fid *fid, const struct lu_buf *buf,
428 int out_attr_get_pack(const struct lu_env *env,
429 struct object_update *update, size_t *max_update_size,
430 const struct lu_fid *fid);
431 int out_index_lookup_pack(const struct lu_env *env,
432 struct object_update *update, size_t *max_update_size,
433 const struct lu_fid *fid, struct dt_rec *rec,
434 const struct dt_key *key);
435 int out_xattr_get_pack(const struct lu_env *env,
436 struct object_update *update, size_t *max_update_size,
437 const struct lu_fid *fid, const char *name,
439 int out_xattr_list_pack(const struct lu_env *env, struct object_update *update,
440 size_t *max_update_size, const struct lu_fid *fid,
442 int out_read_pack(const struct lu_env *env, struct object_update *update,
443 size_t *max_update_length, const struct lu_fid *fid,
444 size_t size, loff_t pos);
446 const char *update_op_str(__u16 opcode);
448 /* target/update_trans.c */
449 struct thandle *thandle_get_sub_by_dt(const struct lu_env *env,
451 struct dt_device *sub_dt);
453 static inline struct thandle *
454 thandle_get_sub(const struct lu_env *env, struct thandle *th,
455 const struct dt_object *sub_obj)
457 return thandle_get_sub_by_dt(env, th, lu2dt_dev(sub_obj->do_lu.lo_dev));
461 top_trans_create(const struct lu_env *env, struct dt_device *master_dev);
462 int top_trans_start(const struct lu_env *env, struct dt_device *master_dev,
464 int top_trans_stop(const struct lu_env *env, struct dt_device *master_dev,
466 void top_multiple_thandle_destroy(struct kref *kref);
468 static inline void top_multiple_thandle_get(struct top_multiple_thandle *tmt)
470 kref_get(&tmt->tmt_refcount);
473 static inline void top_multiple_thandle_put(struct top_multiple_thandle *tmt)
475 kref_put(&tmt->tmt_refcount, top_multiple_thandle_destroy);
478 struct sub_thandle *lookup_sub_thandle(struct top_multiple_thandle *tmt,
479 struct dt_device *dt_dev);
480 int sub_thandle_trans_create(const struct lu_env *env,
481 struct top_thandle *top_th,
482 struct sub_thandle *st);
484 /* update_records.c */
485 size_t update_records_create_size(const struct lu_env *env,
486 const struct lu_fid *fid,
487 const struct lu_attr *attr,
488 const struct dt_allocation_hint *hint,
489 struct dt_object_format *dof);
490 size_t update_records_attr_set_size(const struct lu_env *env,
491 const struct lu_fid *fid,
492 const struct lu_attr *attr);
493 size_t update_records_ref_add_size(const struct lu_env *env,
494 const struct lu_fid *fid);
495 size_t update_records_ref_del_size(const struct lu_env *env,
496 const struct lu_fid *fid);
497 size_t update_records_destroy_size(const struct lu_env *env,
498 const struct lu_fid *fid);
499 size_t update_records_index_insert_size(const struct lu_env *env,
500 const struct lu_fid *fid,
501 const struct dt_rec *rec,
502 const struct dt_key *key);
503 size_t update_records_index_delete_size(const struct lu_env *env,
504 const struct lu_fid *fid,
505 const struct dt_key *key);
506 size_t update_records_xattr_set_size(const struct lu_env *env,
507 const struct lu_fid *fid,
508 const struct lu_buf *buf,
511 size_t update_records_xattr_del_size(const struct lu_env *env,
512 const struct lu_fid *fid,
514 size_t update_records_write_size(const struct lu_env *env,
515 const struct lu_fid *fid,
516 const struct lu_buf *buf,
518 size_t update_records_punch_size(const struct lu_env *env,
519 const struct lu_fid *fid,
520 __u64 start, __u64 end);
522 int update_records_create_pack(const struct lu_env *env,
523 struct update_ops *ops,
524 unsigned int *op_count,
525 size_t *max_ops_size,
526 struct update_params *params,
527 unsigned int *param_count,
528 size_t *max_param_size,
529 const struct lu_fid *fid,
530 const struct lu_attr *attr,
531 const struct dt_allocation_hint *hint,
532 struct dt_object_format *dof);
533 int update_records_attr_set_pack(const struct lu_env *env,
534 struct update_ops *ops,
535 unsigned int *op_count,
536 size_t *max_ops_size,
537 struct update_params *params,
538 unsigned int *param_count,
539 size_t *max_param_size,
540 const struct lu_fid *fid,
541 const struct lu_attr *attr);
542 int update_records_ref_add_pack(const struct lu_env *env,
543 struct update_ops *ops,
544 unsigned int *op_count,
545 size_t *max_ops_size,
546 struct update_params *params,
547 unsigned int *param_count,
548 size_t *max_param_size,
549 const struct lu_fid *fid);
550 int update_records_ref_del_pack(const struct lu_env *env,
551 struct update_ops *ops,
552 unsigned int *op_count,
553 size_t *max_ops_size,
554 struct update_params *params,
555 unsigned int *param_count,
556 size_t *max_param_size,
557 const struct lu_fid *fid);
558 int update_records_destroy_pack(const struct lu_env *env,
559 struct update_ops *ops, unsigned int *op_count,
560 size_t *max_ops_size,
561 struct update_params *params,
562 unsigned int *param_count,
563 size_t *max_param_size,
564 const struct lu_fid *fid);
565 int update_records_index_insert_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 const struct dt_rec *rec,
574 const struct dt_key *key);
575 int update_records_index_delete_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 const struct dt_key *key);
584 int update_records_xattr_set_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 lu_buf *buf, const char *name,
594 int update_records_xattr_del_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,
603 int update_records_write_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,
613 int update_records_punch_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 __u64 start, __u64 end);
622 int update_records_noop_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);
631 int tur_update_records_extend(struct thandle_update_records *tur,
633 int tur_update_params_extend(struct thandle_update_records *tur,
635 int tur_update_extend(struct thandle_update_records *tur,
636 size_t new_op_size, size_t new_param_size);
638 #define update_record_pack(name, th, ...) \
640 struct top_thandle *top_th; \
641 struct top_multiple_thandle *tmt; \
642 struct thandle_update_records *tur; \
643 struct llog_update_record *lur; \
644 size_t avail_param_size; \
645 size_t avail_op_size; \
649 top_th = container_of(th, struct top_thandle, tt_super);\
650 tmt = top_th->tt_multiple_thandle; \
651 tur = tmt->tmt_update_records; \
652 lur = tur->tur_update_records; \
653 avail_param_size = tur->tur_update_params_buf_size - \
654 update_params_size(tur->tur_update_params, \
655 tur->tur_update_param_count); \
656 avail_op_size = tur->tur_update_records_buf_size - \
657 llog_update_record_size(lur); \
658 ret = update_records_##name##_pack(env, \
659 &lur->lur_update_rec.ur_ops, \
660 &lur->lur_update_rec.ur_update_count, \
662 tur->tur_update_params, \
663 &tur->tur_update_param_count, \
664 &avail_param_size, __VA_ARGS__); \
665 if (ret == -E2BIG) { \
666 ret = tur_update_extend(tur, avail_op_size, \
678 #define update_record_size(env, name, th, ...) \
680 struct top_thandle *top_th; \
681 struct top_multiple_thandle *tmt; \
683 top_th = container_of(th, struct top_thandle, tt_super); \
685 LASSERT(top_th->tt_multiple_thandle != NULL); \
686 tmt = top_th->tt_multiple_thandle; \
687 tmt->tmt_record_size += \
688 update_records_##name##_size(env, __VA_ARGS__); \