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, 2015, 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 <lustre_net.h>
34 #include <dt_object.h>
36 #define OUT_UPDATE_INIT_BUFFER_SIZE 4096
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));
134 update_records_size(const struct update_records *record)
137 size_t param_size = 0;
139 if (record->ur_update_count > 0)
140 op_size = update_ops_size(&record->ur_ops,
141 record->ur_update_count);
142 if (record->ur_param_count > 0) {
143 struct update_params *params;
145 params = update_records_get_params(record);
146 param_size = update_params_size(params, record->ur_param_count);
149 return cfs_size_round(offsetof(struct update_records, ur_ops) +
150 op_size + param_size);
154 llog_update_record_size(const struct llog_update_record *lur)
156 return cfs_size_round(sizeof(lur->lur_hdr) +
157 update_records_size(&lur->lur_update_rec) +
158 sizeof(struct llog_rec_tail));
161 static inline struct update_op *
162 update_ops_get_op(const struct update_ops *ops, unsigned int index,
163 unsigned int update_count)
165 struct update_op *op;
168 if (index > update_count)
171 op = (struct update_op *)&ops->uops_op[0];
172 for (i = 0; i < index; i++)
173 op = update_op_next_op(op);
179 *object_update_param_get(const struct object_update *update, size_t index,
182 const struct object_update_param *param;
185 if (index >= update->ou_params_count)
186 return ERR_PTR(-EINVAL);
188 param = &update->ou_params[0];
189 for (i = 0; i < index; i++)
190 param = (struct object_update_param *)((char *)param +
191 object_update_param_size(param));
194 *size = param->oup_len;
196 if (param->oup_len == 0)
197 return ERR_PTR(-ENODATA);
199 return (void *)¶m->oup_buf[0];
202 static inline unsigned long
203 object_update_request_size(const struct object_update_request *our)
208 size = offsetof(struct object_update_request, ourq_updates[0]);
209 for (i = 0; i < our->ourq_count; i++) {
210 struct object_update *update;
212 update = (struct object_update *)((char *)our + size);
213 size += object_update_size(update);
219 object_update_result_insert(struct object_update_reply *reply,
220 void *data, size_t data_len, size_t index,
223 struct object_update_result *update_result;
226 update_result = object_update_result_get(reply, index, NULL);
227 LASSERT(update_result != NULL);
229 update_result->our_rc = ptlrpc_status_hton(rc);
230 if (data != NULL && data_len > 0) {
231 LASSERT(data != NULL);
232 ptr = (char *)update_result +
233 cfs_size_round(sizeof(struct object_update_reply));
234 update_result->our_datalen = data_len;
235 memcpy(ptr, data, data_len);
238 reply->ourp_lens[index] = cfs_size_round(data_len +
239 sizeof(struct object_update_result));
243 object_update_result_data_get(const struct object_update_reply *reply,
244 struct lu_buf *lbuf, size_t index)
246 struct object_update_result *update_result;
250 LASSERT(lbuf != NULL);
251 update_result = object_update_result_get(reply, index, &size);
252 if (update_result == NULL ||
253 size < cfs_size_round(sizeof(struct object_update_reply)) ||
254 update_result->our_datalen > size)
257 result = ptlrpc_status_ntoh(update_result->our_rc);
261 lbuf->lb_buf = update_result->our_data;
262 lbuf->lb_len = update_result->our_datalen;
268 * Attached in the thandle to record the updates for distribute
271 struct thandle_update_records {
272 /* All of updates for the cross-MDT operation, vmalloc'd. */
273 struct llog_update_record *tur_update_records;
274 size_t tur_update_records_buf_size;
276 /* All of parameters for the cross-MDT operation, vmalloc'd */
277 struct update_params *tur_update_params;
278 unsigned int tur_update_param_count;
279 size_t tur_update_params_buf_size;
282 #define TOP_THANDLE_MAGIC 0x20140917
283 struct top_multiple_thandle {
284 struct dt_device *tmt_master_sub_dt;
285 atomic_t tmt_refcount;
286 /* Other sub transactions will be listed here. */
287 struct list_head tmt_sub_thandle_list;
288 spinlock_t tmt_sub_lock;
290 struct list_head tmt_commit_list;
291 /* All of update records will packed here */
292 struct thandle_update_records *tmt_update_records;
294 wait_queue_head_t tmt_stop_waitq;
298 size_t tmt_record_size;
299 __u32 tmt_committed:1;
302 /* {top,sub}_thandle are used to manage distributed transactions which
303 * include updates on several nodes. A top_handle represents the
304 * 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 is used to track multiple sub thandles under one parent
321 struct thandle *st_sub_th;
322 struct dt_device *st_dt;
323 struct list_head st_cookie_list;
324 struct dt_txn_commit_cb st_commit_dcb;
325 struct dt_txn_commit_cb st_stop_dcb;
328 /* linked to top_thandle */
329 struct list_head st_sub_list;
331 /* If this sub thandle is committed */
338 typedef int (*tx_exec_func_t)(const struct lu_env *env, struct thandle *th,
341 /* Structure for holding one update execution */
343 tx_exec_func_t exec_fn;
344 tx_exec_func_t undo_fn;
345 struct dt_object *object;
347 struct object_update_reply *reply;
352 struct dt_insert_rec rec;
353 const struct dt_key *key;
368 struct dt_allocation_hint hint;
369 struct dt_object_format dof;
377 struct ost_body *body;
382 /* Structure for holding all update executations of one transaction */
383 struct thandle_exec_args {
384 struct thandle *ta_handle;
385 int ta_argno; /* used args */
386 int ta_alloc_args; /* allocated args count */
387 struct tx_arg **ta_args;
390 /* target/out_lib.c */
391 int out_update_pack(const struct lu_env *env, struct object_update *update,
392 size_t *max_update_size, enum update_type op,
393 const struct lu_fid *fid, unsigned int params_count,
394 __u16 *param_sizes, const void **param_bufs,
396 int out_create_pack(const struct lu_env *env, struct object_update *update,
397 size_t *max_update_size, const struct lu_fid *fid,
398 const struct lu_attr *attr, struct dt_allocation_hint *hint,
399 struct dt_object_format *dof);
400 int out_object_destroy_pack(const struct lu_env *env,
401 struct object_update *update,
402 size_t *max_update_size,
403 const struct lu_fid *fid);
404 int out_index_delete_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_key *key);
407 int out_index_insert_pack(const struct lu_env *env,
408 struct object_update *update, size_t *max_update_size,
409 const struct lu_fid *fid, const struct dt_rec *rec,
410 const struct dt_key *key);
411 int out_xattr_set_pack(const struct lu_env *env,
412 struct object_update *update, size_t *max_update_size,
413 const struct lu_fid *fid, const struct lu_buf *buf,
414 const char *name, __u32 flag);
415 int out_xattr_del_pack(const struct lu_env *env,
416 struct object_update *update, size_t *max_update_size,
417 const struct lu_fid *fid, const char *name);
418 int out_attr_set_pack(const struct lu_env *env,
419 struct object_update *update, size_t *max_update_size,
420 const struct lu_fid *fid, const struct lu_attr *attr);
421 int out_ref_add_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_ref_del_pack(const struct lu_env *env,
425 struct object_update *update, size_t *max_update_size,
426 const struct lu_fid *fid);
427 int out_write_pack(const struct lu_env *env,
428 struct object_update *update, size_t *max_update_size,
429 const struct lu_fid *fid, const struct lu_buf *buf,
431 int out_attr_get_pack(const struct lu_env *env,
432 struct object_update *update, size_t *max_update_size,
433 const struct lu_fid *fid);
434 int out_index_lookup_pack(const struct lu_env *env,
435 struct object_update *update, size_t *max_update_size,
436 const struct lu_fid *fid, struct dt_rec *rec,
437 const struct dt_key *key);
438 int out_xattr_get_pack(const struct lu_env *env,
439 struct object_update *update, size_t *max_update_size,
440 const struct lu_fid *fid, const char *name,
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 top_multiple_thandle *tmt);
468 static inline void top_multiple_thandle_get(struct top_multiple_thandle *tmt)
470 atomic_inc(&tmt->tmt_refcount);
473 static inline void top_multiple_thandle_put(struct top_multiple_thandle *tmt)
475 if (atomic_dec_and_test(&tmt->tmt_refcount))
476 top_multiple_thandle_destroy(tmt);
479 struct sub_thandle *lookup_sub_thandle(struct top_multiple_thandle *tmt,
480 struct dt_device *dt_dev);
481 int sub_thandle_trans_create(const struct lu_env *env,
482 struct top_thandle *top_th,
483 struct sub_thandle *st);
485 /* update_records.c */
486 size_t update_records_create_size(const struct lu_env *env,
487 const struct lu_fid *fid,
488 const struct lu_attr *attr,
489 const struct dt_allocation_hint *hint,
490 struct dt_object_format *dof);
491 size_t update_records_attr_set_size(const struct lu_env *env,
492 const struct lu_fid *fid,
493 const struct lu_attr *attr);
494 size_t update_records_ref_add_size(const struct lu_env *env,
495 const struct lu_fid *fid);
496 size_t update_records_ref_del_size(const struct lu_env *env,
497 const struct lu_fid *fid);
498 size_t update_records_object_destroy_size(const struct lu_env *env,
499 const struct lu_fid *fid);
500 size_t update_records_index_insert_size(const struct lu_env *env,
501 const struct lu_fid *fid,
502 const struct dt_rec *rec,
503 const struct dt_key *key);
504 size_t update_records_index_delete_size(const struct lu_env *env,
505 const struct lu_fid *fid,
506 const struct dt_key *key);
507 size_t update_records_xattr_set_size(const struct lu_env *env,
508 const struct lu_fid *fid,
509 const struct lu_buf *buf,
512 size_t update_records_xattr_del_size(const struct lu_env *env,
513 const struct lu_fid *fid,
515 size_t update_records_write_size(const struct lu_env *env,
516 const struct lu_fid *fid,
517 const struct lu_buf *buf,
519 size_t update_records_punch_size(const struct lu_env *env,
520 const struct lu_fid *fid,
521 __u64 start, __u64 end);
523 int update_records_create_pack(const struct lu_env *env,
524 struct update_ops *ops,
525 unsigned int *op_count,
526 size_t *max_ops_size,
527 struct update_params *params,
528 unsigned int *param_count,
529 size_t *max_param_size,
530 const struct lu_fid *fid,
531 const struct lu_attr *attr,
532 const struct dt_allocation_hint *hint,
533 struct dt_object_format *dof);
534 int update_records_attr_set_pack(const struct lu_env *env,
535 struct update_ops *ops,
536 unsigned int *op_count,
537 size_t *max_ops_size,
538 struct update_params *params,
539 unsigned int *param_count,
540 size_t *max_param_size,
541 const struct lu_fid *fid,
542 const struct lu_attr *attr);
543 int update_records_ref_add_pack(const struct lu_env *env,
544 struct update_ops *ops,
545 unsigned int *op_count,
546 size_t *max_ops_size,
547 struct update_params *params,
548 unsigned int *param_count,
549 size_t *max_param_size,
550 const struct lu_fid *fid);
551 int update_records_ref_del_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 int update_records_object_destroy_pack(const struct lu_env *env,
560 struct update_ops *ops,
561 unsigned int *op_count,
562 size_t *max_ops_size,
563 struct update_params *params,
564 unsigned int *param_count,
565 size_t *max_param_size,
566 const struct lu_fid *fid);
567 int update_records_index_insert_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 const struct dt_rec *rec,
576 const struct dt_key *key);
577 int update_records_index_delete_pack(const struct lu_env *env,
578 struct update_ops *ops,
579 unsigned int *op_count,
580 size_t *max_ops_size,
581 struct update_params *params,
582 unsigned int *param_count,
583 size_t *max_param_size,
584 const struct lu_fid *fid,
585 const struct dt_key *key);
586 int update_records_xattr_set_pack(const struct lu_env *env,
587 struct update_ops *ops,
588 unsigned int *op_count,
589 size_t *max_ops_size,
590 struct update_params *params,
591 unsigned int *param_count,
592 size_t *max_param_size,
593 const struct lu_fid *fid,
594 const struct lu_buf *buf, const char *name,
596 int update_records_xattr_del_pack(const struct lu_env *env,
597 struct update_ops *ops,
598 unsigned int *op_count,
599 size_t *max_ops_size,
600 struct update_params *params,
601 unsigned int *param_count,
602 size_t *max_param_size,
603 const struct lu_fid *fid,
605 int update_records_write_pack(const struct lu_env *env,
606 struct update_ops *ops,
607 unsigned int *op_count,
608 size_t *max_ops_size,
609 struct update_params *params,
610 unsigned int *param_count,
611 size_t *max_param_size,
612 const struct lu_fid *fid,
613 const struct lu_buf *buf,
615 int update_records_punch_pack(const struct lu_env *env,
616 struct update_ops *ops,
617 unsigned int *op_count,
618 size_t *max_ops_size,
619 struct update_params *params,
620 unsigned int *param_count,
621 size_t *max_param_size,
622 const struct lu_fid *fid,
623 __u64 start, __u64 end);
624 int update_records_noop_pack(const struct lu_env *env,
625 struct update_ops *ops,
626 unsigned int *op_count,
627 size_t *max_ops_size,
628 struct update_params *params,
629 unsigned int *param_count,
630 size_t *max_param_size,
631 const struct lu_fid *fid);
633 int tur_update_records_extend(struct thandle_update_records *tur,
635 int tur_update_params_extend(struct thandle_update_records *tur,
637 int tur_update_extend(struct thandle_update_records *tur,
638 size_t new_op_size, size_t new_param_size);
640 #define update_record_pack(name, th, ...) \
642 struct top_thandle *top_th; \
643 struct top_multiple_thandle *tmt; \
644 struct thandle_update_records *tur; \
645 struct llog_update_record *lur; \
646 size_t avail_param_size; \
647 size_t avail_op_size; \
651 top_th = container_of(th, struct top_thandle, tt_super);\
652 tmt = top_th->tt_multiple_thandle; \
653 tur = tmt->tmt_update_records; \
654 lur = tur->tur_update_records; \
655 avail_param_size = tur->tur_update_params_buf_size - \
656 update_params_size(tur->tur_update_params, \
657 tur->tur_update_param_count); \
658 avail_op_size = tur->tur_update_records_buf_size - \
659 llog_update_record_size(lur); \
660 ret = update_records_##name##_pack(env, \
661 &lur->lur_update_rec.ur_ops, \
662 &lur->lur_update_rec.ur_update_count, \
664 tur->tur_update_params, \
665 &tur->tur_update_param_count, \
666 &avail_param_size, __VA_ARGS__); \
667 if (ret == -E2BIG) { \
668 ret = tur_update_extend(tur, avail_op_size, \
680 #define update_record_size(env, name, th, ...) \
682 struct top_thandle *top_th; \
683 struct top_multiple_thandle *tmt; \
685 top_th = container_of(th, struct top_thandle, tt_super); \
687 LASSERT(top_th->tt_multiple_thandle != NULL); \
688 tmt = top_th->tt_multiple_thandle; \
689 tmt->tmt_record_size += \
690 update_records_##name##_size(env, __VA_ARGS__); \