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, 2014, 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 /* 16KB, the current biggest size is llog header(8KB) */
38 #define OUT_UPDATE_REPLY_SIZE 16384
42 struct object_update_param;
44 struct update_buffer {
45 struct object_update_request *ub_req;
50 * Tracking the updates being executed on this dt_device.
52 struct dt_update_request {
53 struct dt_device *dur_dt;
54 /* attached itself to thandle */
56 /* update request result */
58 /* Current batch(transaction) id */
60 /* Holding object updates */
61 struct update_buffer dur_buf;
62 struct list_head dur_cb_items;
65 struct update_params {
66 struct object_update_param up_params[0];
69 static inline size_t update_params_size(const struct update_params *params,
70 unsigned int param_count)
72 struct object_update_param *param;
73 size_t total_size = sizeof(*params);
76 param = (struct object_update_param *)¶ms->up_params[0];
77 for (i = 0; i < param_count; i++) {
78 size_t size = object_update_param_size(param);
80 param = (struct object_update_param *)((char *)param + size);
87 static inline struct object_update_param *
88 update_params_get_param(const struct update_params *params,
89 unsigned int index, unsigned int param_count)
91 struct object_update_param *param;
94 if (index > param_count)
97 param = (struct object_update_param *)¶ms->up_params[0];
98 for (i = 0; i < index; i++)
99 param = (struct object_update_param *)((char *)param +
100 object_update_param_size(param));
106 struct lu_fid uop_fid;
108 __u16 uop_param_count;
109 __u16 uop_params_off[0];
113 update_op_size(unsigned int param_count)
115 return offsetof(struct update_op, uop_params_off[param_count]);
118 static inline struct update_op *
119 update_op_next_op(const struct update_op *uop)
121 return (struct update_op *)((char *)uop +
122 update_op_size(uop->uop_param_count));
125 /* All of updates in the mulitple_update_record */
127 struct update_op uops_op[0];
130 static inline size_t update_ops_size(const struct update_ops *ops,
131 unsigned int update_count)
133 struct update_op *op;
134 size_t total_size = sizeof(*ops);
137 op = (struct update_op *)&ops->uops_op[0];
138 for (i = 0; i < update_count; i++, op = update_op_next_op(op))
139 total_size += update_op_size(op->uop_param_count);
145 * This is the update record format used to store the updates in
146 * disk. All updates of the operation will be stored in ur_ops.
147 * All of parameters for updates of the operation will be stored
149 * To save the space of the record, parameters in ur_ops will only
150 * remember their offset in ur_params, so to avoid storing duplicate
151 * parameters in ur_params, which can help us save a lot space for
152 * operation like creating striped directory.
154 struct update_records {
155 __u64 ur_master_transno;
158 __u32 ur_param_count;
159 __u32 ur_update_count;
160 struct update_ops ur_ops;
161 /* Note ur_ops has a variable size, so comment out
162 * the following ur_params, in case some use it directly
163 * update_records->ur_params
165 * struct update_params ur_params;
169 struct llog_update_record {
170 struct llog_rec_hdr lur_hdr;
171 struct update_records lur_update_rec;
172 /* Note ur_update_rec has a variable size, so comment out
173 * the following ur_tail, in case someone use it directly
175 * struct llog_rec_tail lur_tail;
179 static inline struct update_params *
180 update_records_get_params(const struct update_records *record)
182 return (struct update_params *)((char *)record +
183 offsetof(struct update_records, ur_ops) +
184 update_ops_size(&record->ur_ops, record->ur_update_count));
188 update_records_size(const struct update_records *record)
190 struct update_params *params;
192 params = update_records_get_params(record);
194 return cfs_size_round(offsetof(struct update_records, ur_ops) +
195 update_ops_size(&record->ur_ops, record->ur_update_count) +
196 update_params_size(params, record->ur_param_count));
200 llog_update_record_size(const struct llog_update_record *lur)
202 return cfs_size_round(sizeof(lur->lur_hdr) +
203 update_records_size(&lur->lur_update_rec) +
204 sizeof(struct llog_rec_tail));
207 static inline struct update_op *
208 update_ops_get_op(const struct update_ops *ops, unsigned int index,
209 unsigned int update_count)
211 struct update_op *op;
214 if (index > update_count)
217 op = (struct update_op *)&ops->uops_op[0];
218 for (i = 0; i < index; i++)
219 op = update_op_next_op(op);
225 *object_update_param_get(const struct object_update *update, size_t index,
228 const struct object_update_param *param;
231 if (index >= update->ou_params_count)
232 return ERR_PTR(-EINVAL);
234 param = &update->ou_params[0];
235 for (i = 0; i < index; i++)
236 param = (struct object_update_param *)((char *)param +
237 object_update_param_size(param));
240 *size = param->oup_len;
242 if (param->oup_len == 0)
245 return (void *)¶m->oup_buf[0];
248 static inline unsigned long
249 object_update_request_size(const struct object_update_request *our)
254 size = offsetof(struct object_update_request, ourq_updates[0]);
255 for (i = 0; i < our->ourq_count; i++) {
256 struct object_update *update;
258 update = (struct object_update *)((char *)our + size);
259 size += object_update_size(update);
265 object_update_reply_init(struct object_update_reply *reply, size_t count)
267 reply->ourp_magic = UPDATE_REPLY_MAGIC;
268 reply->ourp_count = count;
272 object_update_result_insert(struct object_update_reply *reply,
273 void *data, size_t data_len, size_t index,
276 struct object_update_result *update_result;
279 update_result = object_update_result_get(reply, index, NULL);
280 LASSERT(update_result != NULL);
282 update_result->our_rc = ptlrpc_status_hton(rc);
284 LASSERT(data != NULL);
285 ptr = (char *)update_result +
286 cfs_size_round(sizeof(struct object_update_reply));
287 update_result->our_datalen = data_len;
288 memcpy(ptr, data, data_len);
291 reply->ourp_lens[index] = cfs_size_round(data_len +
292 sizeof(struct object_update_result));
296 object_update_result_data_get(const struct object_update_reply *reply,
297 struct lu_buf *lbuf, size_t index)
299 struct object_update_result *update_result;
303 LASSERT(lbuf != NULL);
304 update_result = object_update_result_get(reply, index, &size);
305 if (update_result == NULL ||
306 size < cfs_size_round(sizeof(struct object_update_reply)) ||
307 update_result->our_datalen > size)
310 result = ptlrpc_status_ntoh(update_result->our_rc);
314 lbuf->lb_buf = update_result->our_data;
315 lbuf->lb_len = update_result->our_datalen;
321 * Attached in the thandle to record the updates for distribute
324 struct thandle_update_records {
325 /* All of updates for the cross-MDT operation. */
326 struct llog_update_record *tur_update_records;
327 size_t tur_update_records_buf_size;
329 /* All of parameters for the cross-MDT operation */
330 struct update_params *tur_update_params;
331 unsigned int tur_update_param_count;
332 size_t tur_update_params_buf_size;
335 #define TOP_THANDLE_MAGIC 0x20140917
336 /* {top,sub}_thandle are used to manage distributed transactions which
337 * include updates on several nodes. A top_handle represents the
338 * whole operation, and sub_thandle represents updates on each node. */
340 struct thandle tt_super;
342 atomic_t tt_refcount;
343 /* The master sub transaction. */
344 struct thandle *tt_master_sub_thandle;
346 /* Other sub thandle will be listed here. */
347 struct list_head tt_sub_thandle_list;
349 /* All of update records will packed here */
350 struct thandle_update_records *tt_update_records;
354 /* point to the osd/osp_thandle */
355 struct thandle *st_sub_th;
357 /* linked to top_thandle */
358 struct list_head st_sub_list;
360 /* If this sub thandle is committed */
366 /* target/out_lib.c */
367 int out_update_pack(const struct lu_env *env, struct object_update *update,
368 size_t max_update_size, enum update_type op,
369 const struct lu_fid *fid, unsigned int params_count,
370 __u16 *param_sizes, const void **param_bufs);
371 int out_create_pack(const struct lu_env *env, struct object_update *update,
372 size_t max_update_size, const struct lu_fid *fid,
373 const struct lu_attr *attr, struct dt_allocation_hint *hint,
374 struct dt_object_format *dof);
375 int out_object_destroy_pack(const struct lu_env *env,
376 struct object_update *update,
377 size_t max_update_size,
378 const struct lu_fid *fid);
379 int out_index_delete_pack(const struct lu_env *env,
380 struct object_update *update, size_t max_update_size,
381 const struct lu_fid *fid, const struct dt_key *key);
382 int out_index_insert_pack(const struct lu_env *env,
383 struct object_update *update, size_t max_update_size,
384 const struct lu_fid *fid, const struct dt_rec *rec,
385 const struct dt_key *key);
386 int out_xattr_set_pack(const struct lu_env *env,
387 struct object_update *update, size_t max_update_size,
388 const struct lu_fid *fid, const struct lu_buf *buf,
389 const char *name, __u32 flag);
390 int out_xattr_del_pack(const struct lu_env *env,
391 struct object_update *update, size_t max_update_size,
392 const struct lu_fid *fid, const char *name);
393 int out_attr_set_pack(const struct lu_env *env,
394 struct object_update *update, size_t max_update_size,
395 const struct lu_fid *fid, const struct lu_attr *attr);
396 int out_ref_add_pack(const struct lu_env *env,
397 struct object_update *update, size_t max_update_size,
398 const struct lu_fid *fid);
399 int out_ref_del_pack(const struct lu_env *env,
400 struct object_update *update, size_t max_update_size,
401 const struct lu_fid *fid);
402 int out_write_pack(const struct lu_env *env,
403 struct object_update *update, size_t max_update_size,
404 const struct lu_fid *fid, const struct lu_buf *buf,
406 int out_attr_get_pack(const struct lu_env *env,
407 struct object_update *update, size_t max_update_size,
408 const struct lu_fid *fid);
409 int out_index_lookup_pack(const struct lu_env *env,
410 struct object_update *update, size_t max_update_size,
411 const struct lu_fid *fid, struct dt_rec *rec,
412 const struct dt_key *key);
413 int out_xattr_get_pack(const struct lu_env *env,
414 struct object_update *update, size_t max_update_size,
415 const struct lu_fid *fid, const char *name);
416 int out_read_pack(const struct lu_env *env, struct object_update *update,
417 size_t max_update_length, const struct lu_fid *fid,
418 size_t size, loff_t pos);
420 const char *update_op_str(__u16 opcode);
422 /* target/update_trans.c */
423 struct thandle *thandle_get_sub_by_dt(const struct lu_env *env,
425 struct dt_device *sub_dt);
427 static inline struct thandle *
428 thandle_get_sub(const struct lu_env *env, struct thandle *th,
429 const struct dt_object *sub_obj)
431 return thandle_get_sub_by_dt(env, th, lu2dt_dev(sub_obj->do_lu.lo_dev));
435 top_trans_create(const struct lu_env *env, struct dt_device *master_dev);
437 int top_trans_start(const struct lu_env *env, struct dt_device *master_dev,
440 int top_trans_stop(const struct lu_env *env, struct dt_device *master_dev,
443 void top_thandle_destroy(struct top_thandle *top_th);
445 /* update_records.c */
446 int update_records_create_pack(const struct lu_env *env,
447 struct update_ops *ops,
448 unsigned int *op_count,
449 size_t *max_ops_size,
450 struct update_params *params,
451 unsigned int *param_count,
452 size_t *max_param_size,
453 const struct lu_fid *fid,
454 const struct lu_attr *attr,
455 const struct dt_allocation_hint *hint,
456 struct dt_object_format *dof);
457 int update_records_attr_set_pack(const struct lu_env *env,
458 struct update_ops *ops,
459 unsigned int *op_count,
460 size_t *max_ops_size,
461 struct update_params *params,
462 unsigned int *param_count,
463 size_t *max_param_size,
464 const struct lu_fid *fid,
465 const struct lu_attr *attr);
466 int update_records_ref_add_pack(const struct lu_env *env,
467 struct update_ops *ops,
468 unsigned int *op_count,
469 size_t *max_ops_size,
470 struct update_params *params,
471 unsigned int *param_count,
472 size_t *max_param_size,
473 const struct lu_fid *fid);
474 int update_records_ref_del_pack(const struct lu_env *env,
475 struct update_ops *ops,
476 unsigned int *op_count,
477 size_t *max_ops_size,
478 struct update_params *params,
479 unsigned int *param_count,
480 size_t *max_param_size,
481 const struct lu_fid *fid);
482 int update_records_object_destroy_pack(const struct lu_env *env,
483 struct update_ops *ops,
484 unsigned int *op_count,
485 size_t *max_ops_size,
486 struct update_params *params,
487 unsigned int *param_count,
488 size_t *max_param_size,
489 const struct lu_fid *fid);
490 int update_records_index_insert_pack(const struct lu_env *env,
491 struct update_ops *ops,
492 unsigned int *op_count,
493 size_t *max_ops_size,
494 struct update_params *params,
495 unsigned int *param_count,
496 size_t *max_param_size,
497 const struct lu_fid *fid,
498 const struct dt_rec *rec,
499 const struct dt_key *key);
500 int update_records_index_delete_pack(const struct lu_env *env,
501 struct update_ops *ops,
502 unsigned int *op_count,
503 size_t *max_ops_size,
504 struct update_params *params,
505 unsigned int *param_count,
506 size_t *max_param_size,
507 const struct lu_fid *fid,
508 const struct dt_key *key);
509 int update_records_xattr_set_pack(const struct lu_env *env,
510 struct update_ops *ops,
511 unsigned int *op_count,
512 size_t *max_ops_size,
513 struct update_params *params,
514 unsigned int *param_count,
515 size_t *max_param_size,
516 const struct lu_fid *fid,
517 const struct lu_buf *buf, const char *name,
519 int update_records_xattr_del_pack(const struct lu_env *env,
520 struct update_ops *ops,
521 unsigned int *op_count,
522 size_t *max_ops_size,
523 struct update_params *params,
524 unsigned int *param_count,
525 size_t *max_param_size,
526 const struct lu_fid *fid,
528 int update_records_write_pack(const struct lu_env *env,
529 struct update_ops *ops,
530 unsigned int *op_count,
531 size_t *max_ops_size,
532 struct update_params *params,
533 unsigned int *param_count,
534 size_t *max_param_size,
535 const struct lu_fid *fid,
536 const struct lu_buf *buf,
538 int update_records_punch_pack(const struct lu_env *env,
539 struct update_ops *ops,
540 unsigned int *op_count,
541 size_t *max_ops_size,
542 struct update_params *params,
543 unsigned int *param_count,
544 size_t *max_param_size,
545 const struct lu_fid *fid,
546 __u64 start, __u64 end);
548 int tur_update_records_extend(struct thandle_update_records *tur,
550 int tur_update_params_extend(struct thandle_update_records *tur,
552 int check_and_prepare_update_record(const struct lu_env *env,
554 int merge_params_updates_buf(const struct lu_env *env,
555 struct thandle_update_records *tur);
556 int tur_update_extend(struct thandle_update_records *tur,
557 size_t new_op_size, size_t new_param_size);
559 #define update_record_pack(name, th, ...) \
561 struct top_thandle *top_th; \
562 struct thandle_update_records *tur; \
563 struct llog_update_record *lur; \
564 size_t avail_param_size; \
565 size_t avail_op_size; \
569 top_th = container_of(th, struct top_thandle, tt_super);\
570 tur = top_th->tt_update_records; \
571 lur = tur->tur_update_records; \
572 avail_param_size = tur->tur_update_params_buf_size - \
573 update_params_size(tur->tur_update_params, \
574 tur->tur_update_param_count); \
575 avail_op_size = tur->tur_update_records_buf_size - \
576 llog_update_record_size(lur); \
577 ret = update_records_##name##_pack(env, \
578 &lur->lur_update_rec.ur_ops, \
579 &lur->lur_update_rec.ur_update_count, \
581 tur->tur_update_params, \
582 &tur->tur_update_param_count, \
583 &avail_param_size, __VA_ARGS__); \
584 if (ret == -E2BIG) { \
585 ret = tur_update_extend(tur, avail_op_size, \