staging: lustre: remove top level ccflags variable
[deliverable/linux.git] / drivers / staging / lustre / lustre / ldlm / ldlm_lockd.c
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) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
29 *
30 * Copyright (c) 2010, 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/ldlm/ldlm_lockd.c
37 *
38 * Author: Peter Braam <braam@clusterfs.com>
39 * Author: Phil Schwan <phil@clusterfs.com>
40 */
41
42 #define DEBUG_SUBSYSTEM S_LDLM
43
44 #include "../../include/linux/libcfs/libcfs.h"
45
46 #include <lustre_dlm.h>
47 #include <obd_class.h>
48 #include <linux/list.h>
49 #include "ldlm_internal.h"
50
51 static int ldlm_num_threads;
52 module_param(ldlm_num_threads, int, 0444);
53 MODULE_PARM_DESC(ldlm_num_threads, "number of DLM service threads to start");
54
55 static char *ldlm_cpts;
56 module_param(ldlm_cpts, charp, 0444);
57 MODULE_PARM_DESC(ldlm_cpts, "CPU partitions ldlm threads should run on");
58
59 extern struct kmem_cache *ldlm_resource_slab;
60 extern struct kmem_cache *ldlm_lock_slab;
61 static struct mutex ldlm_ref_mutex;
62 static int ldlm_refcount;
63
64 struct ldlm_cb_async_args {
65 struct ldlm_cb_set_arg *ca_set_arg;
66 struct ldlm_lock *ca_lock;
67 };
68
69 /* LDLM state */
70
71 static struct ldlm_state *ldlm_state;
72
73 inline cfs_time_t round_timeout(cfs_time_t timeout)
74 {
75 return cfs_time_seconds((int)cfs_duration_sec(cfs_time_sub(timeout, 0)) + 1);
76 }
77
78 /* timeout for initial callback (AST) reply (bz10399) */
79 static inline unsigned int ldlm_get_rq_timeout(void)
80 {
81 /* Non-AT value */
82 unsigned int timeout = min(ldlm_timeout, obd_timeout / 3);
83
84 return timeout < 1 ? 1 : timeout;
85 }
86
87 #define ELT_STOPPED 0
88 #define ELT_READY 1
89 #define ELT_TERMINATE 2
90
91 struct ldlm_bl_pool {
92 spinlock_t blp_lock;
93
94 /*
95 * blp_prio_list is used for callbacks that should be handled
96 * as a priority. It is used for LDLM_FL_DISCARD_DATA requests.
97 * see bug 13843
98 */
99 struct list_head blp_prio_list;
100
101 /*
102 * blp_list is used for all other callbacks which are likely
103 * to take longer to process.
104 */
105 struct list_head blp_list;
106
107 wait_queue_head_t blp_waitq;
108 struct completion blp_comp;
109 atomic_t blp_num_threads;
110 atomic_t blp_busy_threads;
111 int blp_min_threads;
112 int blp_max_threads;
113 };
114
115 struct ldlm_bl_work_item {
116 struct list_head blwi_entry;
117 struct ldlm_namespace *blwi_ns;
118 struct ldlm_lock_desc blwi_ld;
119 struct ldlm_lock *blwi_lock;
120 struct list_head blwi_head;
121 int blwi_count;
122 struct completion blwi_comp;
123 ldlm_cancel_flags_t blwi_flags;
124 int blwi_mem_pressure;
125 };
126
127
128 int ldlm_del_waiting_lock(struct ldlm_lock *lock)
129 {
130 return 0;
131 }
132
133 int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, int timeout)
134 {
135 return 0;
136 }
137
138
139
140 /**
141 * Callback handler for receiving incoming blocking ASTs.
142 *
143 * This can only happen on client side.
144 */
145 void ldlm_handle_bl_callback(struct ldlm_namespace *ns,
146 struct ldlm_lock_desc *ld, struct ldlm_lock *lock)
147 {
148 int do_ast;
149
150 LDLM_DEBUG(lock, "client blocking AST callback handler");
151
152 lock_res_and_lock(lock);
153 lock->l_flags |= LDLM_FL_CBPENDING;
154
155 if (lock->l_flags & LDLM_FL_CANCEL_ON_BLOCK)
156 lock->l_flags |= LDLM_FL_CANCEL;
157
158 do_ast = (!lock->l_readers && !lock->l_writers);
159 unlock_res_and_lock(lock);
160
161 if (do_ast) {
162 CDEBUG(D_DLMTRACE, "Lock %p already unused, calling callback (%p)\n",
163 lock, lock->l_blocking_ast);
164 if (lock->l_blocking_ast != NULL)
165 lock->l_blocking_ast(lock, ld, lock->l_ast_data,
166 LDLM_CB_BLOCKING);
167 } else {
168 CDEBUG(D_DLMTRACE, "Lock %p is referenced, will be cancelled later\n",
169 lock);
170 }
171
172 LDLM_DEBUG(lock, "client blocking callback handler END");
173 LDLM_LOCK_RELEASE(lock);
174 }
175
176 /**
177 * Callback handler for receiving incoming completion ASTs.
178 *
179 * This only can happen on client side.
180 */
181 static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
182 struct ldlm_namespace *ns,
183 struct ldlm_request *dlm_req,
184 struct ldlm_lock *lock)
185 {
186 int lvb_len;
187 LIST_HEAD(ast_list);
188 int rc = 0;
189
190 LDLM_DEBUG(lock, "client completion callback handler START");
191
192 if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CANCEL_BL_CB_RACE)) {
193 int to = cfs_time_seconds(1);
194 while (to > 0) {
195 set_current_state(TASK_INTERRUPTIBLE);
196 schedule_timeout(to);
197 if (lock->l_granted_mode == lock->l_req_mode ||
198 lock->l_flags & LDLM_FL_DESTROYED)
199 break;
200 }
201 }
202
203 lvb_len = req_capsule_get_size(&req->rq_pill, &RMF_DLM_LVB, RCL_CLIENT);
204 if (lvb_len < 0) {
205 LDLM_ERROR(lock, "Fail to get lvb_len, rc = %d", lvb_len);
206 GOTO(out, rc = lvb_len);
207 } else if (lvb_len > 0) {
208 if (lock->l_lvb_len > 0) {
209 /* for extent lock, lvb contains ost_lvb{}. */
210 LASSERT(lock->l_lvb_data != NULL);
211
212 if (unlikely(lock->l_lvb_len < lvb_len)) {
213 LDLM_ERROR(lock, "Replied LVB is larger than "
214 "expectation, expected = %d, "
215 "replied = %d",
216 lock->l_lvb_len, lvb_len);
217 GOTO(out, rc = -EINVAL);
218 }
219 } else if (ldlm_has_layout(lock)) { /* for layout lock, lvb has
220 * variable length */
221 void *lvb_data;
222
223 OBD_ALLOC(lvb_data, lvb_len);
224 if (lvb_data == NULL) {
225 LDLM_ERROR(lock, "No memory: %d.\n", lvb_len);
226 GOTO(out, rc = -ENOMEM);
227 }
228
229 lock_res_and_lock(lock);
230 LASSERT(lock->l_lvb_data == NULL);
231 lock->l_lvb_type = LVB_T_LAYOUT;
232 lock->l_lvb_data = lvb_data;
233 lock->l_lvb_len = lvb_len;
234 unlock_res_and_lock(lock);
235 }
236 }
237
238 lock_res_and_lock(lock);
239 if ((lock->l_flags & LDLM_FL_DESTROYED) ||
240 lock->l_granted_mode == lock->l_req_mode) {
241 /* bug 11300: the lock has already been granted */
242 unlock_res_and_lock(lock);
243 LDLM_DEBUG(lock, "Double grant race happened");
244 GOTO(out, rc = 0);
245 }
246
247 /* If we receive the completion AST before the actual enqueue returned,
248 * then we might need to switch lock modes, resources, or extents. */
249 if (dlm_req->lock_desc.l_granted_mode != lock->l_req_mode) {
250 lock->l_req_mode = dlm_req->lock_desc.l_granted_mode;
251 LDLM_DEBUG(lock, "completion AST, new lock mode");
252 }
253
254 if (lock->l_resource->lr_type != LDLM_PLAIN) {
255 ldlm_convert_policy_to_local(req->rq_export,
256 dlm_req->lock_desc.l_resource.lr_type,
257 &dlm_req->lock_desc.l_policy_data,
258 &lock->l_policy_data);
259 LDLM_DEBUG(lock, "completion AST, new policy data");
260 }
261
262 ldlm_resource_unlink_lock(lock);
263 if (memcmp(&dlm_req->lock_desc.l_resource.lr_name,
264 &lock->l_resource->lr_name,
265 sizeof(lock->l_resource->lr_name)) != 0) {
266 unlock_res_and_lock(lock);
267 rc = ldlm_lock_change_resource(ns, lock,
268 &dlm_req->lock_desc.l_resource.lr_name);
269 if (rc < 0) {
270 LDLM_ERROR(lock, "Failed to allocate resource");
271 GOTO(out, rc);
272 }
273 LDLM_DEBUG(lock, "completion AST, new resource");
274 CERROR("change resource!\n");
275 lock_res_and_lock(lock);
276 }
277
278 if (dlm_req->lock_flags & LDLM_FL_AST_SENT) {
279 /* BL_AST locks are not needed in LRU.
280 * Let ldlm_cancel_lru() be fast. */
281 ldlm_lock_remove_from_lru(lock);
282 lock->l_flags |= LDLM_FL_CBPENDING | LDLM_FL_BL_AST;
283 LDLM_DEBUG(lock, "completion AST includes blocking AST");
284 }
285
286 if (lock->l_lvb_len > 0) {
287 rc = ldlm_fill_lvb(lock, &req->rq_pill, RCL_CLIENT,
288 lock->l_lvb_data, lvb_len);
289 if (rc < 0) {
290 unlock_res_and_lock(lock);
291 GOTO(out, rc);
292 }
293 }
294
295 ldlm_grant_lock(lock, &ast_list);
296 unlock_res_and_lock(lock);
297
298 LDLM_DEBUG(lock, "callback handler finished, about to run_ast_work");
299
300 /* Let Enqueue to call osc_lock_upcall() and initialize
301 * l_ast_data */
302 OBD_FAIL_TIMEOUT(OBD_FAIL_OSC_CP_ENQ_RACE, 2);
303
304 ldlm_run_ast_work(ns, &ast_list, LDLM_WORK_CP_AST);
305
306 LDLM_DEBUG_NOLOCK("client completion callback handler END (lock %p)",
307 lock);
308 GOTO(out, rc);
309
310 out:
311 if (rc < 0) {
312 lock_res_and_lock(lock);
313 lock->l_flags |= LDLM_FL_FAILED;
314 unlock_res_and_lock(lock);
315 wake_up(&lock->l_waitq);
316 }
317 LDLM_LOCK_RELEASE(lock);
318 }
319
320 /**
321 * Callback handler for receiving incoming glimpse ASTs.
322 *
323 * This only can happen on client side. After handling the glimpse AST
324 * we also consider dropping the lock here if it is unused locally for a
325 * long time.
326 */
327 static void ldlm_handle_gl_callback(struct ptlrpc_request *req,
328 struct ldlm_namespace *ns,
329 struct ldlm_request *dlm_req,
330 struct ldlm_lock *lock)
331 {
332 int rc = -ENOSYS;
333
334 LDLM_DEBUG(lock, "client glimpse AST callback handler");
335
336 if (lock->l_glimpse_ast != NULL)
337 rc = lock->l_glimpse_ast(lock, req);
338
339 if (req->rq_repmsg != NULL) {
340 ptlrpc_reply(req);
341 } else {
342 req->rq_status = rc;
343 ptlrpc_error(req);
344 }
345
346 lock_res_and_lock(lock);
347 if (lock->l_granted_mode == LCK_PW &&
348 !lock->l_readers && !lock->l_writers &&
349 cfs_time_after(cfs_time_current(),
350 cfs_time_add(lock->l_last_used,
351 cfs_time_seconds(10)))) {
352 unlock_res_and_lock(lock);
353 if (ldlm_bl_to_thread_lock(ns, NULL, lock))
354 ldlm_handle_bl_callback(ns, NULL, lock);
355
356 return;
357 }
358 unlock_res_and_lock(lock);
359 LDLM_LOCK_RELEASE(lock);
360 }
361
362 static int ldlm_callback_reply(struct ptlrpc_request *req, int rc)
363 {
364 if (req->rq_no_reply)
365 return 0;
366
367 req->rq_status = rc;
368 if (!req->rq_packed_final) {
369 rc = lustre_pack_reply(req, 1, NULL, NULL);
370 if (rc)
371 return rc;
372 }
373 return ptlrpc_reply(req);
374 }
375
376 static int __ldlm_bl_to_thread(struct ldlm_bl_work_item *blwi,
377 ldlm_cancel_flags_t cancel_flags)
378 {
379 struct ldlm_bl_pool *blp = ldlm_state->ldlm_bl_pool;
380
381 spin_lock(&blp->blp_lock);
382 if (blwi->blwi_lock &&
383 blwi->blwi_lock->l_flags & LDLM_FL_DISCARD_DATA) {
384 /* add LDLM_FL_DISCARD_DATA requests to the priority list */
385 list_add_tail(&blwi->blwi_entry, &blp->blp_prio_list);
386 } else {
387 /* other blocking callbacks are added to the regular list */
388 list_add_tail(&blwi->blwi_entry, &blp->blp_list);
389 }
390 spin_unlock(&blp->blp_lock);
391
392 wake_up(&blp->blp_waitq);
393
394 /* can not check blwi->blwi_flags as blwi could be already freed in
395 LCF_ASYNC mode */
396 if (!(cancel_flags & LCF_ASYNC))
397 wait_for_completion(&blwi->blwi_comp);
398
399 return 0;
400 }
401
402 static inline void init_blwi(struct ldlm_bl_work_item *blwi,
403 struct ldlm_namespace *ns,
404 struct ldlm_lock_desc *ld,
405 struct list_head *cancels, int count,
406 struct ldlm_lock *lock,
407 ldlm_cancel_flags_t cancel_flags)
408 {
409 init_completion(&blwi->blwi_comp);
410 INIT_LIST_HEAD(&blwi->blwi_head);
411
412 if (memory_pressure_get())
413 blwi->blwi_mem_pressure = 1;
414
415 blwi->blwi_ns = ns;
416 blwi->blwi_flags = cancel_flags;
417 if (ld != NULL)
418 blwi->blwi_ld = *ld;
419 if (count) {
420 list_add(&blwi->blwi_head, cancels);
421 list_del_init(cancels);
422 blwi->blwi_count = count;
423 } else {
424 blwi->blwi_lock = lock;
425 }
426 }
427
428 /**
429 * Queues a list of locks \a cancels containing \a count locks
430 * for later processing by a blocking thread. If \a count is zero,
431 * then the lock referenced as \a lock is queued instead.
432 *
433 * The blocking thread would then call ->l_blocking_ast callback in the lock.
434 * If list addition fails an error is returned and caller is supposed to
435 * call ->l_blocking_ast itself.
436 */
437 static int ldlm_bl_to_thread(struct ldlm_namespace *ns,
438 struct ldlm_lock_desc *ld,
439 struct ldlm_lock *lock,
440 struct list_head *cancels, int count,
441 ldlm_cancel_flags_t cancel_flags)
442 {
443 if (cancels && count == 0)
444 return 0;
445
446 if (cancel_flags & LCF_ASYNC) {
447 struct ldlm_bl_work_item *blwi;
448
449 OBD_ALLOC(blwi, sizeof(*blwi));
450 if (blwi == NULL)
451 return -ENOMEM;
452 init_blwi(blwi, ns, ld, cancels, count, lock, cancel_flags);
453
454 return __ldlm_bl_to_thread(blwi, cancel_flags);
455 } else {
456 /* if it is synchronous call do minimum mem alloc, as it could
457 * be triggered from kernel shrinker
458 */
459 struct ldlm_bl_work_item blwi;
460
461 memset(&blwi, 0, sizeof(blwi));
462 init_blwi(&blwi, ns, ld, cancels, count, lock, cancel_flags);
463 return __ldlm_bl_to_thread(&blwi, cancel_flags);
464 }
465 }
466
467
468 int ldlm_bl_to_thread_lock(struct ldlm_namespace *ns, struct ldlm_lock_desc *ld,
469 struct ldlm_lock *lock)
470 {
471 return ldlm_bl_to_thread(ns, ld, lock, NULL, 0, LCF_ASYNC);
472 }
473
474 int ldlm_bl_to_thread_list(struct ldlm_namespace *ns, struct ldlm_lock_desc *ld,
475 struct list_head *cancels, int count,
476 ldlm_cancel_flags_t cancel_flags)
477 {
478 return ldlm_bl_to_thread(ns, ld, NULL, cancels, count, cancel_flags);
479 }
480
481 /* Setinfo coming from Server (eg MDT) to Client (eg MDC)! */
482 static int ldlm_handle_setinfo(struct ptlrpc_request *req)
483 {
484 struct obd_device *obd = req->rq_export->exp_obd;
485 char *key;
486 void *val;
487 int keylen, vallen;
488 int rc = -ENOSYS;
489
490 DEBUG_REQ(D_HSM, req, "%s: handle setinfo\n", obd->obd_name);
491
492 req_capsule_set(&req->rq_pill, &RQF_OBD_SET_INFO);
493
494 key = req_capsule_client_get(&req->rq_pill, &RMF_SETINFO_KEY);
495 if (key == NULL) {
496 DEBUG_REQ(D_IOCTL, req, "no set_info key");
497 return -EFAULT;
498 }
499 keylen = req_capsule_get_size(&req->rq_pill, &RMF_SETINFO_KEY,
500 RCL_CLIENT);
501 val = req_capsule_client_get(&req->rq_pill, &RMF_SETINFO_VAL);
502 if (val == NULL) {
503 DEBUG_REQ(D_IOCTL, req, "no set_info val");
504 return -EFAULT;
505 }
506 vallen = req_capsule_get_size(&req->rq_pill, &RMF_SETINFO_VAL,
507 RCL_CLIENT);
508
509 /* We are responsible for swabbing contents of val */
510
511 if (KEY_IS(KEY_HSM_COPYTOOL_SEND))
512 /* Pass it on to mdc (the "export" in this case) */
513 rc = obd_set_info_async(req->rq_svc_thread->t_env,
514 req->rq_export,
515 sizeof(KEY_HSM_COPYTOOL_SEND),
516 KEY_HSM_COPYTOOL_SEND,
517 vallen, val, NULL);
518 else
519 DEBUG_REQ(D_WARNING, req, "ignoring unknown key %s", key);
520
521 return rc;
522 }
523
524 static inline void ldlm_callback_errmsg(struct ptlrpc_request *req,
525 const char *msg, int rc,
526 struct lustre_handle *handle)
527 {
528 DEBUG_REQ((req->rq_no_reply || rc) ? D_WARNING : D_DLMTRACE, req,
529 "%s: [nid %s] [rc %d] [lock "LPX64"]",
530 msg, libcfs_id2str(req->rq_peer), rc,
531 handle ? handle->cookie : 0);
532 if (req->rq_no_reply)
533 CWARN("No reply was sent, maybe cause bug 21636.\n");
534 else if (rc)
535 CWARN("Send reply failed, maybe cause bug 21636.\n");
536 }
537
538 static int ldlm_handle_qc_callback(struct ptlrpc_request *req)
539 {
540 struct obd_quotactl *oqctl;
541 struct client_obd *cli = &req->rq_export->exp_obd->u.cli;
542
543 oqctl = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL);
544 if (oqctl == NULL) {
545 CERROR("Can't unpack obd_quotactl\n");
546 return -EPROTO;
547 }
548
549 oqctl->qc_stat = ptlrpc_status_ntoh(oqctl->qc_stat);
550
551 cli->cl_qchk_stat = oqctl->qc_stat;
552 return 0;
553 }
554
555 /* TODO: handle requests in a similar way as MDT: see mdt_handle_common() */
556 static int ldlm_callback_handler(struct ptlrpc_request *req)
557 {
558 struct ldlm_namespace *ns;
559 struct ldlm_request *dlm_req;
560 struct ldlm_lock *lock;
561 int rc;
562
563 /* Requests arrive in sender's byte order. The ptlrpc service
564 * handler has already checked and, if necessary, byte-swapped the
565 * incoming request message body, but I am responsible for the
566 * message buffers. */
567
568 /* do nothing for sec context finalize */
569 if (lustre_msg_get_opc(req->rq_reqmsg) == SEC_CTX_FINI)
570 return 0;
571
572 req_capsule_init(&req->rq_pill, req, RCL_SERVER);
573
574 if (req->rq_export == NULL) {
575 rc = ldlm_callback_reply(req, -ENOTCONN);
576 ldlm_callback_errmsg(req, "Operate on unconnected server",
577 rc, NULL);
578 return 0;
579 }
580
581 LASSERT(req->rq_export != NULL);
582 LASSERT(req->rq_export->exp_obd != NULL);
583
584 switch (lustre_msg_get_opc(req->rq_reqmsg)) {
585 case LDLM_BL_CALLBACK:
586 if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_BL_CALLBACK_NET))
587 return 0;
588 break;
589 case LDLM_CP_CALLBACK:
590 if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CP_CALLBACK_NET))
591 return 0;
592 break;
593 case LDLM_GL_CALLBACK:
594 if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_GL_CALLBACK_NET))
595 return 0;
596 break;
597 case LDLM_SET_INFO:
598 rc = ldlm_handle_setinfo(req);
599 ldlm_callback_reply(req, rc);
600 return 0;
601 case OBD_QC_CALLBACK:
602 req_capsule_set(&req->rq_pill, &RQF_QC_CALLBACK);
603 if (OBD_FAIL_CHECK(OBD_FAIL_OBD_QC_CALLBACK_NET))
604 return 0;
605 rc = ldlm_handle_qc_callback(req);
606 ldlm_callback_reply(req, rc);
607 return 0;
608 default:
609 CERROR("unknown opcode %u\n",
610 lustre_msg_get_opc(req->rq_reqmsg));
611 ldlm_callback_reply(req, -EPROTO);
612 return 0;
613 }
614
615 ns = req->rq_export->exp_obd->obd_namespace;
616 LASSERT(ns != NULL);
617
618 req_capsule_set(&req->rq_pill, &RQF_LDLM_CALLBACK);
619
620 dlm_req = req_capsule_client_get(&req->rq_pill, &RMF_DLM_REQ);
621 if (dlm_req == NULL) {
622 rc = ldlm_callback_reply(req, -EPROTO);
623 ldlm_callback_errmsg(req, "Operate without parameter", rc,
624 NULL);
625 return 0;
626 }
627
628 /* Force a known safe race, send a cancel to the server for a lock
629 * which the server has already started a blocking callback on. */
630 if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CANCEL_BL_CB_RACE) &&
631 lustre_msg_get_opc(req->rq_reqmsg) == LDLM_BL_CALLBACK) {
632 rc = ldlm_cli_cancel(&dlm_req->lock_handle[0], 0);
633 if (rc < 0)
634 CERROR("ldlm_cli_cancel: %d\n", rc);
635 }
636
637 lock = ldlm_handle2lock_long(&dlm_req->lock_handle[0], 0);
638 if (!lock) {
639 CDEBUG(D_DLMTRACE, "callback on lock "LPX64" - lock "
640 "disappeared\n", dlm_req->lock_handle[0].cookie);
641 rc = ldlm_callback_reply(req, -EINVAL);
642 ldlm_callback_errmsg(req, "Operate with invalid parameter", rc,
643 &dlm_req->lock_handle[0]);
644 return 0;
645 }
646
647 if ((lock->l_flags & LDLM_FL_FAIL_LOC) &&
648 lustre_msg_get_opc(req->rq_reqmsg) == LDLM_BL_CALLBACK)
649 OBD_RACE(OBD_FAIL_LDLM_CP_BL_RACE);
650
651 /* Copy hints/flags (e.g. LDLM_FL_DISCARD_DATA) from AST. */
652 lock_res_and_lock(lock);
653 lock->l_flags |= ldlm_flags_from_wire(dlm_req->lock_flags &
654 LDLM_AST_FLAGS);
655 if (lustre_msg_get_opc(req->rq_reqmsg) == LDLM_BL_CALLBACK) {
656 /* If somebody cancels lock and cache is already dropped,
657 * or lock is failed before cp_ast received on client,
658 * we can tell the server we have no lock. Otherwise, we
659 * should send cancel after dropping the cache. */
660 if (((lock->l_flags & LDLM_FL_CANCELING) &&
661 (lock->l_flags & LDLM_FL_BL_DONE)) ||
662 (lock->l_flags & LDLM_FL_FAILED)) {
663 LDLM_DEBUG(lock, "callback on lock "
664 LPX64" - lock disappeared\n",
665 dlm_req->lock_handle[0].cookie);
666 unlock_res_and_lock(lock);
667 LDLM_LOCK_RELEASE(lock);
668 rc = ldlm_callback_reply(req, -EINVAL);
669 ldlm_callback_errmsg(req, "Operate on stale lock", rc,
670 &dlm_req->lock_handle[0]);
671 return 0;
672 }
673 /* BL_AST locks are not needed in LRU.
674 * Let ldlm_cancel_lru() be fast. */
675 ldlm_lock_remove_from_lru(lock);
676 lock->l_flags |= LDLM_FL_BL_AST;
677 }
678 unlock_res_and_lock(lock);
679
680 /* We want the ost thread to get this reply so that it can respond
681 * to ost requests (write cache writeback) that might be triggered
682 * in the callback.
683 *
684 * But we'd also like to be able to indicate in the reply that we're
685 * cancelling right now, because it's unused, or have an intent result
686 * in the reply, so we might have to push the responsibility for sending
687 * the reply down into the AST handlers, alas. */
688
689 switch (lustre_msg_get_opc(req->rq_reqmsg)) {
690 case LDLM_BL_CALLBACK:
691 CDEBUG(D_INODE, "blocking ast\n");
692 req_capsule_extend(&req->rq_pill, &RQF_LDLM_BL_CALLBACK);
693 if (!(lock->l_flags & LDLM_FL_CANCEL_ON_BLOCK)) {
694 rc = ldlm_callback_reply(req, 0);
695 if (req->rq_no_reply || rc)
696 ldlm_callback_errmsg(req, "Normal process", rc,
697 &dlm_req->lock_handle[0]);
698 }
699 if (ldlm_bl_to_thread_lock(ns, &dlm_req->lock_desc, lock))
700 ldlm_handle_bl_callback(ns, &dlm_req->lock_desc, lock);
701 break;
702 case LDLM_CP_CALLBACK:
703 CDEBUG(D_INODE, "completion ast\n");
704 req_capsule_extend(&req->rq_pill, &RQF_LDLM_CP_CALLBACK);
705 ldlm_callback_reply(req, 0);
706 ldlm_handle_cp_callback(req, ns, dlm_req, lock);
707 break;
708 case LDLM_GL_CALLBACK:
709 CDEBUG(D_INODE, "glimpse ast\n");
710 req_capsule_extend(&req->rq_pill, &RQF_LDLM_GL_CALLBACK);
711 ldlm_handle_gl_callback(req, ns, dlm_req, lock);
712 break;
713 default:
714 LBUG(); /* checked above */
715 }
716
717 return 0;
718 }
719
720
721 static struct ldlm_bl_work_item *ldlm_bl_get_work(struct ldlm_bl_pool *blp)
722 {
723 struct ldlm_bl_work_item *blwi = NULL;
724 static unsigned int num_bl = 0;
725
726 spin_lock(&blp->blp_lock);
727 /* process a request from the blp_list at least every blp_num_threads */
728 if (!list_empty(&blp->blp_list) &&
729 (list_empty(&blp->blp_prio_list) || num_bl == 0))
730 blwi = list_entry(blp->blp_list.next,
731 struct ldlm_bl_work_item, blwi_entry);
732 else
733 if (!list_empty(&blp->blp_prio_list))
734 blwi = list_entry(blp->blp_prio_list.next,
735 struct ldlm_bl_work_item,
736 blwi_entry);
737
738 if (blwi) {
739 if (++num_bl >= atomic_read(&blp->blp_num_threads))
740 num_bl = 0;
741 list_del(&blwi->blwi_entry);
742 }
743 spin_unlock(&blp->blp_lock);
744
745 return blwi;
746 }
747
748 /* This only contains temporary data until the thread starts */
749 struct ldlm_bl_thread_data {
750 char bltd_name[CFS_CURPROC_COMM_MAX];
751 struct ldlm_bl_pool *bltd_blp;
752 struct completion bltd_comp;
753 int bltd_num;
754 };
755
756 static int ldlm_bl_thread_main(void *arg);
757
758 static int ldlm_bl_thread_start(struct ldlm_bl_pool *blp)
759 {
760 struct ldlm_bl_thread_data bltd = { .bltd_blp = blp };
761 struct task_struct *task;
762
763 init_completion(&bltd.bltd_comp);
764 bltd.bltd_num = atomic_read(&blp->blp_num_threads);
765 snprintf(bltd.bltd_name, sizeof(bltd.bltd_name),
766 "ldlm_bl_%02d", bltd.bltd_num);
767 task = kthread_run(ldlm_bl_thread_main, &bltd, "%s", bltd.bltd_name);
768 if (IS_ERR(task)) {
769 CERROR("cannot start LDLM thread ldlm_bl_%02d: rc %ld\n",
770 atomic_read(&blp->blp_num_threads), PTR_ERR(task));
771 return PTR_ERR(task);
772 }
773 wait_for_completion(&bltd.bltd_comp);
774
775 return 0;
776 }
777
778 /**
779 * Main blocking requests processing thread.
780 *
781 * Callers put locks into its queue by calling ldlm_bl_to_thread.
782 * This thread in the end ends up doing actual call to ->l_blocking_ast
783 * for queued locks.
784 */
785 static int ldlm_bl_thread_main(void *arg)
786 {
787 struct ldlm_bl_pool *blp;
788
789 {
790 struct ldlm_bl_thread_data *bltd = arg;
791
792 blp = bltd->bltd_blp;
793
794 atomic_inc(&blp->blp_num_threads);
795 atomic_inc(&blp->blp_busy_threads);
796
797 complete(&bltd->bltd_comp);
798 /* cannot use bltd after this, it is only on caller's stack */
799 }
800
801 while (1) {
802 struct l_wait_info lwi = { 0 };
803 struct ldlm_bl_work_item *blwi = NULL;
804 int busy;
805
806 blwi = ldlm_bl_get_work(blp);
807
808 if (blwi == NULL) {
809 atomic_dec(&blp->blp_busy_threads);
810 l_wait_event_exclusive(blp->blp_waitq,
811 (blwi = ldlm_bl_get_work(blp)) != NULL,
812 &lwi);
813 busy = atomic_inc_return(&blp->blp_busy_threads);
814 } else {
815 busy = atomic_read(&blp->blp_busy_threads);
816 }
817
818 if (blwi->blwi_ns == NULL)
819 /* added by ldlm_cleanup() */
820 break;
821
822 /* Not fatal if racy and have a few too many threads */
823 if (unlikely(busy < blp->blp_max_threads &&
824 busy >= atomic_read(&blp->blp_num_threads) &&
825 !blwi->blwi_mem_pressure))
826 /* discard the return value, we tried */
827 ldlm_bl_thread_start(blp);
828
829 if (blwi->blwi_mem_pressure)
830 memory_pressure_set();
831
832 if (blwi->blwi_count) {
833 int count;
834 /* The special case when we cancel locks in LRU
835 * asynchronously, we pass the list of locks here.
836 * Thus locks are marked LDLM_FL_CANCELING, but NOT
837 * canceled locally yet. */
838 count = ldlm_cli_cancel_list_local(&blwi->blwi_head,
839 blwi->blwi_count,
840 LCF_BL_AST);
841 ldlm_cli_cancel_list(&blwi->blwi_head, count, NULL,
842 blwi->blwi_flags);
843 } else {
844 ldlm_handle_bl_callback(blwi->blwi_ns, &blwi->blwi_ld,
845 blwi->blwi_lock);
846 }
847 if (blwi->blwi_mem_pressure)
848 memory_pressure_clr();
849
850 if (blwi->blwi_flags & LCF_ASYNC)
851 OBD_FREE(blwi, sizeof(*blwi));
852 else
853 complete(&blwi->blwi_comp);
854 }
855
856 atomic_dec(&blp->blp_busy_threads);
857 atomic_dec(&blp->blp_num_threads);
858 complete(&blp->blp_comp);
859 return 0;
860 }
861
862
863 static int ldlm_setup(void);
864 static int ldlm_cleanup(void);
865
866 int ldlm_get_ref(void)
867 {
868 int rc = 0;
869
870 mutex_lock(&ldlm_ref_mutex);
871 if (++ldlm_refcount == 1) {
872 rc = ldlm_setup();
873 if (rc)
874 ldlm_refcount--;
875 }
876 mutex_unlock(&ldlm_ref_mutex);
877
878 return rc;
879 }
880 EXPORT_SYMBOL(ldlm_get_ref);
881
882 void ldlm_put_ref(void)
883 {
884 mutex_lock(&ldlm_ref_mutex);
885 if (ldlm_refcount == 1) {
886 int rc = ldlm_cleanup();
887 if (rc)
888 CERROR("ldlm_cleanup failed: %d\n", rc);
889 else
890 ldlm_refcount--;
891 } else {
892 ldlm_refcount--;
893 }
894 mutex_unlock(&ldlm_ref_mutex);
895 }
896 EXPORT_SYMBOL(ldlm_put_ref);
897
898 /*
899 * Export handle<->lock hash operations.
900 */
901 static unsigned
902 ldlm_export_lock_hash(struct cfs_hash *hs, const void *key, unsigned mask)
903 {
904 return cfs_hash_u64_hash(((struct lustre_handle *)key)->cookie, mask);
905 }
906
907 static void *
908 ldlm_export_lock_key(struct hlist_node *hnode)
909 {
910 struct ldlm_lock *lock;
911
912 lock = hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
913 return &lock->l_remote_handle;
914 }
915
916 static void
917 ldlm_export_lock_keycpy(struct hlist_node *hnode, void *key)
918 {
919 struct ldlm_lock *lock;
920
921 lock = hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
922 lock->l_remote_handle = *(struct lustre_handle *)key;
923 }
924
925 static int
926 ldlm_export_lock_keycmp(const void *key, struct hlist_node *hnode)
927 {
928 return lustre_handle_equal(ldlm_export_lock_key(hnode), key);
929 }
930
931 static void *
932 ldlm_export_lock_object(struct hlist_node *hnode)
933 {
934 return hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
935 }
936
937 static void
938 ldlm_export_lock_get(struct cfs_hash *hs, struct hlist_node *hnode)
939 {
940 struct ldlm_lock *lock;
941
942 lock = hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
943 LDLM_LOCK_GET(lock);
944 }
945
946 static void
947 ldlm_export_lock_put(struct cfs_hash *hs, struct hlist_node *hnode)
948 {
949 struct ldlm_lock *lock;
950
951 lock = hlist_entry(hnode, struct ldlm_lock, l_exp_hash);
952 LDLM_LOCK_RELEASE(lock);
953 }
954
955 static cfs_hash_ops_t ldlm_export_lock_ops = {
956 .hs_hash = ldlm_export_lock_hash,
957 .hs_key = ldlm_export_lock_key,
958 .hs_keycmp = ldlm_export_lock_keycmp,
959 .hs_keycpy = ldlm_export_lock_keycpy,
960 .hs_object = ldlm_export_lock_object,
961 .hs_get = ldlm_export_lock_get,
962 .hs_put = ldlm_export_lock_put,
963 .hs_put_locked = ldlm_export_lock_put,
964 };
965
966 int ldlm_init_export(struct obd_export *exp)
967 {
968 int rc;
969 exp->exp_lock_hash =
970 cfs_hash_create(obd_uuid2str(&exp->exp_client_uuid),
971 HASH_EXP_LOCK_CUR_BITS,
972 HASH_EXP_LOCK_MAX_BITS,
973 HASH_EXP_LOCK_BKT_BITS, 0,
974 CFS_HASH_MIN_THETA, CFS_HASH_MAX_THETA,
975 &ldlm_export_lock_ops,
976 CFS_HASH_DEFAULT | CFS_HASH_REHASH_KEY |
977 CFS_HASH_NBLK_CHANGE);
978
979 if (!exp->exp_lock_hash)
980 return -ENOMEM;
981
982 rc = ldlm_init_flock_export(exp);
983 if (rc)
984 GOTO(err, rc);
985
986 return 0;
987 err:
988 ldlm_destroy_export(exp);
989 return rc;
990 }
991 EXPORT_SYMBOL(ldlm_init_export);
992
993 void ldlm_destroy_export(struct obd_export *exp)
994 {
995 cfs_hash_putref(exp->exp_lock_hash);
996 exp->exp_lock_hash = NULL;
997
998 ldlm_destroy_flock_export(exp);
999 }
1000 EXPORT_SYMBOL(ldlm_destroy_export);
1001
1002 static int ldlm_setup(void)
1003 {
1004 static struct ptlrpc_service_conf conf;
1005 struct ldlm_bl_pool *blp = NULL;
1006 int rc = 0;
1007 int i;
1008
1009 if (ldlm_state != NULL)
1010 return -EALREADY;
1011
1012 OBD_ALLOC(ldlm_state, sizeof(*ldlm_state));
1013 if (ldlm_state == NULL)
1014 return -ENOMEM;
1015
1016 rc = ldlm_proc_setup();
1017 if (rc != 0)
1018 GOTO(out, rc);
1019
1020 memset(&conf, 0, sizeof(conf));
1021 conf = (typeof(conf)) {
1022 .psc_name = "ldlm_cbd",
1023 .psc_watchdog_factor = 2,
1024 .psc_buf = {
1025 .bc_nbufs = LDLM_CLIENT_NBUFS,
1026 .bc_buf_size = LDLM_BUFSIZE,
1027 .bc_req_max_size = LDLM_MAXREQSIZE,
1028 .bc_rep_max_size = LDLM_MAXREPSIZE,
1029 .bc_req_portal = LDLM_CB_REQUEST_PORTAL,
1030 .bc_rep_portal = LDLM_CB_REPLY_PORTAL,
1031 },
1032 .psc_thr = {
1033 .tc_thr_name = "ldlm_cb",
1034 .tc_thr_factor = LDLM_THR_FACTOR,
1035 .tc_nthrs_init = LDLM_NTHRS_INIT,
1036 .tc_nthrs_base = LDLM_NTHRS_BASE,
1037 .tc_nthrs_max = LDLM_NTHRS_MAX,
1038 .tc_nthrs_user = ldlm_num_threads,
1039 .tc_cpu_affinity = 1,
1040 .tc_ctx_tags = LCT_MD_THREAD | LCT_DT_THREAD,
1041 },
1042 .psc_cpt = {
1043 .cc_pattern = ldlm_cpts,
1044 },
1045 .psc_ops = {
1046 .so_req_handler = ldlm_callback_handler,
1047 },
1048 };
1049 ldlm_state->ldlm_cb_service = \
1050 ptlrpc_register_service(&conf, ldlm_svc_proc_dir);
1051 if (IS_ERR(ldlm_state->ldlm_cb_service)) {
1052 CERROR("failed to start service\n");
1053 rc = PTR_ERR(ldlm_state->ldlm_cb_service);
1054 ldlm_state->ldlm_cb_service = NULL;
1055 GOTO(out, rc);
1056 }
1057
1058
1059 OBD_ALLOC(blp, sizeof(*blp));
1060 if (blp == NULL)
1061 GOTO(out, rc = -ENOMEM);
1062 ldlm_state->ldlm_bl_pool = blp;
1063
1064 spin_lock_init(&blp->blp_lock);
1065 INIT_LIST_HEAD(&blp->blp_list);
1066 INIT_LIST_HEAD(&blp->blp_prio_list);
1067 init_waitqueue_head(&blp->blp_waitq);
1068 atomic_set(&blp->blp_num_threads, 0);
1069 atomic_set(&blp->blp_busy_threads, 0);
1070
1071 if (ldlm_num_threads == 0) {
1072 blp->blp_min_threads = LDLM_NTHRS_INIT;
1073 blp->blp_max_threads = LDLM_NTHRS_MAX;
1074 } else {
1075 blp->blp_min_threads = blp->blp_max_threads = \
1076 min_t(int, LDLM_NTHRS_MAX, max_t(int, LDLM_NTHRS_INIT,
1077 ldlm_num_threads));
1078 }
1079
1080 for (i = 0; i < blp->blp_min_threads; i++) {
1081 rc = ldlm_bl_thread_start(blp);
1082 if (rc < 0)
1083 GOTO(out, rc);
1084 }
1085
1086
1087 rc = ldlm_pools_init();
1088 if (rc) {
1089 CERROR("Failed to initialize LDLM pools: %d\n", rc);
1090 GOTO(out, rc);
1091 }
1092 return 0;
1093
1094 out:
1095 ldlm_cleanup();
1096 return rc;
1097 }
1098
1099 static int ldlm_cleanup(void)
1100 {
1101 if (!list_empty(ldlm_namespace_list(LDLM_NAMESPACE_SERVER)) ||
1102 !list_empty(ldlm_namespace_list(LDLM_NAMESPACE_CLIENT))) {
1103 CERROR("ldlm still has namespaces; clean these up first.\n");
1104 ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE);
1105 ldlm_dump_all_namespaces(LDLM_NAMESPACE_CLIENT, D_DLMTRACE);
1106 return -EBUSY;
1107 }
1108
1109 ldlm_pools_fini();
1110
1111 if (ldlm_state->ldlm_bl_pool != NULL) {
1112 struct ldlm_bl_pool *blp = ldlm_state->ldlm_bl_pool;
1113
1114 while (atomic_read(&blp->blp_num_threads) > 0) {
1115 struct ldlm_bl_work_item blwi = { .blwi_ns = NULL };
1116
1117 init_completion(&blp->blp_comp);
1118
1119 spin_lock(&blp->blp_lock);
1120 list_add_tail(&blwi.blwi_entry, &blp->blp_list);
1121 wake_up(&blp->blp_waitq);
1122 spin_unlock(&blp->blp_lock);
1123
1124 wait_for_completion(&blp->blp_comp);
1125 }
1126
1127 OBD_FREE(blp, sizeof(*blp));
1128 }
1129
1130 if (ldlm_state->ldlm_cb_service != NULL)
1131 ptlrpc_unregister_service(ldlm_state->ldlm_cb_service);
1132
1133 ldlm_proc_cleanup();
1134
1135
1136 OBD_FREE(ldlm_state, sizeof(*ldlm_state));
1137 ldlm_state = NULL;
1138
1139 return 0;
1140 }
1141
1142 int ldlm_init(void)
1143 {
1144 mutex_init(&ldlm_ref_mutex);
1145 mutex_init(ldlm_namespace_lock(LDLM_NAMESPACE_SERVER));
1146 mutex_init(ldlm_namespace_lock(LDLM_NAMESPACE_CLIENT));
1147 ldlm_resource_slab = kmem_cache_create("ldlm_resources",
1148 sizeof(struct ldlm_resource), 0,
1149 SLAB_HWCACHE_ALIGN, NULL);
1150 if (ldlm_resource_slab == NULL)
1151 return -ENOMEM;
1152
1153 ldlm_lock_slab = kmem_cache_create("ldlm_locks",
1154 sizeof(struct ldlm_lock), 0,
1155 SLAB_HWCACHE_ALIGN | SLAB_DESTROY_BY_RCU, NULL);
1156 if (ldlm_lock_slab == NULL) {
1157 kmem_cache_destroy(ldlm_resource_slab);
1158 return -ENOMEM;
1159 }
1160
1161 ldlm_interval_slab = kmem_cache_create("interval_node",
1162 sizeof(struct ldlm_interval),
1163 0, SLAB_HWCACHE_ALIGN, NULL);
1164 if (ldlm_interval_slab == NULL) {
1165 kmem_cache_destroy(ldlm_resource_slab);
1166 kmem_cache_destroy(ldlm_lock_slab);
1167 return -ENOMEM;
1168 }
1169 #if LUSTRE_TRACKS_LOCK_EXP_REFS
1170 class_export_dump_hook = ldlm_dump_export_locks;
1171 #endif
1172 return 0;
1173 }
1174
1175 void ldlm_exit(void)
1176 {
1177 if (ldlm_refcount)
1178 CERROR("ldlm_refcount is %d in ldlm_exit!\n", ldlm_refcount);
1179 kmem_cache_destroy(ldlm_resource_slab);
1180 /* ldlm_lock_put() use RCU to call ldlm_lock_free, so need call
1181 * synchronize_rcu() to wait a grace period elapsed, so that
1182 * ldlm_lock_free() get a chance to be called. */
1183 synchronize_rcu();
1184 kmem_cache_destroy(ldlm_lock_slab);
1185 kmem_cache_destroy(ldlm_interval_slab);
1186 }
This page took 0.120411 seconds and 5 git commands to generate.