Whamcloud - gitweb
861d631dba5a6f085d663122e6d443dc74033dff
[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 #define OUT_UPDATE_REPLY_SIZE           8192
38
39 struct dt_key;
40 struct dt_rec;
41
42 struct update_buffer {
43         struct object_update_request    *ub_req;
44         size_t                          ub_req_size;
45 };
46
47 #define TOP_THANDLE_MAGIC       0x20140917
48 /* {top,sub}_thandle are used to manage distributed transactions which
49  * include updates on several nodes. A top_handle represents the
50  * whole operation, and sub_thandle represents updates on each node. */
51 struct top_thandle {
52         struct thandle          tt_super;
53         __u32                   tt_magic;
54         /* The master sub transaction. */
55         struct thandle          *tt_master_sub_thandle;
56
57         /* Other sub thandle will be listed here. */
58         struct list_head        tt_sub_thandle_list;
59 };
60
61 struct sub_thandle {
62         /* point to the osd/osp_thandle */
63         struct thandle          *st_sub_th;
64         struct list_head        st_sub_list;
65 };
66
67 /**
68  * Tracking the updates being executed on this dt_device.
69  */
70 struct dt_update_request {
71         struct dt_device                *dur_dt;
72         /* attached itself to thandle */
73         int                             dur_flags;
74         /* update request result */
75         int                             dur_rc;
76         /* Current batch(transaction) id */
77         __u64                           dur_batchid;
78         /* Holding object updates */
79         struct update_buffer            dur_buf;
80         struct list_head                dur_cb_items;
81 };
82
83 static inline void
84 *object_update_param_get(const struct object_update *update, size_t index,
85                          size_t *size)
86 {
87         const struct    object_update_param *param;
88         size_t          i;
89
90         if (index >= update->ou_params_count)
91                 return NULL;
92
93         param = &update->ou_params[0];
94         for (i = 0; i < index; i++)
95                 param = (struct object_update_param *)((char *)param +
96                         object_update_param_size(param));
97
98         if (size != NULL)
99                 *size = param->oup_len;
100
101         if (param->oup_len == 0)
102                 return NULL;
103
104         return (void *)&param->oup_buf[0];
105 }
106
107 static inline unsigned long
108 object_update_request_size(const struct object_update_request *our)
109 {
110         unsigned long   size;
111         size_t          i = 0;
112
113         size = offsetof(struct object_update_request, ourq_updates[0]);
114         for (i = 0; i < our->ourq_count; i++) {
115                 struct object_update *update;
116
117                 update = (struct object_update *)((char *)our + size);
118                 size += object_update_size(update);
119         }
120         return size;
121 }
122
123 static inline void
124 object_update_reply_init(struct object_update_reply *reply, size_t count)
125 {
126         reply->ourp_magic = UPDATE_REPLY_MAGIC;
127         reply->ourp_count = count;
128 }
129
130 static inline void
131 object_update_result_insert(struct object_update_reply *reply,
132                             void *data, size_t data_len, size_t index,
133                             int rc)
134 {
135         struct object_update_result *update_result;
136         char *ptr;
137
138         update_result = object_update_result_get(reply, index, NULL);
139         LASSERT(update_result != NULL);
140
141         update_result->our_rc = ptlrpc_status_hton(rc);
142         if (data_len > 0) {
143                 LASSERT(data != NULL);
144                 ptr = (char *)update_result +
145                         cfs_size_round(sizeof(struct object_update_reply));
146                 update_result->our_datalen = data_len;
147                 memcpy(ptr, data, data_len);
148         }
149
150         reply->ourp_lens[index] = cfs_size_round(data_len +
151                                         sizeof(struct object_update_result));
152 }
153
154 static inline int
155 object_update_result_data_get(const struct object_update_reply *reply,
156                               struct lu_buf *lbuf, size_t index)
157 {
158         struct object_update_result *update_result;
159         size_t size = 0;
160         int    result;
161
162         LASSERT(lbuf != NULL);
163         update_result = object_update_result_get(reply, index, &size);
164         if (update_result == NULL ||
165             size < cfs_size_round(sizeof(struct object_update_reply)) ||
166             update_result->our_datalen > size)
167                 RETURN(-EFAULT);
168
169         result = ptlrpc_status_ntoh(update_result->our_rc);
170         if (result < 0)
171                 return result;
172
173         lbuf->lb_buf = update_result->our_data;
174         lbuf->lb_len = update_result->our_datalen;
175
176         return 0;
177 }
178
179 static inline void update_inc_batchid(struct dt_update_request *update)
180 {
181         update->dur_batchid++;
182 }
183
184 /* target/out_lib.c */
185 void dt_update_request_destroy(struct dt_update_request *update);
186 struct dt_update_request *dt_update_request_create(struct dt_device *dt);
187
188 int out_update_pack(const struct lu_env *env, struct update_buffer *ubuf,
189                     enum update_type op, const struct lu_fid *fid,
190                     int params_count, __u16 *param_sizes, const void **bufs,
191                     __u64 batchid);
192 int out_create_pack(const struct lu_env *env, struct update_buffer *ubuf,
193                     const struct lu_fid *fid, struct lu_attr *attr,
194                     struct dt_allocation_hint *hint,
195                     struct dt_object_format *dof, __u64 batchid);
196 int out_object_destroy_pack(const struct lu_env *env,
197                             struct update_buffer *ubuf,
198                             const struct lu_fid *fid, __u64 batchid);
199 int out_index_delete_pack(const struct lu_env *env, struct update_buffer *ubuf,
200                           const struct lu_fid *fid, const struct dt_key *key,
201                           __u64 batchid);
202 int out_index_insert_pack(const struct lu_env *env, struct update_buffer *ubuf,
203                           const struct lu_fid *fid, const struct dt_rec *rec,
204                           const struct dt_key *key, __u64 batchid);
205 int out_xattr_set_pack(const struct lu_env *env, struct update_buffer *ubuf,
206                        const struct lu_fid *fid, const struct lu_buf *buf,
207                        const char *name, int flag, __u64 batchid);
208 int out_xattr_del_pack(const struct lu_env *env, struct update_buffer *ubuf,
209                        const struct lu_fid *fid, const char *name,
210                        __u64 batchid);
211 int out_attr_set_pack(const struct lu_env *env, struct update_buffer *ubuf,
212                       const struct lu_fid *fid, const struct lu_attr *attr,
213                       __u64 batchid);
214 int out_ref_add_pack(const struct lu_env *env, struct update_buffer *ubuf,
215                      const struct lu_fid *fid, __u64 batchid);
216 int out_ref_del_pack(const struct lu_env *env, struct update_buffer *ubuf,
217                      const struct lu_fid *fid, __u64 batchid);
218 int out_write_pack(const struct lu_env *env, struct update_buffer *ubuf,
219                    const struct lu_fid *fid, const struct lu_buf *buf,
220                    loff_t pos, __u64 batchid);
221 int out_attr_get_pack(const struct lu_env *env, struct update_buffer *ubuf,
222                       const struct lu_fid *fid);
223 int out_index_lookup_pack(const struct lu_env *env, struct update_buffer *ubuf,
224                           const struct lu_fid *fid, struct dt_rec *rec,
225                           const struct dt_key *key);
226 int out_xattr_get_pack(const struct lu_env *env, struct update_buffer *ubuf,
227                        const struct lu_fid *fid, const char *name);
228
229 /* target/update_trans.c */
230 struct thandle *thandle_get_sub_by_dt(const struct lu_env *env,
231                                       struct thandle *th,
232                                       struct dt_device *sub_dt);
233
234 static inline struct thandle *
235 thandle_get_sub(const struct lu_env *env, struct thandle *th,
236                  const struct dt_object *sub_obj)
237 {
238         return thandle_get_sub_by_dt(env, th, lu2dt_dev(sub_obj->do_lu.lo_dev));
239 }
240
241 struct thandle *
242 top_trans_create(const struct lu_env *env, struct dt_device *master_dev);
243
244 int top_trans_start(const struct lu_env *env, struct dt_device *master_dev,
245                     struct thandle *th);
246
247 int top_trans_stop(const struct lu_env *env, struct dt_device *master_dev,
248                    struct thandle *th);
249
250 void top_thandle_destroy(struct top_thandle *top_th);
251 #endif