[go: nahoru, domu]

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
35struct 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};
43
44static inline unsigned long update_size(struct update *update)
45{
46	unsigned long size;
47	int	   i;
48
49	size = cfs_size_round(offsetof(struct update, u_bufs[0]));
50	for (i = 0; i < UPDATE_BUF_COUNT; i++)
51		size += cfs_size_round(update->u_lens[i]);
52
53	return size;
54}
55
56static inline void *update_param_buf(struct update *update, int index,
57				     int *size)
58{
59	int	i;
60	void	*ptr;
61
62	if (index >= UPDATE_BUF_COUNT)
63		return NULL;
64
65	ptr = (char *)update + cfs_size_round(offsetof(struct update,
66						       u_bufs[0]));
67	for (i = 0; i < index; i++) {
68		LASSERT(update->u_lens[i] > 0);
69		ptr += cfs_size_round(update->u_lens[i]);
70	}
71
72	if (size != NULL)
73		*size = update->u_lens[index];
74
75	return ptr;
76}
77
78static inline unsigned long update_buf_size(struct update_buf *buf)
79{
80	unsigned long size;
81	int	   i = 0;
82
83	size = cfs_size_round(offsetof(struct update_buf, ub_bufs[0]));
84	for (i = 0; i < buf->ub_count; i++) {
85		struct update *update;
86
87		update = (struct update *)((char *)buf + size);
88		size += update_size(update);
89	}
90	LASSERT(size <= UPDATE_BUFFER_SIZE);
91	return size;
92}
93
94static inline void *update_buf_get(struct update_buf *buf, int index, int *size)
95{
96	int	count = buf->ub_count;
97	void	*ptr;
98	int	i = 0;
99
100	if (index >= count)
101		return NULL;
102
103	ptr = (char *)buf + cfs_size_round(offsetof(struct update_buf,
104						    ub_bufs[0]));
105	for (i = 0; i < index; i++)
106		ptr += update_size((struct update *)ptr);
107
108	if (size != NULL)
109		*size = update_size((struct update *)ptr);
110
111	return ptr;
112}
113
114static inline void update_init_reply_buf(struct update_reply *reply, int count)
115{
116	reply->ur_version = UPDATE_REPLY_V1;
117	reply->ur_count = count;
118}
119
120static inline void *update_get_buf_internal(struct update_reply *reply,
121					    int index, int *size)
122{
123	char *ptr;
124	int count = reply->ur_count;
125	int i;
126
127	if (index >= count)
128		return NULL;
129
130	ptr = (char *)reply + cfs_size_round(offsetof(struct update_reply,
131					     ur_lens[count]));
132	for (i = 0; i < index; i++) {
133		LASSERT(reply->ur_lens[i] > 0);
134		ptr += cfs_size_round(reply->ur_lens[i]);
135	}
136
137	if (size != NULL)
138		*size = reply->ur_lens[index];
139
140	return ptr;
141}
142
143static inline void update_insert_reply(struct update_reply *reply, void *data,
144				       int data_len, int index, int rc)
145{
146	char *ptr;
147
148	ptr = update_get_buf_internal(reply, index, NULL);
149	LASSERT(ptr != NULL);
150
151	*(int *)ptr = cpu_to_le32(rc);
152	ptr += sizeof(int);
153	if (data_len > 0) {
154		LASSERT(data != NULL);
155		memcpy(ptr, data, data_len);
156	}
157	reply->ur_lens[index] = data_len + sizeof(int);
158}
159
160static inline int update_get_reply_buf(struct update_reply *reply, void **buf,
161				       int index)
162{
163	char *ptr;
164	int  size = 0;
165	int  result;
166
167	ptr = update_get_buf_internal(reply, index, &size);
168	result = *(int *)ptr;
169
170	if (result < 0)
171		return result;
172
173	LASSERT((ptr != NULL && size >= sizeof(int)));
174	*buf = ptr + sizeof(int);
175	return size - sizeof(int);
176}
177
178static inline int update_get_reply_result(struct update_reply *reply,
179					  void **buf, int index)
180{
181	void *ptr;
182	int  size;
183
184	ptr = update_get_buf_internal(reply, index, &size);
185	LASSERT(ptr != NULL && size > sizeof(int));
186	return *(int *)ptr;
187}
188
189#endif
190