Whamcloud - gitweb
LU-3529 lod: create striped directory
[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 UPDATE_BUFFER_SIZE      8192
35 struct update_request {
36         struct dt_device        *ur_dt;
37         struct list_head         ur_list; /* attached itself to thandle */
38         int                      ur_flags;
39         int                      ur_rc; /* request result */
40         int                      ur_batchid; /* Current batch(trans) id */
41         struct update_buf       *ur_buf; /* Holding the update req */
42         struct list_head         ur_cb_items;
43 };
44
45 static inline unsigned long update_size(struct update *update)
46 {
47         unsigned long size;
48         int        i;
49
50         size = cfs_size_round(offsetof(struct update, u_bufs[0]));
51         for (i = 0; i < UPDATE_BUF_COUNT; i++)
52                 size += cfs_size_round(update->u_lens[i]);
53
54         return size;
55 }
56
57 static inline void *update_param_buf(struct update *update, int index,
58                                      int *size)
59 {
60         int     i;
61         void    *ptr;
62
63         if (index >= UPDATE_BUF_COUNT)
64                 return NULL;
65
66         if (unlikely(update->u_lens[index] == 0)) {
67                 ptr = NULL;
68         } else {
69                 ptr = (char *)update +
70                       cfs_size_round(offsetof(struct update, u_bufs[0]));
71                 for (i = 0; i < index; i++)
72                         ptr += cfs_size_round(update->u_lens[i]);
73         }
74
75         if (size != NULL)
76                 *size = update->u_lens[index];
77
78         return ptr;
79 }
80
81 static inline unsigned long update_buf_size(struct update_buf *buf)
82 {
83         unsigned long size;
84         int        i = 0;
85
86         size = cfs_size_round(offsetof(struct update_buf, ub_bufs[0]));
87         for (i = 0; i < buf->ub_count; i++) {
88                 struct update *update;
89
90                 update = (struct update *)((char *)buf + size);
91                 size += update_size(update);
92         }
93         LASSERT(size <= UPDATE_BUFFER_SIZE);
94         return size;
95 }
96
97 static inline void *update_buf_get(struct update_buf *buf, int index, int *size)
98 {
99         int     count = buf->ub_count;
100         void    *ptr;
101         int     i = 0;
102
103         if (index >= count)
104                 return NULL;
105
106         ptr = (char *)buf + cfs_size_round(offsetof(struct update_buf,
107                                                     ub_bufs[0]));
108         for (i = 0; i < index; i++)
109                 ptr += update_size((struct update *)ptr);
110
111         if (size != NULL)
112                 *size = update_size((struct update *)ptr);
113
114         return ptr;
115 }
116
117 static inline void update_init_reply_buf(struct update_reply *reply, int count)
118 {
119         reply->ur_version = UPDATE_REPLY_V1;
120         reply->ur_count = count;
121 }
122
123 static inline void *update_get_buf_internal(struct update_reply *reply,
124                                             int index, int *size)
125 {
126         char *ptr;
127         int count = reply->ur_count;
128         int i;
129
130         if (index >= count)
131                 return NULL;
132
133         ptr = (char *)reply + cfs_size_round(offsetof(struct update_reply,
134                                              ur_lens[count]));
135         for (i = 0; i < index; i++) {
136                 LASSERT(reply->ur_lens[i] > 0);
137                 ptr += cfs_size_round(reply->ur_lens[i]);
138         }
139
140         if (size != NULL)
141                 *size = reply->ur_lens[index];
142
143         return ptr;
144 }
145
146 static inline void update_insert_reply(struct update_reply *reply, void *data,
147                                        int data_len, int index, int rc)
148 {
149         char *ptr;
150
151         ptr = update_get_buf_internal(reply, index, NULL);
152         LASSERT(ptr != NULL);
153
154         *(int *)ptr = cpu_to_le32(rc);
155         ptr += sizeof(int);
156         if (data_len > 0) {
157                 LASSERT(data != NULL);
158                 memcpy(ptr, data, data_len);
159         }
160         reply->ur_lens[index] = data_len + sizeof(int);
161 }
162
163 static inline int update_get_reply_buf(struct update_reply *reply,
164                                        struct lu_buf *lbuf, int index)
165 {
166         char *ptr;
167         int  size = 0;
168         int  result;
169
170         LASSERT(lbuf != NULL);
171
172         ptr = update_get_buf_internal(reply, index, &size);
173         LASSERT(ptr != NULL);
174         result = *(int *)ptr;
175
176         if (result < 0)
177                 return result;
178
179         LASSERT(size >= sizeof(int));
180
181         lbuf->lb_buf = ptr + sizeof(int);
182         lbuf->lb_len = size - sizeof(int);
183
184         return 0;
185 }
186
187 static inline int update_get_reply_result(struct update_reply *reply,
188                                           void **buf, int index)
189 {
190         void *ptr;
191         int  size;
192
193         ptr = update_get_buf_internal(reply, index, &size);
194         LASSERT(ptr != NULL && size > sizeof(int));
195         return *(int *)ptr;
196 }
197
198 static inline void update_inc_batchid(struct update_request *update)
199 {
200         update->ur_batchid++;
201 }
202
203 #endif