Commit | Line | Data |
---|---|---|
d7e09d03 PT |
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.sun.com/software/products/lustre/docs/GPLv2.pdf | |
19 | * | |
20 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
21 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
22 | * have any questions. | |
23 | * | |
24 | * GPL HEADER END | |
25 | */ | |
26 | /* | |
27 | * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. | |
28 | * Use is subject to license terms. | |
29 | * | |
30 | * Copyright (c) 2011, 2012, Intel Corporation. | |
31 | */ | |
32 | /* | |
33 | * This file is part of Lustre, http://www.lustre.org/ | |
34 | * Lustre is a trademark of Sun Microsystems, Inc. | |
35 | * | |
36 | * lustre/include/lustre_lib.h | |
37 | * | |
38 | * Basic Lustre library routines. | |
39 | */ | |
40 | ||
41 | #ifndef _LUSTRE_LIB_H | |
42 | #define _LUSTRE_LIB_H | |
43 | ||
44 | /** \defgroup lib lib | |
45 | * | |
46 | * @{ | |
47 | */ | |
48 | ||
49 | #include <linux/libcfs/libcfs.h> | |
50 | #include <lustre/lustre_idl.h> | |
51 | #include <lustre_ver.h> | |
52 | #include <lustre_cfg.h> | |
53 | #include <linux/lustre_lib.h> | |
54 | ||
55 | /* target.c */ | |
56 | struct ptlrpc_request; | |
57 | struct obd_export; | |
58 | struct lu_target; | |
59 | struct l_wait_info; | |
60 | #include <lustre_ha.h> | |
61 | #include <lustre_net.h> | |
62 | #include <lvfs.h> | |
63 | ||
64 | ||
65 | int target_pack_pool_reply(struct ptlrpc_request *req); | |
66 | int do_set_info_async(struct obd_import *imp, | |
67 | int opcode, int version, | |
68 | obd_count keylen, void *key, | |
69 | obd_count vallen, void *val, | |
70 | struct ptlrpc_request_set *set); | |
71 | ||
72 | #define OBD_RECOVERY_MAX_TIME (obd_timeout * 18) /* b13079 */ | |
73 | #define OBD_MAX_IOCTL_BUFFER CONFIG_LUSTRE_OBD_MAX_IOCTL_BUFFER | |
74 | ||
75 | void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id); | |
76 | ||
77 | /* client.c */ | |
78 | ||
79 | int client_sanobd_setup(struct obd_device *obddev, struct lustre_cfg* lcfg); | |
80 | struct client_obd *client_conn2cli(struct lustre_handle *conn); | |
81 | ||
82 | struct md_open_data; | |
83 | struct obd_client_handle { | |
d3a8a4e2 JX |
84 | struct lustre_handle och_fh; |
85 | struct lu_fid och_fid; | |
86 | struct md_open_data *och_mod; | |
87 | struct lustre_handle och_lease_handle; /* open lock for lease */ | |
88 | __u32 och_magic; | |
89 | fmode_t och_flags; | |
d7e09d03 PT |
90 | }; |
91 | #define OBD_CLIENT_HANDLE_MAGIC 0xd15ea5ed | |
92 | ||
93 | /* statfs_pack.c */ | |
94 | void statfs_pack(struct obd_statfs *osfs, struct kstatfs *sfs); | |
95 | void statfs_unpack(struct kstatfs *sfs, struct obd_statfs *osfs); | |
96 | ||
97 | /* l_lock.c */ | |
98 | struct lustre_lock { | |
99 | int l_depth; | |
68b636b6 | 100 | struct task_struct *l_owner; |
d7e09d03 PT |
101 | struct semaphore l_sem; |
102 | spinlock_t l_spin; | |
103 | }; | |
104 | ||
105 | void l_lock_init(struct lustre_lock *); | |
106 | void l_lock(struct lustre_lock *); | |
107 | void l_unlock(struct lustre_lock *); | |
108 | int l_has_lock(struct lustre_lock *); | |
109 | ||
110 | /* | |
111 | * For md echo client | |
112 | */ | |
113 | enum md_echo_cmd { | |
114 | ECHO_MD_CREATE = 1, /* Open/Create file on MDT */ | |
115 | ECHO_MD_MKDIR = 2, /* Mkdir on MDT */ | |
116 | ECHO_MD_DESTROY = 3, /* Unlink file on MDT */ | |
117 | ECHO_MD_RMDIR = 4, /* Rmdir on MDT */ | |
118 | ECHO_MD_LOOKUP = 5, /* Lookup on MDT */ | |
119 | ECHO_MD_GETATTR = 6, /* Getattr on MDT */ | |
120 | ECHO_MD_SETATTR = 7, /* Setattr on MDT */ | |
121 | ECHO_MD_ALLOC_FID = 8, /* Get FIDs from MDT */ | |
122 | }; | |
123 | ||
124 | /* | |
125 | * OBD IOCTLS | |
126 | */ | |
127 | #define OBD_IOCTL_VERSION 0x00010004 | |
128 | ||
129 | struct obd_ioctl_data { | |
130 | __u32 ioc_len; | |
131 | __u32 ioc_version; | |
132 | ||
133 | union { | |
134 | __u64 ioc_cookie; | |
135 | __u64 ioc_u64_1; | |
136 | }; | |
137 | union { | |
138 | __u32 ioc_conn1; | |
139 | __u32 ioc_u32_1; | |
140 | }; | |
141 | union { | |
142 | __u32 ioc_conn2; | |
143 | __u32 ioc_u32_2; | |
144 | }; | |
145 | ||
146 | struct obdo ioc_obdo1; | |
147 | struct obdo ioc_obdo2; | |
148 | ||
149 | obd_size ioc_count; | |
150 | obd_off ioc_offset; | |
151 | __u32 ioc_dev; | |
152 | __u32 ioc_command; | |
153 | ||
154 | __u64 ioc_nid; | |
155 | __u32 ioc_nal; | |
156 | __u32 ioc_type; | |
157 | ||
158 | /* buffers the kernel will treat as user pointers */ | |
159 | __u32 ioc_plen1; | |
160 | char *ioc_pbuf1; | |
161 | __u32 ioc_plen2; | |
162 | char *ioc_pbuf2; | |
163 | ||
164 | /* inline buffers for various arguments */ | |
165 | __u32 ioc_inllen1; | |
166 | char *ioc_inlbuf1; | |
167 | __u32 ioc_inllen2; | |
168 | char *ioc_inlbuf2; | |
169 | __u32 ioc_inllen3; | |
170 | char *ioc_inlbuf3; | |
171 | __u32 ioc_inllen4; | |
172 | char *ioc_inlbuf4; | |
173 | ||
174 | char ioc_bulk[0]; | |
175 | }; | |
176 | ||
177 | struct obd_ioctl_hdr { | |
178 | __u32 ioc_len; | |
179 | __u32 ioc_version; | |
180 | }; | |
181 | ||
182 | static inline int obd_ioctl_packlen(struct obd_ioctl_data *data) | |
183 | { | |
184 | int len = cfs_size_round(sizeof(struct obd_ioctl_data)); | |
185 | len += cfs_size_round(data->ioc_inllen1); | |
186 | len += cfs_size_round(data->ioc_inllen2); | |
187 | len += cfs_size_round(data->ioc_inllen3); | |
188 | len += cfs_size_round(data->ioc_inllen4); | |
189 | return len; | |
190 | } | |
191 | ||
192 | ||
193 | static inline int obd_ioctl_is_invalid(struct obd_ioctl_data *data) | |
194 | { | |
195 | if (data->ioc_len > (1<<30)) { | |
196 | CERROR("OBD ioctl: ioc_len larger than 1<<30\n"); | |
197 | return 1; | |
198 | } | |
199 | if (data->ioc_inllen1 > (1<<30)) { | |
200 | CERROR("OBD ioctl: ioc_inllen1 larger than 1<<30\n"); | |
201 | return 1; | |
202 | } | |
203 | if (data->ioc_inllen2 > (1<<30)) { | |
204 | CERROR("OBD ioctl: ioc_inllen2 larger than 1<<30\n"); | |
205 | return 1; | |
206 | } | |
207 | if (data->ioc_inllen3 > (1<<30)) { | |
208 | CERROR("OBD ioctl: ioc_inllen3 larger than 1<<30\n"); | |
209 | return 1; | |
210 | } | |
211 | if (data->ioc_inllen4 > (1<<30)) { | |
212 | CERROR("OBD ioctl: ioc_inllen4 larger than 1<<30\n"); | |
213 | return 1; | |
214 | } | |
215 | if (data->ioc_inlbuf1 && !data->ioc_inllen1) { | |
216 | CERROR("OBD ioctl: inlbuf1 pointer but 0 length\n"); | |
217 | return 1; | |
218 | } | |
219 | if (data->ioc_inlbuf2 && !data->ioc_inllen2) { | |
220 | CERROR("OBD ioctl: inlbuf2 pointer but 0 length\n"); | |
221 | return 1; | |
222 | } | |
223 | if (data->ioc_inlbuf3 && !data->ioc_inllen3) { | |
224 | CERROR("OBD ioctl: inlbuf3 pointer but 0 length\n"); | |
225 | return 1; | |
226 | } | |
227 | if (data->ioc_inlbuf4 && !data->ioc_inllen4) { | |
228 | CERROR("OBD ioctl: inlbuf4 pointer but 0 length\n"); | |
229 | return 1; | |
230 | } | |
231 | if (data->ioc_pbuf1 && !data->ioc_plen1) { | |
232 | CERROR("OBD ioctl: pbuf1 pointer but 0 length\n"); | |
233 | return 1; | |
234 | } | |
235 | if (data->ioc_pbuf2 && !data->ioc_plen2) { | |
236 | CERROR("OBD ioctl: pbuf2 pointer but 0 length\n"); | |
237 | return 1; | |
238 | } | |
239 | if (data->ioc_plen1 && !data->ioc_pbuf1) { | |
240 | CERROR("OBD ioctl: plen1 set but NULL pointer\n"); | |
241 | return 1; | |
242 | } | |
243 | if (data->ioc_plen2 && !data->ioc_pbuf2) { | |
244 | CERROR("OBD ioctl: plen2 set but NULL pointer\n"); | |
245 | return 1; | |
246 | } | |
247 | if (obd_ioctl_packlen(data) > data->ioc_len) { | |
248 | CERROR("OBD ioctl: packlen exceeds ioc_len (%d > %d)\n", | |
249 | obd_ioctl_packlen(data), data->ioc_len); | |
250 | return 1; | |
251 | } | |
252 | return 0; | |
253 | } | |
254 | ||
255 | ||
256 | #include <obd_support.h> | |
257 | ||
258 | /* function defined in lustre/obdclass/<platform>/<platform>-module.c */ | |
259 | int obd_ioctl_getdata(char **buf, int *len, void *arg); | |
260 | int obd_ioctl_popdata(void *arg, void *data, int len); | |
261 | ||
262 | static inline void obd_ioctl_freedata(char *buf, int len) | |
263 | { | |
d7e09d03 | 264 | OBD_FREE_LARGE(buf, len); |
d7e09d03 PT |
265 | return; |
266 | } | |
267 | ||
268 | /* | |
269 | * BSD ioctl description: | |
270 | * #define IOC_V1 _IOR(g, n1, long) | |
271 | * #define IOC_V2 _IOW(g, n2, long) | |
272 | * | |
273 | * ioctl(f, IOC_V1, arg); | |
274 | * arg will be treated as a long value, | |
275 | * | |
276 | * ioctl(f, IOC_V2, arg) | |
277 | * arg will be treated as a pointer, bsd will call | |
278 | * copyin(buf, arg, sizeof(long)) | |
279 | * | |
280 | * To make BSD ioctl handles argument correctly and simplely, | |
281 | * we change _IOR to _IOWR so BSD will copyin obd_ioctl_data | |
282 | * for us. Does this change affect Linux? (XXX Liang) | |
283 | */ | |
284 | #define OBD_IOC_CREATE _IOWR('f', 101, OBD_IOC_DATA_TYPE) | |
285 | #define OBD_IOC_DESTROY _IOW ('f', 104, OBD_IOC_DATA_TYPE) | |
286 | #define OBD_IOC_PREALLOCATE _IOWR('f', 105, OBD_IOC_DATA_TYPE) | |
287 | ||
288 | #define OBD_IOC_SETATTR _IOW ('f', 107, OBD_IOC_DATA_TYPE) | |
289 | #define OBD_IOC_GETATTR _IOWR ('f', 108, OBD_IOC_DATA_TYPE) | |
290 | #define OBD_IOC_READ _IOWR('f', 109, OBD_IOC_DATA_TYPE) | |
291 | #define OBD_IOC_WRITE _IOWR('f', 110, OBD_IOC_DATA_TYPE) | |
292 | ||
293 | ||
294 | #define OBD_IOC_STATFS _IOWR('f', 113, OBD_IOC_DATA_TYPE) | |
295 | #define OBD_IOC_SYNC _IOW ('f', 114, OBD_IOC_DATA_TYPE) | |
296 | #define OBD_IOC_READ2 _IOWR('f', 115, OBD_IOC_DATA_TYPE) | |
297 | #define OBD_IOC_FORMAT _IOWR('f', 116, OBD_IOC_DATA_TYPE) | |
298 | #define OBD_IOC_PARTITION _IOWR('f', 117, OBD_IOC_DATA_TYPE) | |
299 | #define OBD_IOC_COPY _IOWR('f', 120, OBD_IOC_DATA_TYPE) | |
300 | #define OBD_IOC_MIGR _IOWR('f', 121, OBD_IOC_DATA_TYPE) | |
301 | #define OBD_IOC_PUNCH _IOWR('f', 122, OBD_IOC_DATA_TYPE) | |
302 | ||
303 | #define OBD_IOC_MODULE_DEBUG _IOWR('f', 124, OBD_IOC_DATA_TYPE) | |
304 | #define OBD_IOC_BRW_READ _IOWR('f', 125, OBD_IOC_DATA_TYPE) | |
305 | #define OBD_IOC_BRW_WRITE _IOWR('f', 126, OBD_IOC_DATA_TYPE) | |
306 | #define OBD_IOC_NAME2DEV _IOWR('f', 127, OBD_IOC_DATA_TYPE) | |
307 | #define OBD_IOC_UUID2DEV _IOWR('f', 130, OBD_IOC_DATA_TYPE) | |
308 | ||
309 | #define OBD_IOC_GETNAME _IOWR('f', 131, OBD_IOC_DATA_TYPE) | |
310 | #define OBD_IOC_GETMDNAME _IOR('f', 131, char[MAX_OBD_NAME]) | |
311 | #define OBD_IOC_GETDTNAME OBD_IOC_GETNAME | |
312 | ||
313 | #define OBD_IOC_LOV_GET_CONFIG _IOWR('f', 132, OBD_IOC_DATA_TYPE) | |
314 | #define OBD_IOC_CLIENT_RECOVER _IOW ('f', 133, OBD_IOC_DATA_TYPE) | |
315 | #define OBD_IOC_PING_TARGET _IOW ('f', 136, OBD_IOC_DATA_TYPE) | |
316 | ||
317 | #define OBD_IOC_DEC_FS_USE_COUNT _IO ('f', 139 ) | |
318 | #define OBD_IOC_NO_TRANSNO _IOW ('f', 140, OBD_IOC_DATA_TYPE) | |
319 | #define OBD_IOC_SET_READONLY _IOW ('f', 141, OBD_IOC_DATA_TYPE) | |
320 | #define OBD_IOC_ABORT_RECOVERY _IOR ('f', 142, OBD_IOC_DATA_TYPE) | |
321 | ||
322 | #define OBD_IOC_ROOT_SQUASH _IOWR('f', 143, OBD_IOC_DATA_TYPE) | |
323 | ||
324 | #define OBD_GET_VERSION _IOWR ('f', 144, OBD_IOC_DATA_TYPE) | |
325 | ||
326 | #define OBD_IOC_GSS_SUPPORT _IOWR('f', 145, OBD_IOC_DATA_TYPE) | |
327 | ||
328 | #define OBD_IOC_CLOSE_UUID _IOWR ('f', 147, OBD_IOC_DATA_TYPE) | |
329 | ||
330 | #define OBD_IOC_CHANGELOG_SEND _IOW ('f', 148, OBD_IOC_DATA_TYPE) | |
331 | #define OBD_IOC_GETDEVICE _IOWR ('f', 149, OBD_IOC_DATA_TYPE) | |
332 | #define OBD_IOC_FID2PATH _IOWR ('f', 150, OBD_IOC_DATA_TYPE) | |
333 | /* see also <lustre/lustre_user.h> for ioctls 151-153 */ | |
334 | /* OBD_IOC_LOV_SETSTRIPE: See also LL_IOC_LOV_SETSTRIPE */ | |
335 | #define OBD_IOC_LOV_SETSTRIPE _IOW ('f', 154, OBD_IOC_DATA_TYPE) | |
336 | /* OBD_IOC_LOV_GETSTRIPE: See also LL_IOC_LOV_GETSTRIPE */ | |
337 | #define OBD_IOC_LOV_GETSTRIPE _IOW ('f', 155, OBD_IOC_DATA_TYPE) | |
338 | /* OBD_IOC_LOV_SETEA: See also LL_IOC_LOV_SETEA */ | |
339 | #define OBD_IOC_LOV_SETEA _IOW ('f', 156, OBD_IOC_DATA_TYPE) | |
340 | /* see <lustre/lustre_user.h> for ioctls 157-159 */ | |
341 | /* OBD_IOC_QUOTACHECK: See also LL_IOC_QUOTACHECK */ | |
342 | #define OBD_IOC_QUOTACHECK _IOW ('f', 160, int) | |
343 | /* OBD_IOC_POLL_QUOTACHECK: See also LL_IOC_POLL_QUOTACHECK */ | |
344 | #define OBD_IOC_POLL_QUOTACHECK _IOR ('f', 161, struct if_quotacheck *) | |
345 | /* OBD_IOC_QUOTACTL: See also LL_IOC_QUOTACTL */ | |
346 | #define OBD_IOC_QUOTACTL _IOWR('f', 162, struct if_quotactl) | |
347 | /* see also <lustre/lustre_user.h> for ioctls 163-176 */ | |
348 | #define OBD_IOC_CHANGELOG_REG _IOW ('f', 177, struct obd_ioctl_data) | |
349 | #define OBD_IOC_CHANGELOG_DEREG _IOW ('f', 178, struct obd_ioctl_data) | |
350 | #define OBD_IOC_CHANGELOG_CLEAR _IOW ('f', 179, struct obd_ioctl_data) | |
351 | #define OBD_IOC_RECORD _IOWR('f', 180, OBD_IOC_DATA_TYPE) | |
352 | #define OBD_IOC_ENDRECORD _IOWR('f', 181, OBD_IOC_DATA_TYPE) | |
353 | #define OBD_IOC_PARSE _IOWR('f', 182, OBD_IOC_DATA_TYPE) | |
354 | #define OBD_IOC_DORECORD _IOWR('f', 183, OBD_IOC_DATA_TYPE) | |
355 | #define OBD_IOC_PROCESS_CFG _IOWR('f', 184, OBD_IOC_DATA_TYPE) | |
356 | #define OBD_IOC_DUMP_LOG _IOWR('f', 185, OBD_IOC_DATA_TYPE) | |
357 | #define OBD_IOC_CLEAR_LOG _IOWR('f', 186, OBD_IOC_DATA_TYPE) | |
358 | #define OBD_IOC_PARAM _IOW ('f', 187, OBD_IOC_DATA_TYPE) | |
359 | #define OBD_IOC_POOL _IOWR('f', 188, OBD_IOC_DATA_TYPE) | |
360 | #define OBD_IOC_REPLACE_NIDS _IOWR('f', 189, OBD_IOC_DATA_TYPE) | |
361 | ||
362 | #define OBD_IOC_CATLOGLIST _IOWR('f', 190, OBD_IOC_DATA_TYPE) | |
363 | #define OBD_IOC_LLOG_INFO _IOWR('f', 191, OBD_IOC_DATA_TYPE) | |
364 | #define OBD_IOC_LLOG_PRINT _IOWR('f', 192, OBD_IOC_DATA_TYPE) | |
365 | #define OBD_IOC_LLOG_CANCEL _IOWR('f', 193, OBD_IOC_DATA_TYPE) | |
366 | #define OBD_IOC_LLOG_REMOVE _IOWR('f', 194, OBD_IOC_DATA_TYPE) | |
367 | #define OBD_IOC_LLOG_CHECK _IOWR('f', 195, OBD_IOC_DATA_TYPE) | |
368 | /* OBD_IOC_LLOG_CATINFO is deprecated */ | |
369 | #define OBD_IOC_LLOG_CATINFO _IOWR('f', 196, OBD_IOC_DATA_TYPE) | |
370 | ||
371 | #define ECHO_IOC_GET_STRIPE _IOWR('f', 200, OBD_IOC_DATA_TYPE) | |
372 | #define ECHO_IOC_SET_STRIPE _IOWR('f', 201, OBD_IOC_DATA_TYPE) | |
373 | #define ECHO_IOC_ENQUEUE _IOWR('f', 202, OBD_IOC_DATA_TYPE) | |
374 | #define ECHO_IOC_CANCEL _IOWR('f', 203, OBD_IOC_DATA_TYPE) | |
375 | ||
376 | #define OBD_IOC_GET_OBJ_VERSION _IOR('f', 210, OBD_IOC_DATA_TYPE) | |
377 | ||
378 | /* <lustre/lustre_user.h> defines ioctl number 218-219 */ | |
379 | #define OBD_IOC_GET_MNTOPT _IOW('f', 220, mntopt_t) | |
380 | ||
381 | #define OBD_IOC_ECHO_MD _IOR('f', 221, struct obd_ioctl_data) | |
382 | #define OBD_IOC_ECHO_ALLOC_SEQ _IOWR('f', 222, struct obd_ioctl_data) | |
383 | ||
384 | #define OBD_IOC_START_LFSCK _IOWR('f', 230, OBD_IOC_DATA_TYPE) | |
385 | #define OBD_IOC_STOP_LFSCK _IOW('f', 231, OBD_IOC_DATA_TYPE) | |
386 | #define OBD_IOC_PAUSE_LFSCK _IOW('f', 232, OBD_IOC_DATA_TYPE) | |
387 | ||
388 | /* XXX _IOWR('f', 250, long) has been defined in | |
389 | * libcfs/include/libcfs/libcfs_private.h for debug, don't use it | |
390 | */ | |
391 | ||
392 | /* Until such time as we get_info the per-stripe maximum from the OST, | |
393 | * we define this to be 2T - 4k, which is the ext3 maxbytes. */ | |
394 | #define LUSTRE_STRIPE_MAXBYTES 0x1fffffff000ULL | |
395 | ||
396 | /* Special values for remove LOV EA from disk */ | |
397 | #define LOVEA_DELETE_VALUES(size, count, offset) (size == 0 && count == 0 && \ | |
398 | offset == (typeof(offset))(-1)) | |
399 | ||
400 | /* #define POISON_BULK 0 */ | |
401 | ||
402 | /* | |
403 | * l_wait_event is a flexible sleeping function, permitting simple caller | |
404 | * configuration of interrupt and timeout sensitivity along with actions to | |
405 | * be performed in the event of either exception. | |
406 | * | |
407 | * The first form of usage looks like this: | |
408 | * | |
409 | * struct l_wait_info lwi = LWI_TIMEOUT_INTR(timeout, timeout_handler, | |
410 | * intr_handler, callback_data); | |
411 | * rc = l_wait_event(waitq, condition, &lwi); | |
412 | * | |
413 | * l_wait_event() makes the current process wait on 'waitq' until 'condition' | |
414 | * is TRUE or a "killable" signal (SIGTERM, SIKGILL, SIGINT) is pending. It | |
415 | * returns 0 to signify 'condition' is TRUE, but if a signal wakes it before | |
416 | * 'condition' becomes true, it optionally calls the specified 'intr_handler' | |
417 | * if not NULL, and returns -EINTR. | |
418 | * | |
419 | * If a non-zero timeout is specified, signals are ignored until the timeout | |
420 | * has expired. At this time, if 'timeout_handler' is not NULL it is called. | |
421 | * If it returns FALSE l_wait_event() continues to wait as described above with | |
422 | * signals enabled. Otherwise it returns -ETIMEDOUT. | |
423 | * | |
424 | * LWI_INTR(intr_handler, callback_data) is shorthand for | |
425 | * LWI_TIMEOUT_INTR(0, NULL, intr_handler, callback_data) | |
426 | * | |
427 | * The second form of usage looks like this: | |
428 | * | |
429 | * struct l_wait_info lwi = LWI_TIMEOUT(timeout, timeout_handler); | |
430 | * rc = l_wait_event(waitq, condition, &lwi); | |
431 | * | |
432 | * This form is the same as the first except that it COMPLETELY IGNORES | |
433 | * SIGNALS. The caller must therefore beware that if 'timeout' is zero, or if | |
434 | * 'timeout_handler' is not NULL and returns FALSE, then the ONLY thing that | |
435 | * can unblock the current process is 'condition' becoming TRUE. | |
436 | * | |
437 | * Another form of usage is: | |
438 | * struct l_wait_info lwi = LWI_TIMEOUT_INTERVAL(timeout, interval, | |
439 | * timeout_handler); | |
440 | * rc = l_wait_event(waitq, condition, &lwi); | |
441 | * This is the same as previous case, but condition is checked once every | |
442 | * 'interval' jiffies (if non-zero). | |
443 | * | |
444 | * Subtle synchronization point: this macro does *not* necessary takes | |
445 | * wait-queue spin-lock before returning, and, hence, following idiom is safe | |
446 | * ONLY when caller provides some external locking: | |
447 | * | |
448 | * Thread1 Thread2 | |
449 | * | |
450 | * l_wait_event(&obj->wq, ....); (1) | |
451 | * | |
452 | * wake_up(&obj->wq): (2) | |
453 | * spin_lock(&q->lock); (2.1) | |
454 | * __wake_up_common(q, ...); (2.2) | |
455 | * spin_unlock(&q->lock, flags); (2.3) | |
456 | * | |
457 | * OBD_FREE_PTR(obj); (3) | |
458 | * | |
459 | * As l_wait_event() may "short-cut" execution and return without taking | |
460 | * wait-queue spin-lock, some additional synchronization is necessary to | |
461 | * guarantee that step (3) can begin only after (2.3) finishes. | |
462 | * | |
463 | * XXX nikita: some ptlrpc daemon threads have races of that sort. | |
464 | * | |
465 | */ | |
466 | static inline int back_to_sleep(void *arg) | |
467 | { | |
468 | return 0; | |
469 | } | |
470 | ||
471 | #define LWI_ON_SIGNAL_NOOP ((void (*)(void *))(-1)) | |
472 | ||
473 | struct l_wait_info { | |
474 | cfs_duration_t lwi_timeout; | |
475 | cfs_duration_t lwi_interval; | |
476 | int lwi_allow_intr; | |
477 | int (*lwi_on_timeout)(void *); | |
478 | void (*lwi_on_signal)(void *); | |
479 | void *lwi_cb_data; | |
480 | }; | |
481 | ||
482 | /* NB: LWI_TIMEOUT ignores signals completely */ | |
483 | #define LWI_TIMEOUT(time, cb, data) \ | |
484 | ((struct l_wait_info) { \ | |
485 | .lwi_timeout = time, \ | |
486 | .lwi_on_timeout = cb, \ | |
487 | .lwi_cb_data = data, \ | |
488 | .lwi_interval = 0, \ | |
489 | .lwi_allow_intr = 0 \ | |
490 | }) | |
491 | ||
492 | #define LWI_TIMEOUT_INTERVAL(time, interval, cb, data) \ | |
493 | ((struct l_wait_info) { \ | |
494 | .lwi_timeout = time, \ | |
495 | .lwi_on_timeout = cb, \ | |
496 | .lwi_cb_data = data, \ | |
497 | .lwi_interval = interval, \ | |
498 | .lwi_allow_intr = 0 \ | |
499 | }) | |
500 | ||
501 | #define LWI_TIMEOUT_INTR(time, time_cb, sig_cb, data) \ | |
502 | ((struct l_wait_info) { \ | |
503 | .lwi_timeout = time, \ | |
504 | .lwi_on_timeout = time_cb, \ | |
505 | .lwi_on_signal = sig_cb, \ | |
506 | .lwi_cb_data = data, \ | |
507 | .lwi_interval = 0, \ | |
508 | .lwi_allow_intr = 0 \ | |
509 | }) | |
510 | ||
511 | #define LWI_TIMEOUT_INTR_ALL(time, time_cb, sig_cb, data) \ | |
512 | ((struct l_wait_info) { \ | |
513 | .lwi_timeout = time, \ | |
514 | .lwi_on_timeout = time_cb, \ | |
515 | .lwi_on_signal = sig_cb, \ | |
516 | .lwi_cb_data = data, \ | |
517 | .lwi_interval = 0, \ | |
518 | .lwi_allow_intr = 1 \ | |
519 | }) | |
520 | ||
521 | #define LWI_INTR(cb, data) LWI_TIMEOUT_INTR(0, NULL, cb, data) | |
522 | ||
523 | ||
524 | /* | |
525 | * wait for @condition to become true, but no longer than timeout, specified | |
526 | * by @info. | |
527 | */ | |
528 | #define __l_wait_event(wq, condition, info, ret, l_add_wait) \ | |
529 | do { \ | |
530 | wait_queue_t __wait; \ | |
531 | cfs_duration_t __timeout = info->lwi_timeout; \ | |
532 | sigset_t __blocked; \ | |
533 | int __allow_intr = info->lwi_allow_intr; \ | |
534 | \ | |
535 | ret = 0; \ | |
536 | if (condition) \ | |
537 | break; \ | |
538 | \ | |
9e795d35 | 539 | init_waitqueue_entry(&__wait, current); \ |
d7e09d03 PT |
540 | l_add_wait(&wq, &__wait); \ |
541 | \ | |
542 | /* Block all signals (just the non-fatal ones if no timeout). */ \ | |
543 | if (info->lwi_on_signal != NULL && (__timeout == 0 || __allow_intr)) \ | |
544 | __blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS); \ | |
545 | else \ | |
546 | __blocked = cfs_block_sigsinv(0); \ | |
547 | \ | |
548 | for (;;) { \ | |
549 | unsigned __wstate; \ | |
550 | \ | |
551 | __wstate = info->lwi_on_signal != NULL && \ | |
552 | (__timeout == 0 || __allow_intr) ? \ | |
553 | TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE; \ | |
554 | \ | |
555 | set_current_state(TASK_INTERRUPTIBLE); \ | |
556 | \ | |
557 | if (condition) \ | |
558 | break; \ | |
559 | \ | |
560 | if (__timeout == 0) { \ | |
561 | waitq_wait(&__wait, __wstate); \ | |
562 | } else { \ | |
563 | cfs_duration_t interval = info->lwi_interval? \ | |
564 | min_t(cfs_duration_t, \ | |
565 | info->lwi_interval,__timeout):\ | |
566 | __timeout; \ | |
567 | cfs_duration_t remaining = waitq_timedwait(&__wait,\ | |
568 | __wstate, \ | |
569 | interval); \ | |
570 | __timeout = cfs_time_sub(__timeout, \ | |
571 | cfs_time_sub(interval, remaining));\ | |
572 | if (__timeout == 0) { \ | |
573 | if (info->lwi_on_timeout == NULL || \ | |
574 | info->lwi_on_timeout(info->lwi_cb_data)) { \ | |
575 | ret = -ETIMEDOUT; \ | |
576 | break; \ | |
577 | } \ | |
578 | /* Take signals after the timeout expires. */ \ | |
579 | if (info->lwi_on_signal != NULL) \ | |
580 | (void)cfs_block_sigsinv(LUSTRE_FATAL_SIGS);\ | |
581 | } \ | |
582 | } \ | |
583 | \ | |
584 | if (condition) \ | |
585 | break; \ | |
586 | if (cfs_signal_pending()) { \ | |
587 | if (info->lwi_on_signal != NULL && \ | |
588 | (__timeout == 0 || __allow_intr)) { \ | |
589 | if (info->lwi_on_signal != LWI_ON_SIGNAL_NOOP) \ | |
590 | info->lwi_on_signal(info->lwi_cb_data);\ | |
591 | ret = -EINTR; \ | |
592 | break; \ | |
593 | } \ | |
594 | /* We have to do this here because some signals */ \ | |
595 | /* are not blockable - ie from strace(1). */ \ | |
596 | /* In these cases we want to schedule_timeout() */ \ | |
597 | /* again, because we don't want that to return */ \ | |
598 | /* -EINTR when the RPC actually succeeded. */ \ | |
599 | /* the recalc_sigpending() below will deliver the */ \ | |
600 | /* signal properly. */ \ | |
601 | cfs_clear_sigpending(); \ | |
602 | } \ | |
603 | } \ | |
604 | \ | |
605 | cfs_restore_sigs(__blocked); \ | |
606 | \ | |
607 | set_current_state(TASK_RUNNING); \ | |
608 | remove_wait_queue(&wq, &__wait); \ | |
609 | } while (0) | |
610 | ||
611 | ||
612 | ||
613 | #define l_wait_event(wq, condition, info) \ | |
614 | ({ \ | |
615 | int __ret; \ | |
616 | struct l_wait_info *__info = (info); \ | |
617 | \ | |
618 | __l_wait_event(wq, condition, __info, \ | |
619 | __ret, add_wait_queue); \ | |
620 | __ret; \ | |
621 | }) | |
622 | ||
623 | #define l_wait_event_exclusive(wq, condition, info) \ | |
624 | ({ \ | |
625 | int __ret; \ | |
626 | struct l_wait_info *__info = (info); \ | |
627 | \ | |
628 | __l_wait_event(wq, condition, __info, \ | |
629 | __ret, add_wait_queue_exclusive); \ | |
630 | __ret; \ | |
631 | }) | |
632 | ||
633 | #define l_wait_event_exclusive_head(wq, condition, info) \ | |
634 | ({ \ | |
635 | int __ret; \ | |
636 | struct l_wait_info *__info = (info); \ | |
637 | \ | |
638 | __l_wait_event(wq, condition, __info, \ | |
639 | __ret, add_wait_queue_exclusive_head); \ | |
640 | __ret; \ | |
641 | }) | |
642 | ||
643 | #define l_wait_condition(wq, condition) \ | |
644 | ({ \ | |
645 | struct l_wait_info lwi = { 0 }; \ | |
646 | l_wait_event(wq, condition, &lwi); \ | |
647 | }) | |
648 | ||
649 | #define l_wait_condition_exclusive(wq, condition) \ | |
650 | ({ \ | |
651 | struct l_wait_info lwi = { 0 }; \ | |
652 | l_wait_event_exclusive(wq, condition, &lwi); \ | |
653 | }) | |
654 | ||
655 | #define l_wait_condition_exclusive_head(wq, condition) \ | |
656 | ({ \ | |
657 | struct l_wait_info lwi = { 0 }; \ | |
658 | l_wait_event_exclusive_head(wq, condition, &lwi); \ | |
659 | }) | |
660 | ||
661 | #define LIBLUSTRE_CLIENT (0) | |
662 | ||
663 | /** @} lib */ | |
664 | ||
665 | #endif /* _LUSTRE_LIB_H */ |