Whamcloud - gitweb
d99e14128467f63257a7e19c3b6fda7322a975aa
[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, 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
34 #define OUT_UPDATE_INIT_BUFFER_SIZE     8192
35 #define OUT_UPDATE_REPLY_SIZE   8192
36 struct dt_update_request {
37         struct dt_device                *dur_dt;
38         /* attached itself to thandle */
39         struct list_head                dur_list;
40         int                             dur_flags;
41         /* update request result */
42         int                             dur_rc;
43         /* Current batch(transaction) id */
44         __u64                           dur_batchid;
45         /* Holding the update req */
46         struct object_update_request    *dur_req;
47         int                             dur_req_len;
48         struct list_head                dur_cb_items;
49 };
50
51 static inline unsigned long
52 object_update_param_size(const struct object_update_param *param)
53 {
54         return cfs_size_round(sizeof(*param) + param->oup_len);
55 }
56
57 static inline unsigned long
58 object_update_size(const struct object_update *update)
59 {
60         const struct    object_update_param *param;
61         unsigned long   size;
62         int             i;
63
64         size = offsetof(struct object_update, ou_params[0]);
65         for (i = 0; i < update->ou_params_count; i++) {
66                 param = (struct object_update_param *)((char *)update + size);
67                 size += object_update_param_size(param);
68         }
69
70         return size;
71 }
72
73 static inline void
74 *object_update_param_get(const struct object_update *update, int index,
75                          int *size)
76 {
77         const struct    object_update_param *param;
78         int             i;
79
80         if (index >= update->ou_params_count)
81                 return NULL;
82
83         param = &update->ou_params[0];
84         for (i = 0; i < index; i++)
85                 param = (struct object_update_param *)((char *)param +
86                         object_update_param_size(param));
87
88         if (size != NULL)
89                 *size = param->oup_len;
90
91         if (param->oup_len == 0)
92                 return NULL;
93
94         return (void *)&param->oup_buf[0];
95 }
96
97 static inline unsigned long
98 object_update_request_size(const struct object_update_request *our)
99 {
100         unsigned long size;
101         int        i = 0;
102
103         size = offsetof(struct object_update_request, ourq_updates[0]);
104         for (i = 0; i < our->ourq_count; i++) {
105                 struct object_update *update;
106
107                 update = (struct object_update *)((char *)our + size);
108                 size += object_update_size(update);
109         }
110         return size;
111 }
112
113 static inline struct object_update
114 *object_update_request_get(const struct object_update_request *our,
115                            int index, int *size)
116 {
117         void    *ptr;
118         int     i;
119
120         if (index >= our->ourq_count)
121                 return NULL;
122
123         ptr = (char *)our + offsetof(struct object_update_request,
124                                      ourq_updates[0]);
125         for (i = 0; i < index; i++)
126                 ptr += object_update_size((struct object_update *)ptr);
127
128         if (size != NULL)
129                 *size = object_update_size((struct object_update *)ptr);
130
131         return ptr;
132 }
133
134 static inline void
135 object_update_reply_init(struct object_update_reply *reply, int count)
136 {
137         reply->ourp_magic = UPDATE_REPLY_MAGIC;
138         reply->ourp_count = count;
139 }
140
141 static inline struct object_update_result
142 *object_update_result_get(const struct object_update_reply *reply,
143                           int index, int *size)
144 {
145         char *ptr;
146         int count = reply->ourp_count;
147         int i;
148
149         if (index >= count)
150                 return NULL;
151
152         ptr = (char *)reply +
153               cfs_size_round(offsetof(struct object_update_reply,
154                                       ourp_lens[count]));
155         for (i = 0; i < index; i++) {
156                 LASSERT(reply->ourp_lens[i] > 0);
157                 ptr += cfs_size_round(reply->ourp_lens[i]);
158         }
159
160         if (size != NULL)
161                 *size = reply->ourp_lens[index];
162
163         return (struct object_update_result *)ptr;
164 }
165
166 static inline void
167 object_update_result_insert(struct object_update_reply *reply,
168                             void *data, int data_len, int index,
169                             int rc)
170 {
171         struct object_update_result *update_result;
172         char *ptr;
173
174         update_result = object_update_result_get(reply, index, NULL);
175         LASSERT(update_result != NULL);
176
177         update_result->our_rc = ptlrpc_status_hton(rc);
178         if (data_len > 0) {
179                 LASSERT(data != NULL);
180                 ptr = (char *)update_result +
181                         cfs_size_round(sizeof(struct object_update_reply));
182                 update_result->our_datalen = data_len;
183                 memcpy(ptr, data, data_len);
184         }
185
186         reply->ourp_lens[index] = cfs_size_round(data_len +
187                                         sizeof(struct object_update_result));
188 }
189
190 static inline int
191 object_update_result_data_get(const struct object_update_reply *reply,
192                               struct lu_buf *lbuf, int index)
193 {
194         struct object_update_result *update_result;
195         int  size = 0;
196         int  result;
197
198         LASSERT(lbuf != NULL);
199         update_result = object_update_result_get(reply, index, &size);
200         if (update_result == NULL ||
201             size < cfs_size_round(sizeof(struct object_update_reply)) ||
202             update_result->our_datalen > size)
203                 RETURN(-EFAULT);
204
205         result = ptlrpc_status_ntoh(update_result->our_rc);
206         if (result < 0)
207                 return result;
208
209         lbuf->lb_buf = update_result->our_data;
210         lbuf->lb_len = update_result->our_datalen;
211
212         return 0;
213 }
214
215 static inline void update_inc_batchid(struct dt_update_request *update)
216 {
217         update->dur_batchid++;
218 }
219
220 #endif