Whamcloud - gitweb
LU-6698 kernel: kernel update RHEL 6.6 [2.6.32-504.23.4.el6]
[fs/lustre-release.git] / lustre / include / lustre_update.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2013, 2014, Intel Corporation.
24  */
25 /*
26  * lustre/include/lustre_update.h
27  *
28  * Author: Di Wang <di.wang@intel.com>
29  */
30
31 #ifndef _LUSTRE_UPDATE_H
32 #define _LUSTRE_UPDATE_H
33 #include <lustre_net.h>
34 #include <dt_object.h>
35
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
39
40 struct dt_key;
41 struct dt_rec;
42 struct object_update_param;
43
44 struct update_params {
45         struct object_update_param      up_params[0];
46 };
47
48 static inline size_t update_params_size(const struct update_params *params,
49                                         unsigned int param_count)
50 {
51         struct object_update_param      *param;
52         size_t total_size = sizeof(*params);
53         unsigned int i;
54
55         param = (struct object_update_param *)&params->up_params[0];
56         for (i = 0; i < param_count; i++) {
57                 size_t size = object_update_param_size(param);
58
59                 param = (struct object_update_param *)((char *)param + size);
60                 total_size += size;
61         }
62
63         return total_size;
64 }
65
66 static inline struct object_update_param *
67 update_params_get_param(const struct update_params *params,
68                         unsigned int index, unsigned int param_count)
69 {
70         struct object_update_param *param;
71         unsigned int            i;
72
73         if (index > param_count)
74                 return NULL;
75
76         param = (struct object_update_param *)&params->up_params[0];
77         for (i = 0; i < index; i++)
78                 param = (struct object_update_param *)((char *)param +
79                         object_update_param_size(param));
80
81         return param;
82 }
83
84 static inline void*
85 update_params_get_param_buf(const struct update_params *params, __u16 index,
86                             unsigned int param_count, __u16 *size)
87 {
88         struct object_update_param *param;
89
90         param = update_params_get_param(params, (unsigned int)index,
91                                         param_count);
92         if (param == NULL)
93                 return NULL;
94
95         if (size != NULL)
96                 *size = param->oup_len;
97
98         return param->oup_buf;
99 }
100
101 struct update_op {
102         struct lu_fid uop_fid;
103         __u16   uop_type;
104         __u16   uop_param_count;
105         __u16   uop_params_off[0];
106 };
107
108 static inline size_t
109 update_op_size(unsigned int param_count)
110 {
111         return offsetof(struct update_op, uop_params_off[param_count]);
112 }
113
114 static inline struct update_op *
115 update_op_next_op(const struct update_op *uop)
116 {
117         return (struct update_op *)((char *)uop +
118                                 update_op_size(uop->uop_param_count));
119 }
120
121 /* All of updates in the mulitple_update_record */
122 struct update_ops {
123         struct update_op        uops_op[0];
124 };
125
126 static inline size_t update_ops_size(const struct update_ops *ops,
127                                      unsigned int update_count)
128 {
129         struct update_op *op;
130         size_t total_size = sizeof(*ops);
131         unsigned int i;
132
133         op = (struct update_op *)&ops->uops_op[0];
134         for (i = 0; i < update_count; i++, op = update_op_next_op(op))
135                 total_size += update_op_size(op->uop_param_count);
136
137         return total_size;
138 }
139
140 /*
141  * This is the update record format used to store the updates in
142  * disk. All updates of the operation will be stored in ur_ops.
143  * All of parameters for updates of the operation will be stored
144  * in ur_params.
145  * To save the space of the record, parameters in ur_ops will only
146  * remember their offset in ur_params, so to avoid storing duplicate
147  * parameters in ur_params, which can help us save a lot space for
148  * operation like creating striped directory.
149  */
150 struct update_records {
151         __u64                   ur_master_transno;
152         __u64                   ur_batchid;
153         __u32                   ur_flags;
154         __u32                   ur_param_count;
155         __u32                   ur_update_count;
156         struct update_ops       ur_ops;
157          /* Note ur_ops has a variable size, so comment out
158           * the following ur_params, in case some use it directly
159           * update_records->ur_params
160           *
161           * struct update_params        ur_params;
162           */
163 };
164
165 struct llog_update_record {
166         struct llog_rec_hdr     lur_hdr;
167         struct update_records   lur_update_rec;
168         /* Note ur_update_rec has a variable size, so comment out
169          * the following ur_tail, in case someone use it directly
170          *
171          * struct llog_rec_tail lur_tail;
172          */
173 };
174
175 static inline struct update_params *
176 update_records_get_params(const struct update_records *record)
177 {
178         return (struct update_params *)((char *)record +
179                 offsetof(struct update_records, ur_ops) +
180                 update_ops_size(&record->ur_ops, record->ur_update_count));
181 }
182
183 static inline size_t
184 update_records_size(const struct update_records *record)
185 {
186         struct update_params *params;
187
188         params = update_records_get_params(record);
189
190         return cfs_size_round(offsetof(struct update_records, ur_ops) +
191                update_ops_size(&record->ur_ops, record->ur_update_count) +
192                update_params_size(params, record->ur_param_count));
193 }
194
195 static inline size_t
196 llog_update_record_size(const struct llog_update_record *lur)
197 {
198         return cfs_size_round(sizeof(lur->lur_hdr) +
199                               update_records_size(&lur->lur_update_rec) +
200                               sizeof(struct llog_rec_tail));
201 }
202
203 static inline struct update_op *
204 update_ops_get_op(const struct update_ops *ops, unsigned int index,
205                   unsigned int update_count)
206 {
207         struct update_op *op;
208         unsigned int i;
209
210         if (index > update_count)
211                 return NULL;
212
213         op = (struct update_op *)&ops->uops_op[0];
214         for (i = 0; i < index; i++)
215                 op = update_op_next_op(op);
216
217         return op;
218 }
219
220 static inline void
221 *object_update_param_get(const struct object_update *update, size_t index,
222                          size_t *size)
223 {
224         const struct    object_update_param *param;
225         size_t          i;
226
227         if (index >= update->ou_params_count)
228                 return ERR_PTR(-EINVAL);
229
230         param = &update->ou_params[0];
231         for (i = 0; i < index; i++)
232                 param = (struct object_update_param *)((char *)param +
233                         object_update_param_size(param));
234
235         if (size != NULL)
236                 *size = param->oup_len;
237
238         if (param->oup_len == 0)
239                 return NULL;
240
241         return (void *)&param->oup_buf[0];
242 }
243
244 static inline unsigned long
245 object_update_request_size(const struct object_update_request *our)
246 {
247         unsigned long   size;
248         size_t          i = 0;
249
250         size = offsetof(struct object_update_request, ourq_updates[0]);
251         for (i = 0; i < our->ourq_count; i++) {
252                 struct object_update *update;
253
254                 update = (struct object_update *)((char *)our + size);
255                 size += object_update_size(update);
256         }
257         return size;
258 }
259
260 static inline void
261 object_update_reply_init(struct object_update_reply *reply, size_t count)
262 {
263         reply->ourp_magic = UPDATE_REPLY_MAGIC;
264         reply->ourp_count = count;
265 }
266
267 static inline void
268 object_update_result_insert(struct object_update_reply *reply,
269                             void *data, size_t data_len, size_t index,
270                             int rc)
271 {
272         struct object_update_result *update_result;
273         char *ptr;
274
275         update_result = object_update_result_get(reply, index, NULL);
276         LASSERT(update_result != NULL);
277
278         update_result->our_rc = ptlrpc_status_hton(rc);
279         if (data_len > 0) {
280                 LASSERT(data != NULL);
281                 ptr = (char *)update_result +
282                         cfs_size_round(sizeof(struct object_update_reply));
283                 update_result->our_datalen = data_len;
284                 memcpy(ptr, data, data_len);
285         }
286
287         reply->ourp_lens[index] = cfs_size_round(data_len +
288                                         sizeof(struct object_update_result));
289 }
290
291 static inline int
292 object_update_result_data_get(const struct object_update_reply *reply,
293                               struct lu_buf *lbuf, size_t index)
294 {
295         struct object_update_result *update_result;
296         size_t size = 0;
297         int    result;
298
299         LASSERT(lbuf != NULL);
300         update_result = object_update_result_get(reply, index, &size);
301         if (update_result == NULL ||
302             size < cfs_size_round(sizeof(struct object_update_reply)) ||
303             update_result->our_datalen > size)
304                 RETURN(-EFAULT);
305
306         result = ptlrpc_status_ntoh(update_result->our_rc);
307         if (result < 0)
308                 return result;
309
310         lbuf->lb_buf = update_result->our_data;
311         lbuf->lb_len = update_result->our_datalen;
312
313         return 0;
314 }
315
316 /**
317  * Attached in the thandle to record the updates for distribute
318  * distribution.
319  */
320 struct thandle_update_records {
321         /* All of updates for the cross-MDT operation. */
322         struct llog_update_record       *tur_update_records;
323         size_t                          tur_update_records_buf_size;
324
325         /* All of parameters for the cross-MDT operation */
326         struct update_params    *tur_update_params;
327         unsigned int            tur_update_param_count;
328         size_t                  tur_update_params_buf_size;
329 };
330
331 #define TOP_THANDLE_MAGIC       0x20140917
332 struct top_multiple_thandle {
333         struct dt_device        *tmt_master_sub_dt;
334         atomic_t                tmt_refcount;
335         /* Other sub transactions will be listed here. */
336         struct list_head        tmt_sub_thandle_list;
337
338         struct list_head        tmt_commit_list;
339         /* All of update records will packed here */
340         struct thandle_update_records *tmt_update_records;
341
342         wait_queue_head_t       tmt_stop_waitq;
343         __u64                   tmt_batchid;
344         int                     tmt_result;
345         __u32                   tmt_magic;
346         __u32                   tmt_committed:1;
347 };
348
349 /* {top,sub}_thandle are used to manage distributed transactions which
350  * include updates on several nodes. A top_handle represents the
351  * whole operation, and sub_thandle represents updates on each node. */
352 struct top_thandle {
353         struct thandle          tt_super;
354         /* The master sub transaction. */
355         struct thandle          *tt_master_sub_thandle;
356
357         struct top_multiple_thandle *tt_multiple_thandle;
358 };
359
360 /* Sub thandle is used to track multiple sub thandles under one parent
361  * thandle */
362 struct sub_thandle {
363         struct thandle          *st_sub_th;
364         struct dt_device        *st_dt;
365         struct llog_cookie      st_cookie;
366         struct dt_txn_commit_cb st_commit_dcb;
367         struct dt_txn_commit_cb st_stop_dcb;
368         int                     st_result;
369
370         /* linked to top_thandle */
371         struct list_head        st_sub_list;
372
373         /* If this sub thandle is committed */
374         bool                    st_committed:1,
375                                 st_stopped:1;
376 };
377
378 struct tx_arg;
379 typedef int (*tx_exec_func_t)(const struct lu_env *env, struct thandle *th,
380                               struct tx_arg *ta);
381
382 /* Structure for holding one update execution */
383 struct tx_arg {
384         tx_exec_func_t           exec_fn;
385         tx_exec_func_t           undo_fn;
386         struct dt_object        *object;
387         const char              *file;
388         struct object_update_reply *reply;
389         int                      line;
390         int                      index;
391         union {
392                 struct {
393                         struct dt_insert_rec     rec;
394                         const struct dt_key     *key;
395                 } insert;
396                 struct {
397                 } ref;
398                 struct {
399                         struct lu_attr   attr;
400                 } attr_set;
401                 struct {
402                         struct lu_buf    buf;
403                         const char      *name;
404                         int              flags;
405                         __u32            csum;
406                 } xattr_set;
407                 struct {
408                         struct lu_attr                  attr;
409                         struct dt_allocation_hint       hint;
410                         struct dt_object_format         dof;
411                         struct lu_fid                   fid;
412                 } create;
413                 struct {
414                         struct lu_buf   buf;
415                         loff_t          pos;
416                 } write;
417                 struct {
418                         struct ost_body     *body;
419                 } destroy;
420         } u;
421 };
422
423 /* Structure for holding all update executations of one transaction */
424 struct thandle_exec_args {
425         struct thandle          *ta_handle;
426         int                     ta_argno;   /* used args */
427         int                     ta_alloc_args; /* allocated args count */
428         struct tx_arg           **ta_args;
429 };
430
431 /* target/out_lib.c */
432 int out_update_pack(const struct lu_env *env, struct object_update *update,
433                     size_t max_update_size, enum update_type op,
434                     const struct lu_fid *fid, unsigned int params_count,
435                     __u16 *param_sizes, const void **param_bufs);
436 int out_create_pack(const struct lu_env *env, struct object_update *update,
437                     size_t max_update_size, const struct lu_fid *fid,
438                     const struct lu_attr *attr, struct dt_allocation_hint *hint,
439                     struct dt_object_format *dof);
440 int out_object_destroy_pack(const struct lu_env *env,
441                             struct object_update *update,
442                             size_t max_update_size,
443                             const struct lu_fid *fid);
444 int out_index_delete_pack(const struct lu_env *env,
445                           struct object_update *update, size_t max_update_size,
446                           const struct lu_fid *fid, const struct dt_key *key);
447 int out_index_insert_pack(const struct lu_env *env,
448                           struct object_update *update, size_t max_update_size,
449                           const struct lu_fid *fid, const struct dt_rec *rec,
450                           const struct dt_key *key);
451 int out_xattr_set_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,
454                        const char *name, __u32 flag);
455 int out_xattr_del_pack(const struct lu_env *env,
456                        struct object_update *update, size_t max_update_size,
457                        const struct lu_fid *fid, const char *name);
458 int out_attr_set_pack(const struct lu_env *env,
459                       struct object_update *update, size_t max_update_size,
460                       const struct lu_fid *fid, const struct lu_attr *attr);
461 int out_ref_add_pack(const struct lu_env *env,
462                      struct object_update *update, size_t max_update_size,
463                      const struct lu_fid *fid);
464 int out_ref_del_pack(const struct lu_env *env,
465                      struct object_update *update, size_t max_update_size,
466                      const struct lu_fid *fid);
467 int out_write_pack(const struct lu_env *env,
468                    struct object_update *update, size_t max_update_size,
469                    const struct lu_fid *fid, const struct lu_buf *buf,
470                    __u64 pos);
471 int out_attr_get_pack(const struct lu_env *env,
472                       struct object_update *update, size_t max_update_size,
473                       const struct lu_fid *fid);
474 int out_index_lookup_pack(const struct lu_env *env,
475                           struct object_update *update, size_t max_update_size,
476                           const struct lu_fid *fid, struct dt_rec *rec,
477                           const struct dt_key *key);
478 int out_xattr_get_pack(const struct lu_env *env,
479                        struct object_update *update, size_t max_update_size,
480                        const struct lu_fid *fid, const char *name);
481 int out_read_pack(const struct lu_env *env, struct object_update *update,
482                   size_t max_update_length, const struct lu_fid *fid,
483                   size_t size, loff_t pos);
484
485 const char *update_op_str(__u16 opcode);
486
487 /* target/update_trans.c */
488 struct thandle *thandle_get_sub_by_dt(const struct lu_env *env,
489                                       struct thandle *th,
490                                       struct dt_device *sub_dt);
491
492 static inline struct thandle *
493 thandle_get_sub(const struct lu_env *env, struct thandle *th,
494                  const struct dt_object *sub_obj)
495 {
496         return thandle_get_sub_by_dt(env, th, lu2dt_dev(sub_obj->do_lu.lo_dev));
497 }
498
499 struct thandle *
500 top_trans_create(const struct lu_env *env, struct dt_device *master_dev);
501 int top_trans_start(const struct lu_env *env, struct dt_device *master_dev,
502                     struct thandle *th);
503 int top_trans_stop(const struct lu_env *env, struct dt_device *master_dev,
504                    struct thandle *th);
505 void top_multiple_thandle_destroy(struct top_multiple_thandle *tmt);
506
507 static inline void top_multiple_thandle_get(struct top_multiple_thandle *tmt)
508 {
509         atomic_inc(&tmt->tmt_refcount);
510 }
511
512 static inline void top_multiple_thandle_put(struct top_multiple_thandle *tmt)
513 {
514         if (atomic_dec_and_test(&tmt->tmt_refcount))
515                 top_multiple_thandle_destroy(tmt);
516 }
517
518 struct sub_thandle *lookup_sub_thandle(struct top_multiple_thandle *tmt,
519                                        struct dt_device *dt_dev);
520 int sub_thandle_trans_create(const struct lu_env *env,
521                              struct top_thandle *top_th,
522                              struct sub_thandle *st);
523
524 /* update_records.c */
525 int update_records_create_pack(const struct lu_env *env,
526                                struct update_ops *ops,
527                                unsigned int *op_count,
528                                size_t *max_ops_size,
529                                struct update_params *params,
530                                unsigned int *param_count,
531                                size_t *max_param_size,
532                                const struct lu_fid *fid,
533                                const struct lu_attr *attr,
534                                const struct dt_allocation_hint *hint,
535                                struct dt_object_format *dof);
536 int update_records_attr_set_pack(const struct lu_env *env,
537                                  struct update_ops *ops,
538                                  unsigned int *op_count,
539                                  size_t *max_ops_size,
540                                  struct update_params *params,
541                                  unsigned int *param_count,
542                                  size_t *max_param_size,
543                                  const struct lu_fid *fid,
544                                  const struct lu_attr *attr);
545 int update_records_ref_add_pack(const struct lu_env *env,
546                                 struct update_ops *ops,
547                                 unsigned int *op_count,
548                                 size_t *max_ops_size,
549                                 struct update_params *params,
550                                 unsigned int *param_count,
551                                 size_t *max_param_size,
552                                 const struct lu_fid *fid);
553 int update_records_ref_del_pack(const struct lu_env *env,
554                                 struct update_ops *ops,
555                                 unsigned int *op_count,
556                                 size_t *max_ops_size,
557                                 struct update_params *params,
558                                 unsigned int *param_count,
559                                 size_t *max_param_size,
560                                 const struct lu_fid *fid);
561 int update_records_object_destroy_pack(const struct lu_env *env,
562                                        struct update_ops *ops,
563                                        unsigned int *op_count,
564                                        size_t *max_ops_size,
565                                        struct update_params *params,
566                                        unsigned int *param_count,
567                                        size_t *max_param_size,
568                                        const struct lu_fid *fid);
569 int update_records_index_insert_pack(const struct lu_env *env,
570                                      struct update_ops *ops,
571                                      unsigned int *op_count,
572                                      size_t *max_ops_size,
573                                      struct update_params *params,
574                                      unsigned int *param_count,
575                                      size_t *max_param_size,
576                                      const struct lu_fid *fid,
577                                      const struct dt_rec *rec,
578                                      const struct dt_key *key);
579 int update_records_index_delete_pack(const struct lu_env *env,
580                                      struct update_ops *ops,
581                                      unsigned int *op_count,
582                                      size_t *max_ops_size,
583                                      struct update_params *params,
584                                      unsigned int *param_count,
585                                      size_t *max_param_size,
586                                      const struct lu_fid *fid,
587                                      const struct dt_key *key);
588 int update_records_xattr_set_pack(const struct lu_env *env,
589                                   struct update_ops *ops,
590                                   unsigned int *op_count,
591                                   size_t *max_ops_size,
592                                   struct update_params *params,
593                                   unsigned int *param_count,
594                                   size_t *max_param_size,
595                                   const struct lu_fid *fid,
596                                   const struct lu_buf *buf, const char *name,
597                                   __u32 flag);
598 int update_records_xattr_del_pack(const struct lu_env *env,
599                                   struct update_ops *ops,
600                                   unsigned int *op_count,
601                                   size_t *max_ops_size,
602                                   struct update_params *params,
603                                   unsigned int *param_count,
604                                   size_t *max_param_size,
605                                   const struct lu_fid *fid,
606                                   const char *name);
607 int update_records_write_pack(const struct lu_env *env,
608                               struct update_ops *ops,
609                               unsigned int *op_count,
610                               size_t *max_ops_size,
611                               struct update_params *params,
612                               unsigned int *param_count,
613                               size_t *max_param_size,
614                               const struct lu_fid *fid,
615                               const struct lu_buf *buf,
616                               __u64 pos);
617 int update_records_punch_pack(const struct lu_env *env,
618                               struct update_ops *ops,
619                               unsigned int *op_count,
620                               size_t *max_ops_size,
621                               struct update_params *params,
622                               unsigned int *param_count,
623                               size_t *max_param_size,
624                               const struct lu_fid *fid,
625                               __u64 start, __u64 end);
626
627 int tur_update_records_extend(struct thandle_update_records *tur,
628                               size_t new_size);
629 int tur_update_params_extend(struct thandle_update_records *tur,
630                              size_t new_size);
631 int tur_update_extend(struct thandle_update_records *tur,
632                       size_t new_op_size, size_t new_param_size);
633
634 #define update_record_pack(name, th, ...)                               \
635 ({                                                                      \
636         struct top_thandle *top_th;                                     \
637         struct top_multiple_thandle *tmt;                               \
638         struct thandle_update_records *tur;                             \
639         struct llog_update_record     *lur;                             \
640         size_t          avail_param_size;                               \
641         size_t          avail_op_size;                                  \
642         int             ret;                                            \
643                                                                         \
644         while (1) {                                                     \
645                 top_th = container_of(th, struct top_thandle, tt_super);\
646                 tmt = top_th->tt_multiple_thandle;                      \
647                 tur = tmt->tmt_update_records;                          \
648                 lur = tur->tur_update_records;                          \
649                 avail_param_size = tur->tur_update_params_buf_size -    \
650                              update_params_size(tur->tur_update_params, \
651                                         tur->tur_update_param_count);   \
652                 avail_op_size = tur->tur_update_records_buf_size -      \
653                                 llog_update_record_size(lur);           \
654                 ret = update_records_##name##_pack(env,                 \
655                                           &lur->lur_update_rec.ur_ops,  \
656                                   &lur->lur_update_rec.ur_update_count, \
657                                   &avail_op_size,                       \
658                                   tur->tur_update_params,               \
659                                   &tur->tur_update_param_count,         \
660                                   &avail_param_size, __VA_ARGS__);      \
661                 if (ret == -E2BIG) {                                    \
662                         ret = tur_update_extend(tur, avail_op_size,     \
663                                                    avail_param_size);   \
664                         if (ret != 0)                                   \
665                                 break;                                  \
666                         continue;                                       \
667                 } else {                                                \
668                         break;                                          \
669                 }                                                       \
670         }                                                               \
671         ret;                                                            \
672 })
673 #endif