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