4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
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
27 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2010, 2012, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/ldlm/ldlm_resource.c
38 * Author: Phil Schwan <phil@clusterfs.com>
39 * Author: Peter Braam <braam@clusterfs.com>
42 #define DEBUG_SUBSYSTEM S_LDLM
43 #include "../include/lustre_dlm.h"
44 #include "../include/lustre_fid.h"
45 #include "../include/obd_class.h"
46 #include "ldlm_internal.h"
48 struct kmem_cache
*ldlm_resource_slab
, *ldlm_lock_slab
;
50 int ldlm_srv_namespace_nr
= 0;
51 int ldlm_cli_namespace_nr
= 0;
53 struct mutex ldlm_srv_namespace_lock
;
54 LIST_HEAD(ldlm_srv_namespace_list
);
56 struct mutex ldlm_cli_namespace_lock
;
57 /* Client Namespaces that have active resources in them.
58 * Once all resources go away, ldlm_poold moves such namespaces to the
60 LIST_HEAD(ldlm_cli_active_namespace_list
);
61 /* Client namespaces that don't have any locks in them */
62 LIST_HEAD(ldlm_cli_inactive_namespace_list
);
64 static struct dentry
*ldlm_debugfs_dir
;
65 static struct dentry
*ldlm_ns_debugfs_dir
;
66 struct dentry
*ldlm_svc_debugfs_dir
;
68 /* during debug dump certain amount of granted locks for one resource to avoid
70 unsigned int ldlm_dump_granted_max
= 256;
73 lprocfs_wr_dump_ns(struct file
*file
, const char __user
*buffer
,
74 size_t count
, loff_t
*off
)
76 ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER
, D_DLMTRACE
);
77 ldlm_dump_all_namespaces(LDLM_NAMESPACE_CLIENT
, D_DLMTRACE
);
80 LPROC_SEQ_FOPS_WR_ONLY(ldlm
, dump_ns
);
82 LPROC_SEQ_FOPS_RW_TYPE(ldlm_rw
, uint
);
84 static struct lprocfs_vars ldlm_debugfs_list
[] = {
85 { "dump_namespaces", &ldlm_dump_ns_fops
, NULL
, 0222 },
86 { "dump_granted_max", &ldlm_rw_uint_fops
, &ldlm_dump_granted_max
},
90 int ldlm_debugfs_setup(void)
94 ldlm_debugfs_dir
= ldebugfs_register(OBD_LDLM_DEVICENAME
,
97 if (IS_ERR_OR_NULL(ldlm_debugfs_dir
)) {
98 CERROR("LProcFS failed in ldlm-init\n");
99 rc
= ldlm_debugfs_dir
? PTR_ERR(ldlm_debugfs_dir
) : -ENOMEM
;
103 ldlm_ns_debugfs_dir
= ldebugfs_register("namespaces",
106 if (IS_ERR_OR_NULL(ldlm_ns_debugfs_dir
)) {
107 CERROR("LProcFS failed in ldlm-init\n");
108 rc
= ldlm_ns_debugfs_dir
? PTR_ERR(ldlm_ns_debugfs_dir
)
113 ldlm_svc_debugfs_dir
= ldebugfs_register("services",
116 if (IS_ERR_OR_NULL(ldlm_svc_debugfs_dir
)) {
117 CERROR("LProcFS failed in ldlm-init\n");
118 rc
= ldlm_svc_debugfs_dir
? PTR_ERR(ldlm_svc_debugfs_dir
)
123 rc
= ldebugfs_add_vars(ldlm_debugfs_dir
, ldlm_debugfs_list
, NULL
);
128 ldebugfs_remove(&ldlm_ns_debugfs_dir
);
130 ldebugfs_remove(&ldlm_debugfs_dir
);
132 ldlm_svc_debugfs_dir
= NULL
;
133 ldlm_ns_debugfs_dir
= NULL
;
134 ldlm_debugfs_dir
= NULL
;
138 void ldlm_debugfs_cleanup(void)
140 if (!IS_ERR_OR_NULL(ldlm_svc_debugfs_dir
))
141 ldebugfs_remove(&ldlm_svc_debugfs_dir
);
143 if (!IS_ERR_OR_NULL(ldlm_ns_debugfs_dir
))
144 ldebugfs_remove(&ldlm_ns_debugfs_dir
);
146 if (!IS_ERR_OR_NULL(ldlm_debugfs_dir
))
147 ldebugfs_remove(&ldlm_debugfs_dir
);
149 ldlm_svc_debugfs_dir
= NULL
;
150 ldlm_ns_debugfs_dir
= NULL
;
151 ldlm_debugfs_dir
= NULL
;
154 static ssize_t
resource_count_show(struct kobject
*kobj
, struct attribute
*attr
,
157 struct ldlm_namespace
*ns
= container_of(kobj
, struct ldlm_namespace
,
160 struct cfs_hash_bd bd
;
163 /* result is not strictly consistent */
164 cfs_hash_for_each_bucket(ns
->ns_rs_hash
, &bd
, i
)
165 res
+= cfs_hash_bd_count_get(&bd
);
166 return sprintf(buf
, "%lld\n", res
);
168 LUSTRE_RO_ATTR(resource_count
);
170 static ssize_t
lock_count_show(struct kobject
*kobj
, struct attribute
*attr
,
173 struct ldlm_namespace
*ns
= container_of(kobj
, struct ldlm_namespace
,
177 locks
= lprocfs_stats_collector(ns
->ns_stats
, LDLM_NSS_LOCKS
,
178 LPROCFS_FIELDS_FLAGS_SUM
);
179 return sprintf(buf
, "%lld\n", locks
);
181 LUSTRE_RO_ATTR(lock_count
);
183 static ssize_t
lock_unused_count_show(struct kobject
*kobj
,
184 struct attribute
*attr
,
187 struct ldlm_namespace
*ns
= container_of(kobj
, struct ldlm_namespace
,
190 return sprintf(buf
, "%d\n", ns
->ns_nr_unused
);
192 LUSTRE_RO_ATTR(lock_unused_count
);
194 static ssize_t
lru_size_show(struct kobject
*kobj
, struct attribute
*attr
,
197 struct ldlm_namespace
*ns
= container_of(kobj
, struct ldlm_namespace
,
199 __u32
*nr
= &ns
->ns_max_unused
;
201 if (ns_connect_lru_resize(ns
))
202 nr
= &ns
->ns_nr_unused
;
203 return sprintf(buf
, "%u", *nr
);
206 static ssize_t
lru_size_store(struct kobject
*kobj
, struct attribute
*attr
,
207 const char *buffer
, size_t count
)
209 struct ldlm_namespace
*ns
= container_of(kobj
, struct ldlm_namespace
,
215 if (strncmp(buffer
, "clear", 5) == 0) {
217 "dropping all unused locks from namespace %s\n",
219 if (ns_connect_lru_resize(ns
)) {
220 int canceled
, unused
= ns
->ns_nr_unused
;
222 /* Try to cancel all @ns_nr_unused locks. */
223 canceled
= ldlm_cancel_lru(ns
, unused
, 0,
225 if (canceled
< unused
) {
227 "not all requested locks are canceled, requested: %d, canceled: %d\n",
233 tmp
= ns
->ns_max_unused
;
234 ns
->ns_max_unused
= 0;
235 ldlm_cancel_lru(ns
, 0, 0, LDLM_CANCEL_PASSED
);
236 ns
->ns_max_unused
= tmp
;
241 err
= kstrtoul(buffer
, 10, &tmp
);
243 CERROR("lru_size: invalid value written\n");
246 lru_resize
= (tmp
== 0);
248 if (ns_connect_lru_resize(ns
)) {
250 ns
->ns_max_unused
= (unsigned int)tmp
;
252 if (tmp
> ns
->ns_nr_unused
)
253 tmp
= ns
->ns_nr_unused
;
254 tmp
= ns
->ns_nr_unused
- tmp
;
257 "changing namespace %s unused locks from %u to %u\n",
258 ldlm_ns_name(ns
), ns
->ns_nr_unused
,
260 ldlm_cancel_lru(ns
, tmp
, LCF_ASYNC
, LDLM_CANCEL_PASSED
);
264 "disable lru_resize for namespace %s\n",
266 ns
->ns_connect_flags
&= ~OBD_CONNECT_LRU_RESIZE
;
270 "changing namespace %s max_unused from %u to %u\n",
271 ldlm_ns_name(ns
), ns
->ns_max_unused
,
273 ns
->ns_max_unused
= (unsigned int)tmp
;
274 ldlm_cancel_lru(ns
, 0, LCF_ASYNC
, LDLM_CANCEL_PASSED
);
276 /* Make sure that LRU resize was originally supported before
277 * turning it on here. */
279 (ns
->ns_orig_connect_flags
& OBD_CONNECT_LRU_RESIZE
)) {
281 "enable lru_resize for namespace %s\n",
283 ns
->ns_connect_flags
|= OBD_CONNECT_LRU_RESIZE
;
289 LUSTRE_RW_ATTR(lru_size
);
291 static ssize_t
lru_max_age_show(struct kobject
*kobj
, struct attribute
*attr
,
294 struct ldlm_namespace
*ns
= container_of(kobj
, struct ldlm_namespace
,
297 return sprintf(buf
, "%u", ns
->ns_max_age
);
300 static ssize_t
lru_max_age_store(struct kobject
*kobj
, struct attribute
*attr
,
301 const char *buffer
, size_t count
)
303 struct ldlm_namespace
*ns
= container_of(kobj
, struct ldlm_namespace
,
308 err
= kstrtoul(buffer
, 10, &tmp
);
312 ns
->ns_max_age
= tmp
;
316 LUSTRE_RW_ATTR(lru_max_age
);
318 static ssize_t
early_lock_cancel_show(struct kobject
*kobj
,
319 struct attribute
*attr
,
322 struct ldlm_namespace
*ns
= container_of(kobj
, struct ldlm_namespace
,
325 return sprintf(buf
, "%d\n", ns_connect_cancelset(ns
));
328 static ssize_t
early_lock_cancel_store(struct kobject
*kobj
,
329 struct attribute
*attr
,
333 struct ldlm_namespace
*ns
= container_of(kobj
, struct ldlm_namespace
,
335 unsigned long supp
= -1;
338 rc
= kstrtoul(buffer
, 10, &supp
);
343 ns
->ns_connect_flags
&= ~OBD_CONNECT_CANCELSET
;
344 else if (ns
->ns_orig_connect_flags
& OBD_CONNECT_CANCELSET
)
345 ns
->ns_connect_flags
|= OBD_CONNECT_CANCELSET
;
348 LUSTRE_RW_ATTR(early_lock_cancel
);
350 /* These are for namespaces in /sys/fs/lustre/ldlm/namespaces/ */
351 static struct attribute
*ldlm_ns_attrs
[] = {
352 &lustre_attr_resource_count
.attr
,
353 &lustre_attr_lock_count
.attr
,
354 &lustre_attr_lock_unused_count
.attr
,
355 &lustre_attr_lru_size
.attr
,
356 &lustre_attr_lru_max_age
.attr
,
357 &lustre_attr_early_lock_cancel
.attr
,
361 static void ldlm_ns_release(struct kobject
*kobj
)
363 struct ldlm_namespace
*ns
= container_of(kobj
, struct ldlm_namespace
,
365 complete(&ns
->ns_kobj_unregister
);
368 static struct kobj_type ldlm_ns_ktype
= {
369 .default_attrs
= ldlm_ns_attrs
,
370 .sysfs_ops
= &lustre_sysfs_ops
,
371 .release
= ldlm_ns_release
,
374 static void ldlm_namespace_debugfs_unregister(struct ldlm_namespace
*ns
)
376 if (IS_ERR_OR_NULL(ns
->ns_debugfs_entry
))
377 CERROR("dlm namespace %s has no procfs dir?\n",
380 ldebugfs_remove(&ns
->ns_debugfs_entry
);
382 if (ns
->ns_stats
!= NULL
)
383 lprocfs_free_stats(&ns
->ns_stats
);
386 void ldlm_namespace_sysfs_unregister(struct ldlm_namespace
*ns
)
388 kobject_put(&ns
->ns_kobj
);
389 wait_for_completion(&ns
->ns_kobj_unregister
);
392 int ldlm_namespace_sysfs_register(struct ldlm_namespace
*ns
)
396 ns
->ns_kobj
.kset
= ldlm_ns_kset
;
397 init_completion(&ns
->ns_kobj_unregister
);
398 err
= kobject_init_and_add(&ns
->ns_kobj
, &ldlm_ns_ktype
, NULL
,
399 "%s", ldlm_ns_name(ns
));
401 ns
->ns_stats
= lprocfs_alloc_stats(LDLM_NSS_LAST
, 0);
402 if (ns
->ns_stats
== NULL
) {
403 kobject_put(&ns
->ns_kobj
);
407 lprocfs_counter_init(ns
->ns_stats
, LDLM_NSS_LOCKS
,
408 LPROCFS_CNTR_AVGMINMAX
, "locks", "locks");
413 static int ldlm_namespace_debugfs_register(struct ldlm_namespace
*ns
)
415 struct dentry
*ns_entry
;
417 if (!IS_ERR_OR_NULL(ns
->ns_debugfs_entry
)) {
418 ns_entry
= ns
->ns_debugfs_entry
;
420 ns_entry
= debugfs_create_dir(ldlm_ns_name(ns
),
421 ldlm_ns_debugfs_dir
);
422 if (ns_entry
== NULL
)
424 ns
->ns_debugfs_entry
= ns_entry
;
429 #undef MAX_STRING_SIZE
431 static unsigned ldlm_res_hop_hash(struct cfs_hash
*hs
,
432 const void *key
, unsigned mask
)
434 const struct ldlm_res_id
*id
= key
;
438 for (i
= 0; i
< RES_NAME_SIZE
; i
++)
443 static unsigned ldlm_res_hop_fid_hash(struct cfs_hash
*hs
,
444 const void *key
, unsigned mask
)
446 const struct ldlm_res_id
*id
= key
;
451 fid
.f_seq
= id
->name
[LUSTRE_RES_ID_SEQ_OFF
];
452 fid
.f_oid
= (__u32
)id
->name
[LUSTRE_RES_ID_VER_OID_OFF
];
453 fid
.f_ver
= (__u32
)(id
->name
[LUSTRE_RES_ID_VER_OID_OFF
] >> 32);
455 hash
= fid_flatten32(&fid
);
456 hash
+= (hash
>> 4) + (hash
<< 12); /* mixing oid and seq */
457 if (id
->name
[LUSTRE_RES_ID_HSH_OFF
] != 0) {
458 val
= id
->name
[LUSTRE_RES_ID_HSH_OFF
];
459 hash
+= (val
>> 5) + (val
<< 11);
463 hash
= hash_long(hash
, hs
->hs_bkt_bits
);
464 /* give me another random factor */
465 hash
-= hash_long((unsigned long)hs
, val
% 11 + 3);
467 hash
<<= hs
->hs_cur_bits
- hs
->hs_bkt_bits
;
468 hash
|= ldlm_res_hop_hash(hs
, key
, CFS_HASH_NBKT(hs
) - 1);
473 static void *ldlm_res_hop_key(struct hlist_node
*hnode
)
475 struct ldlm_resource
*res
;
477 res
= hlist_entry(hnode
, struct ldlm_resource
, lr_hash
);
478 return &res
->lr_name
;
481 static int ldlm_res_hop_keycmp(const void *key
, struct hlist_node
*hnode
)
483 struct ldlm_resource
*res
;
485 res
= hlist_entry(hnode
, struct ldlm_resource
, lr_hash
);
486 return ldlm_res_eq((const struct ldlm_res_id
*)key
,
487 (const struct ldlm_res_id
*)&res
->lr_name
);
490 static void *ldlm_res_hop_object(struct hlist_node
*hnode
)
492 return hlist_entry(hnode
, struct ldlm_resource
, lr_hash
);
495 static void ldlm_res_hop_get_locked(struct cfs_hash
*hs
,
496 struct hlist_node
*hnode
)
498 struct ldlm_resource
*res
;
500 res
= hlist_entry(hnode
, struct ldlm_resource
, lr_hash
);
501 ldlm_resource_getref(res
);
504 static void ldlm_res_hop_put_locked(struct cfs_hash
*hs
,
505 struct hlist_node
*hnode
)
507 struct ldlm_resource
*res
;
509 res
= hlist_entry(hnode
, struct ldlm_resource
, lr_hash
);
510 /* cfs_hash_for_each_nolock is the only chance we call it */
511 ldlm_resource_putref_locked(res
);
514 static void ldlm_res_hop_put(struct cfs_hash
*hs
, struct hlist_node
*hnode
)
516 struct ldlm_resource
*res
;
518 res
= hlist_entry(hnode
, struct ldlm_resource
, lr_hash
);
519 ldlm_resource_putref(res
);
522 cfs_hash_ops_t ldlm_ns_hash_ops
= {
523 .hs_hash
= ldlm_res_hop_hash
,
524 .hs_key
= ldlm_res_hop_key
,
525 .hs_keycmp
= ldlm_res_hop_keycmp
,
527 .hs_object
= ldlm_res_hop_object
,
528 .hs_get
= ldlm_res_hop_get_locked
,
529 .hs_put_locked
= ldlm_res_hop_put_locked
,
530 .hs_put
= ldlm_res_hop_put
533 cfs_hash_ops_t ldlm_ns_fid_hash_ops
= {
534 .hs_hash
= ldlm_res_hop_fid_hash
,
535 .hs_key
= ldlm_res_hop_key
,
536 .hs_keycmp
= ldlm_res_hop_keycmp
,
538 .hs_object
= ldlm_res_hop_object
,
539 .hs_get
= ldlm_res_hop_get_locked
,
540 .hs_put_locked
= ldlm_res_hop_put_locked
,
541 .hs_put
= ldlm_res_hop_put
544 struct ldlm_ns_hash_def
{
545 ldlm_ns_type_t nsd_type
;
546 /** hash bucket bits */
547 unsigned nsd_bkt_bits
;
549 unsigned nsd_all_bits
;
550 /** hash operations */
551 cfs_hash_ops_t
*nsd_hops
;
554 struct ldlm_ns_hash_def ldlm_ns_hash_defs
[] = {
556 .nsd_type
= LDLM_NS_TYPE_MDC
,
559 .nsd_hops
= &ldlm_ns_fid_hash_ops
,
562 .nsd_type
= LDLM_NS_TYPE_MDT
,
565 .nsd_hops
= &ldlm_ns_fid_hash_ops
,
568 .nsd_type
= LDLM_NS_TYPE_OSC
,
571 .nsd_hops
= &ldlm_ns_hash_ops
,
574 .nsd_type
= LDLM_NS_TYPE_OST
,
577 .nsd_hops
= &ldlm_ns_hash_ops
,
580 .nsd_type
= LDLM_NS_TYPE_MGC
,
583 .nsd_hops
= &ldlm_ns_hash_ops
,
586 .nsd_type
= LDLM_NS_TYPE_MGT
,
589 .nsd_hops
= &ldlm_ns_hash_ops
,
592 .nsd_type
= LDLM_NS_TYPE_UNKNOWN
,
597 * Create and initialize new empty namespace.
599 struct ldlm_namespace
*ldlm_namespace_new(struct obd_device
*obd
, char *name
,
602 ldlm_ns_type_t ns_type
)
604 struct ldlm_namespace
*ns
= NULL
;
605 struct ldlm_ns_bucket
*nsb
;
606 struct ldlm_ns_hash_def
*nsd
;
607 struct cfs_hash_bd bd
;
611 LASSERT(obd
!= NULL
);
615 CERROR("ldlm_get_ref failed: %d\n", rc
);
619 for (idx
= 0;; idx
++) {
620 nsd
= &ldlm_ns_hash_defs
[idx
];
621 if (nsd
->nsd_type
== LDLM_NS_TYPE_UNKNOWN
) {
622 CERROR("Unknown type %d for ns %s\n", ns_type
, name
);
626 if (nsd
->nsd_type
== ns_type
)
630 ns
= kzalloc(sizeof(*ns
), GFP_NOFS
);
634 ns
->ns_rs_hash
= cfs_hash_create(name
,
635 nsd
->nsd_all_bits
, nsd
->nsd_all_bits
,
636 nsd
->nsd_bkt_bits
, sizeof(*nsb
),
642 CFS_HASH_SPIN_BKTLOCK
|
643 CFS_HASH_NO_ITEMREF
);
644 if (ns
->ns_rs_hash
== NULL
)
647 cfs_hash_for_each_bucket(ns
->ns_rs_hash
, &bd
, idx
) {
648 nsb
= cfs_hash_bd_extra_get(ns
->ns_rs_hash
, &bd
);
649 at_init(&nsb
->nsb_at_estimate
, ldlm_enqueue_min
, 0);
650 nsb
->nsb_namespace
= ns
;
654 ns
->ns_appetite
= apt
;
655 ns
->ns_client
= client
;
657 INIT_LIST_HEAD(&ns
->ns_list_chain
);
658 INIT_LIST_HEAD(&ns
->ns_unused_list
);
659 spin_lock_init(&ns
->ns_lock
);
660 atomic_set(&ns
->ns_bref
, 0);
661 init_waitqueue_head(&ns
->ns_waitq
);
663 ns
->ns_max_parallel_ast
= LDLM_DEFAULT_PARALLEL_AST_LIMIT
;
664 ns
->ns_nr_unused
= 0;
665 ns
->ns_max_unused
= LDLM_DEFAULT_LRU_SIZE
;
666 ns
->ns_max_age
= LDLM_DEFAULT_MAX_ALIVE
;
667 ns
->ns_orig_connect_flags
= 0;
668 ns
->ns_connect_flags
= 0;
671 rc
= ldlm_namespace_sysfs_register(ns
);
673 CERROR("Can't initialize ns sysfs, rc %d\n", rc
);
677 rc
= ldlm_namespace_debugfs_register(ns
);
679 CERROR("Can't initialize ns proc, rc %d\n", rc
);
683 idx
= ldlm_namespace_nr_read(client
);
684 rc
= ldlm_pool_init(&ns
->ns_pool
, ns
, idx
, client
);
686 CERROR("Can't initialize lock pool, rc %d\n", rc
);
690 ldlm_namespace_register(ns
, client
);
693 ldlm_namespace_debugfs_unregister(ns
);
695 ldlm_namespace_sysfs_unregister(ns
);
696 ldlm_namespace_cleanup(ns
, 0);
698 cfs_hash_putref(ns
->ns_rs_hash
);
705 EXPORT_SYMBOL(ldlm_namespace_new
);
707 extern struct ldlm_lock
*ldlm_lock_get(struct ldlm_lock
*lock
);
710 * Cancel and destroy all locks on a resource.
712 * If flags contains FL_LOCAL_ONLY, don't try to tell the server, just
713 * clean up. This is currently only used for recovery, and we make
714 * certain assumptions as a result--notably, that we shouldn't cancel
717 static void cleanup_resource(struct ldlm_resource
*res
, struct list_head
*q
,
720 struct list_head
*tmp
;
721 int rc
= 0, client
= ns_is_client(ldlm_res_to_ns(res
));
722 bool local_only
= !!(flags
& LDLM_FL_LOCAL_ONLY
);
725 struct ldlm_lock
*lock
= NULL
;
727 /* First, we look for non-cleaned-yet lock
728 * all cleaned locks are marked by CLEANED flag. */
730 list_for_each(tmp
, q
) {
731 lock
= list_entry(tmp
, struct ldlm_lock
,
733 if (lock
->l_flags
& LDLM_FL_CLEANED
) {
738 lock
->l_flags
|= LDLM_FL_CLEANED
;
747 /* Set CBPENDING so nothing in the cancellation path
748 * can match this lock. */
749 lock
->l_flags
|= LDLM_FL_CBPENDING
;
750 lock
->l_flags
|= LDLM_FL_FAILED
;
751 lock
->l_flags
|= flags
;
753 /* ... without sending a CANCEL message for local_only. */
755 lock
->l_flags
|= LDLM_FL_LOCAL_ONLY
;
757 if (local_only
&& (lock
->l_readers
|| lock
->l_writers
)) {
758 /* This is a little bit gross, but much better than the
759 * alternative: pretend that we got a blocking AST from
760 * the server, so that when the lock is decref'd, it
761 * will go away ... */
763 LDLM_DEBUG(lock
, "setting FL_LOCAL_ONLY");
764 if (lock
->l_completion_ast
)
765 lock
->l_completion_ast(lock
, 0, NULL
);
766 LDLM_LOCK_RELEASE(lock
);
771 struct lustre_handle lockh
;
774 ldlm_lock2handle(lock
, &lockh
);
775 rc
= ldlm_cli_cancel(&lockh
, LCF_ASYNC
);
777 CERROR("ldlm_cli_cancel: %d\n", rc
);
779 ldlm_resource_unlink_lock(lock
);
781 LDLM_DEBUG(lock
, "Freeing a lock still held by a client node");
782 ldlm_lock_destroy(lock
);
784 LDLM_LOCK_RELEASE(lock
);
788 static int ldlm_resource_clean(struct cfs_hash
*hs
, struct cfs_hash_bd
*bd
,
789 struct hlist_node
*hnode
, void *arg
)
791 struct ldlm_resource
*res
= cfs_hash_object(hs
, hnode
);
792 __u64 flags
= *(__u64
*)arg
;
794 cleanup_resource(res
, &res
->lr_granted
, flags
);
795 cleanup_resource(res
, &res
->lr_converting
, flags
);
796 cleanup_resource(res
, &res
->lr_waiting
, flags
);
801 static int ldlm_resource_complain(struct cfs_hash
*hs
, struct cfs_hash_bd
*bd
,
802 struct hlist_node
*hnode
, void *arg
)
804 struct ldlm_resource
*res
= cfs_hash_object(hs
, hnode
);
807 CERROR("%s: namespace resource "DLDLMRES
808 " (%p) refcount nonzero (%d) after lock cleanup; forcing cleanup.\n",
809 ldlm_ns_name(ldlm_res_to_ns(res
)), PLDLMRES(res
), res
,
810 atomic_read(&res
->lr_refcount
) - 1);
812 ldlm_resource_dump(D_ERROR
, res
);
818 * Cancel and destroy all locks in the namespace.
820 * Typically used during evictions when server notified client that it was
821 * evicted and all of its state needs to be destroyed.
822 * Also used during shutdown.
824 int ldlm_namespace_cleanup(struct ldlm_namespace
*ns
, __u64 flags
)
827 CDEBUG(D_INFO
, "NULL ns, skipping cleanup\n");
831 cfs_hash_for_each_nolock(ns
->ns_rs_hash
, ldlm_resource_clean
, &flags
);
832 cfs_hash_for_each_nolock(ns
->ns_rs_hash
, ldlm_resource_complain
, NULL
);
835 EXPORT_SYMBOL(ldlm_namespace_cleanup
);
838 * Attempts to free namespace.
840 * Only used when namespace goes away, like during an unmount.
842 static int __ldlm_namespace_free(struct ldlm_namespace
*ns
, int force
)
844 /* At shutdown time, don't call the cancellation callback */
845 ldlm_namespace_cleanup(ns
, force
? LDLM_FL_LOCAL_ONLY
: 0);
847 if (atomic_read(&ns
->ns_bref
) > 0) {
848 struct l_wait_info lwi
= LWI_INTR(LWI_ON_SIGNAL_NOOP
, NULL
);
852 "dlm namespace %s free waiting on refcount %d\n",
853 ldlm_ns_name(ns
), atomic_read(&ns
->ns_bref
));
856 lwi
= LWI_TIMEOUT(obd_timeout
* HZ
/ 4, NULL
, NULL
);
858 rc
= l_wait_event(ns
->ns_waitq
,
859 atomic_read(&ns
->ns_bref
) == 0, &lwi
);
861 /* Forced cleanups should be able to reclaim all references,
862 * so it's safe to wait forever... we can't leak locks... */
863 if (force
&& rc
== -ETIMEDOUT
) {
864 LCONSOLE_ERROR("Forced cleanup waiting for %s namespace with %d resources in use, (rc=%d)\n",
866 atomic_read(&ns
->ns_bref
), rc
);
870 if (atomic_read(&ns
->ns_bref
)) {
871 LCONSOLE_ERROR("Cleanup waiting for %s namespace with %d resources in use, (rc=%d)\n",
873 atomic_read(&ns
->ns_bref
), rc
);
874 return ELDLM_NAMESPACE_EXISTS
;
876 CDEBUG(D_DLMTRACE
, "dlm namespace %s free done waiting\n",
884 * Performs various cleanups for passed \a ns to make it drop refc and be
885 * ready for freeing. Waits for refc == 0.
887 * The following is done:
888 * (0) Unregister \a ns from its list to make inaccessible for potential
889 * users like pools thread and others;
890 * (1) Clear all locks in \a ns.
892 void ldlm_namespace_free_prior(struct ldlm_namespace
*ns
,
893 struct obd_import
*imp
,
901 spin_lock(&ns
->ns_lock
);
903 spin_unlock(&ns
->ns_lock
);
906 * Can fail with -EINTR when force == 0 in which case try harder.
908 rc
= __ldlm_namespace_free(ns
, force
);
909 if (rc
!= ELDLM_OK
) {
911 ptlrpc_disconnect_import(imp
, 0);
912 ptlrpc_invalidate_import(imp
);
916 * With all requests dropped and the import inactive
917 * we are guaranteed all reference will be dropped.
919 rc
= __ldlm_namespace_free(ns
, 1);
925 * Performs freeing memory structures related to \a ns. This is only done
926 * when ldlm_namespce_free_prior() successfully removed all resources
927 * referencing \a ns and its refc == 0.
929 void ldlm_namespace_free_post(struct ldlm_namespace
*ns
)
934 /* Make sure that nobody can find this ns in its list. */
935 ldlm_namespace_unregister(ns
, ns
->ns_client
);
936 /* Fini pool _before_ parent proc dir is removed. This is important as
937 * ldlm_pool_fini() removes own proc dir which is child to @dir.
938 * Removing it after @dir may cause oops. */
939 ldlm_pool_fini(&ns
->ns_pool
);
941 ldlm_namespace_debugfs_unregister(ns
);
942 ldlm_namespace_sysfs_unregister(ns
);
943 cfs_hash_putref(ns
->ns_rs_hash
);
944 /* Namespace \a ns should be not on list at this time, otherwise
945 * this will cause issues related to using freed \a ns in poold
947 LASSERT(list_empty(&ns
->ns_list_chain
));
953 * Cleanup the resource, and free namespace.
956 * proc1: destroy import
957 * class_disconnect_export(grab cl_sem) ->
958 * -> ldlm_namespace_free ->
959 * -> ldebugfs_remove(grab _lprocfs_lock).
960 * proc2: read proc info
961 * lprocfs_fops_read(grab _lprocfs_lock) ->
962 * -> osc_rd_active, etc(grab cl_sem).
964 * So that I have to split the ldlm_namespace_free into two parts - the first
965 * part ldlm_namespace_free_prior is used to cleanup the resource which is
966 * being used; the 2nd part ldlm_namespace_free_post is used to unregister the
967 * lprocfs entries, and then free memory. It will be called w/o cli->cl_sem
970 void ldlm_namespace_free(struct ldlm_namespace
*ns
,
971 struct obd_import
*imp
,
974 ldlm_namespace_free_prior(ns
, imp
, force
);
975 ldlm_namespace_free_post(ns
);
977 EXPORT_SYMBOL(ldlm_namespace_free
);
979 void ldlm_namespace_get(struct ldlm_namespace
*ns
)
981 atomic_inc(&ns
->ns_bref
);
983 EXPORT_SYMBOL(ldlm_namespace_get
);
985 /* This is only for callers that care about refcount */
986 int ldlm_namespace_get_return(struct ldlm_namespace
*ns
)
988 return atomic_inc_return(&ns
->ns_bref
);
991 void ldlm_namespace_put(struct ldlm_namespace
*ns
)
993 if (atomic_dec_and_lock(&ns
->ns_bref
, &ns
->ns_lock
)) {
994 wake_up(&ns
->ns_waitq
);
995 spin_unlock(&ns
->ns_lock
);
998 EXPORT_SYMBOL(ldlm_namespace_put
);
1000 /** Register \a ns in the list of namespaces */
1001 void ldlm_namespace_register(struct ldlm_namespace
*ns
, ldlm_side_t client
)
1003 mutex_lock(ldlm_namespace_lock(client
));
1004 LASSERT(list_empty(&ns
->ns_list_chain
));
1005 list_add(&ns
->ns_list_chain
, ldlm_namespace_inactive_list(client
));
1006 ldlm_namespace_nr_inc(client
);
1007 mutex_unlock(ldlm_namespace_lock(client
));
1010 /** Unregister \a ns from the list of namespaces. */
1011 void ldlm_namespace_unregister(struct ldlm_namespace
*ns
, ldlm_side_t client
)
1013 mutex_lock(ldlm_namespace_lock(client
));
1014 LASSERT(!list_empty(&ns
->ns_list_chain
));
1015 /* Some asserts and possibly other parts of the code are still
1016 * using list_empty(&ns->ns_list_chain). This is why it is
1017 * important to use list_del_init() here. */
1018 list_del_init(&ns
->ns_list_chain
);
1019 ldlm_namespace_nr_dec(client
);
1020 mutex_unlock(ldlm_namespace_lock(client
));
1023 /** Should be called with ldlm_namespace_lock(client) taken. */
1024 void ldlm_namespace_move_to_active_locked(struct ldlm_namespace
*ns
,
1027 LASSERT(!list_empty(&ns
->ns_list_chain
));
1028 LASSERT(mutex_is_locked(ldlm_namespace_lock(client
)));
1029 list_move_tail(&ns
->ns_list_chain
, ldlm_namespace_list(client
));
1032 /** Should be called with ldlm_namespace_lock(client) taken. */
1033 void ldlm_namespace_move_to_inactive_locked(struct ldlm_namespace
*ns
,
1036 LASSERT(!list_empty(&ns
->ns_list_chain
));
1037 LASSERT(mutex_is_locked(ldlm_namespace_lock(client
)));
1038 list_move_tail(&ns
->ns_list_chain
,
1039 ldlm_namespace_inactive_list(client
));
1042 /** Should be called with ldlm_namespace_lock(client) taken. */
1043 struct ldlm_namespace
*ldlm_namespace_first_locked(ldlm_side_t client
)
1045 LASSERT(mutex_is_locked(ldlm_namespace_lock(client
)));
1046 LASSERT(!list_empty(ldlm_namespace_list(client
)));
1047 return container_of(ldlm_namespace_list(client
)->next
,
1048 struct ldlm_namespace
, ns_list_chain
);
1051 /** Create and initialize new resource. */
1052 static struct ldlm_resource
*ldlm_resource_new(void)
1054 struct ldlm_resource
*res
;
1057 OBD_SLAB_ALLOC_PTR_GFP(res
, ldlm_resource_slab
, GFP_NOFS
);
1061 INIT_LIST_HEAD(&res
->lr_granted
);
1062 INIT_LIST_HEAD(&res
->lr_converting
);
1063 INIT_LIST_HEAD(&res
->lr_waiting
);
1065 /* Initialize interval trees for each lock mode. */
1066 for (idx
= 0; idx
< LCK_MODE_NUM
; idx
++) {
1067 res
->lr_itree
[idx
].lit_size
= 0;
1068 res
->lr_itree
[idx
].lit_mode
= 1 << idx
;
1069 res
->lr_itree
[idx
].lit_root
= NULL
;
1072 atomic_set(&res
->lr_refcount
, 1);
1073 spin_lock_init(&res
->lr_lock
);
1074 lu_ref_init(&res
->lr_reference
);
1076 /* The creator of the resource must unlock the mutex after LVB
1077 * initialization. */
1078 mutex_init(&res
->lr_lvb_mutex
);
1079 mutex_lock(&res
->lr_lvb_mutex
);
1085 * Return a reference to resource with given name, creating it if necessary.
1086 * Args: namespace with ns_lock unlocked
1087 * Locks: takes and releases NS hash-lock and res->lr_lock
1088 * Returns: referenced, unlocked ldlm_resource or NULL
1090 struct ldlm_resource
*
1091 ldlm_resource_get(struct ldlm_namespace
*ns
, struct ldlm_resource
*parent
,
1092 const struct ldlm_res_id
*name
, ldlm_type_t type
, int create
)
1094 struct hlist_node
*hnode
;
1095 struct ldlm_resource
*res
;
1096 struct cfs_hash_bd bd
;
1098 int ns_refcount
= 0;
1100 LASSERT(ns
!= NULL
);
1101 LASSERT(parent
== NULL
);
1102 LASSERT(ns
->ns_rs_hash
!= NULL
);
1103 LASSERT(name
->name
[0] != 0);
1105 cfs_hash_bd_get_and_lock(ns
->ns_rs_hash
, (void *)name
, &bd
, 0);
1106 hnode
= cfs_hash_bd_lookup_locked(ns
->ns_rs_hash
, &bd
, (void *)name
);
1107 if (hnode
!= NULL
) {
1108 cfs_hash_bd_unlock(ns
->ns_rs_hash
, &bd
, 0);
1109 res
= hlist_entry(hnode
, struct ldlm_resource
, lr_hash
);
1110 /* Synchronize with regard to resource creation. */
1111 if (ns
->ns_lvbo
&& ns
->ns_lvbo
->lvbo_init
) {
1112 mutex_lock(&res
->lr_lvb_mutex
);
1113 mutex_unlock(&res
->lr_lvb_mutex
);
1116 if (unlikely(res
->lr_lvb_len
< 0)) {
1117 ldlm_resource_putref(res
);
1123 version
= cfs_hash_bd_version_get(&bd
);
1124 cfs_hash_bd_unlock(ns
->ns_rs_hash
, &bd
, 0);
1129 LASSERTF(type
>= LDLM_MIN_TYPE
&& type
< LDLM_MAX_TYPE
,
1130 "type: %d\n", type
);
1131 res
= ldlm_resource_new();
1135 res
->lr_ns_bucket
= cfs_hash_bd_extra_get(ns
->ns_rs_hash
, &bd
);
1136 res
->lr_name
= *name
;
1137 res
->lr_type
= type
;
1138 res
->lr_most_restr
= LCK_NL
;
1140 cfs_hash_bd_lock(ns
->ns_rs_hash
, &bd
, 1);
1141 hnode
= (version
== cfs_hash_bd_version_get(&bd
)) ? NULL
:
1142 cfs_hash_bd_lookup_locked(ns
->ns_rs_hash
, &bd
, (void *)name
);
1144 if (hnode
!= NULL
) {
1145 /* Someone won the race and already added the resource. */
1146 cfs_hash_bd_unlock(ns
->ns_rs_hash
, &bd
, 1);
1147 /* Clean lu_ref for failed resource. */
1148 lu_ref_fini(&res
->lr_reference
);
1149 /* We have taken lr_lvb_mutex. Drop it. */
1150 mutex_unlock(&res
->lr_lvb_mutex
);
1151 OBD_SLAB_FREE(res
, ldlm_resource_slab
, sizeof(*res
));
1153 res
= hlist_entry(hnode
, struct ldlm_resource
, lr_hash
);
1154 /* Synchronize with regard to resource creation. */
1155 if (ns
->ns_lvbo
&& ns
->ns_lvbo
->lvbo_init
) {
1156 mutex_lock(&res
->lr_lvb_mutex
);
1157 mutex_unlock(&res
->lr_lvb_mutex
);
1160 if (unlikely(res
->lr_lvb_len
< 0)) {
1161 ldlm_resource_putref(res
);
1166 /* We won! Let's add the resource. */
1167 cfs_hash_bd_add_locked(ns
->ns_rs_hash
, &bd
, &res
->lr_hash
);
1168 if (cfs_hash_bd_count_get(&bd
) == 1)
1169 ns_refcount
= ldlm_namespace_get_return(ns
);
1171 cfs_hash_bd_unlock(ns
->ns_rs_hash
, &bd
, 1);
1172 if (ns
->ns_lvbo
&& ns
->ns_lvbo
->lvbo_init
) {
1175 OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_CREATE_RESOURCE
, 2);
1176 rc
= ns
->ns_lvbo
->lvbo_init(res
);
1178 CERROR("%s: lvbo_init failed for resource %#llx:%#llx: rc = %d\n",
1179 ns
->ns_obd
->obd_name
, name
->name
[0],
1181 kfree(res
->lr_lvb_data
);
1182 res
->lr_lvb_data
= NULL
;
1183 res
->lr_lvb_len
= rc
;
1184 mutex_unlock(&res
->lr_lvb_mutex
);
1185 ldlm_resource_putref(res
);
1190 /* We create resource with locked lr_lvb_mutex. */
1191 mutex_unlock(&res
->lr_lvb_mutex
);
1193 /* Let's see if we happened to be the very first resource in this
1194 * namespace. If so, and this is a client namespace, we need to move
1195 * the namespace into the active namespaces list to be patrolled by
1196 * the ldlm_poold. */
1197 if (ns_is_client(ns
) && ns_refcount
== 1) {
1198 mutex_lock(ldlm_namespace_lock(LDLM_NAMESPACE_CLIENT
));
1199 ldlm_namespace_move_to_active_locked(ns
, LDLM_NAMESPACE_CLIENT
);
1200 mutex_unlock(ldlm_namespace_lock(LDLM_NAMESPACE_CLIENT
));
1205 EXPORT_SYMBOL(ldlm_resource_get
);
1207 struct ldlm_resource
*ldlm_resource_getref(struct ldlm_resource
*res
)
1209 LASSERT(res
!= NULL
);
1210 LASSERT(res
!= LP_POISON
);
1211 atomic_inc(&res
->lr_refcount
);
1212 CDEBUG(D_INFO
, "getref res: %p count: %d\n", res
,
1213 atomic_read(&res
->lr_refcount
));
1217 static void __ldlm_resource_putref_final(struct cfs_hash_bd
*bd
,
1218 struct ldlm_resource
*res
)
1220 struct ldlm_ns_bucket
*nsb
= res
->lr_ns_bucket
;
1222 if (!list_empty(&res
->lr_granted
)) {
1223 ldlm_resource_dump(D_ERROR
, res
);
1227 if (!list_empty(&res
->lr_converting
)) {
1228 ldlm_resource_dump(D_ERROR
, res
);
1232 if (!list_empty(&res
->lr_waiting
)) {
1233 ldlm_resource_dump(D_ERROR
, res
);
1237 cfs_hash_bd_del_locked(nsb
->nsb_namespace
->ns_rs_hash
,
1239 lu_ref_fini(&res
->lr_reference
);
1240 if (cfs_hash_bd_count_get(bd
) == 0)
1241 ldlm_namespace_put(nsb
->nsb_namespace
);
1244 /* Returns 1 if the resource was freed, 0 if it remains. */
1245 int ldlm_resource_putref(struct ldlm_resource
*res
)
1247 struct ldlm_namespace
*ns
= ldlm_res_to_ns(res
);
1248 struct cfs_hash_bd bd
;
1250 LASSERT_ATOMIC_GT_LT(&res
->lr_refcount
, 0, LI_POISON
);
1251 CDEBUG(D_INFO
, "putref res: %p count: %d\n",
1252 res
, atomic_read(&res
->lr_refcount
) - 1);
1254 cfs_hash_bd_get(ns
->ns_rs_hash
, &res
->lr_name
, &bd
);
1255 if (cfs_hash_bd_dec_and_lock(ns
->ns_rs_hash
, &bd
, &res
->lr_refcount
)) {
1256 __ldlm_resource_putref_final(&bd
, res
);
1257 cfs_hash_bd_unlock(ns
->ns_rs_hash
, &bd
, 1);
1258 if (ns
->ns_lvbo
&& ns
->ns_lvbo
->lvbo_free
)
1259 ns
->ns_lvbo
->lvbo_free(res
);
1260 OBD_SLAB_FREE(res
, ldlm_resource_slab
, sizeof(*res
));
1265 EXPORT_SYMBOL(ldlm_resource_putref
);
1267 /* Returns 1 if the resource was freed, 0 if it remains. */
1268 int ldlm_resource_putref_locked(struct ldlm_resource
*res
)
1270 struct ldlm_namespace
*ns
= ldlm_res_to_ns(res
);
1272 LASSERT_ATOMIC_GT_LT(&res
->lr_refcount
, 0, LI_POISON
);
1273 CDEBUG(D_INFO
, "putref res: %p count: %d\n",
1274 res
, atomic_read(&res
->lr_refcount
) - 1);
1276 if (atomic_dec_and_test(&res
->lr_refcount
)) {
1277 struct cfs_hash_bd bd
;
1279 cfs_hash_bd_get(ldlm_res_to_ns(res
)->ns_rs_hash
,
1280 &res
->lr_name
, &bd
);
1281 __ldlm_resource_putref_final(&bd
, res
);
1282 cfs_hash_bd_unlock(ns
->ns_rs_hash
, &bd
, 1);
1283 /* NB: ns_rs_hash is created with CFS_HASH_NO_ITEMREF,
1284 * so we should never be here while calling cfs_hash_del,
1285 * cfs_hash_for_each_nolock is the only case we can get
1286 * here, which is safe to release cfs_hash_bd_lock.
1288 if (ns
->ns_lvbo
&& ns
->ns_lvbo
->lvbo_free
)
1289 ns
->ns_lvbo
->lvbo_free(res
);
1290 OBD_SLAB_FREE(res
, ldlm_resource_slab
, sizeof(*res
));
1292 cfs_hash_bd_lock(ns
->ns_rs_hash
, &bd
, 1);
1299 * Add a lock into a given resource into specified lock list.
1301 void ldlm_resource_add_lock(struct ldlm_resource
*res
, struct list_head
*head
,
1302 struct ldlm_lock
*lock
)
1304 check_res_locked(res
);
1306 LDLM_DEBUG(lock
, "About to add this lock:\n");
1308 if (lock
->l_flags
& LDLM_FL_DESTROYED
) {
1309 CDEBUG(D_OTHER
, "Lock destroyed, not adding to resource\n");
1313 LASSERT(list_empty(&lock
->l_res_link
));
1315 list_add_tail(&lock
->l_res_link
, head
);
1319 * Insert a lock into resource after specified lock.
1321 * Obtain resource description from the lock we are inserting after.
1323 void ldlm_resource_insert_lock_after(struct ldlm_lock
*original
,
1324 struct ldlm_lock
*new)
1326 struct ldlm_resource
*res
= original
->l_resource
;
1328 check_res_locked(res
);
1330 ldlm_resource_dump(D_INFO
, res
);
1331 LDLM_DEBUG(new, "About to insert this lock after %p:\n", original
);
1333 if (new->l_flags
& LDLM_FL_DESTROYED
) {
1334 CDEBUG(D_OTHER
, "Lock destroyed, not adding to resource\n");
1338 LASSERT(list_empty(&new->l_res_link
));
1340 list_add(&new->l_res_link
, &original
->l_res_link
);
1344 void ldlm_resource_unlink_lock(struct ldlm_lock
*lock
)
1346 int type
= lock
->l_resource
->lr_type
;
1348 check_res_locked(lock
->l_resource
);
1349 if (type
== LDLM_IBITS
|| type
== LDLM_PLAIN
)
1350 ldlm_unlink_lock_skiplist(lock
);
1351 else if (type
== LDLM_EXTENT
)
1352 ldlm_extent_unlink_lock(lock
);
1353 list_del_init(&lock
->l_res_link
);
1355 EXPORT_SYMBOL(ldlm_resource_unlink_lock
);
1357 void ldlm_res2desc(struct ldlm_resource
*res
, struct ldlm_resource_desc
*desc
)
1359 desc
->lr_type
= res
->lr_type
;
1360 desc
->lr_name
= res
->lr_name
;
1364 * Print information about all locks in all namespaces on this node to debug
1367 void ldlm_dump_all_namespaces(ldlm_side_t client
, int level
)
1369 struct list_head
*tmp
;
1371 if (!((libcfs_debug
| D_ERROR
) & level
))
1374 mutex_lock(ldlm_namespace_lock(client
));
1376 list_for_each(tmp
, ldlm_namespace_list(client
)) {
1377 struct ldlm_namespace
*ns
;
1379 ns
= list_entry(tmp
, struct ldlm_namespace
, ns_list_chain
);
1380 ldlm_namespace_dump(level
, ns
);
1383 mutex_unlock(ldlm_namespace_lock(client
));
1385 EXPORT_SYMBOL(ldlm_dump_all_namespaces
);
1387 static int ldlm_res_hash_dump(struct cfs_hash
*hs
, struct cfs_hash_bd
*bd
,
1388 struct hlist_node
*hnode
, void *arg
)
1390 struct ldlm_resource
*res
= cfs_hash_object(hs
, hnode
);
1391 int level
= (int)(unsigned long)arg
;
1394 ldlm_resource_dump(level
, res
);
1401 * Print information about all locks in this namespace on this node to debug
1404 void ldlm_namespace_dump(int level
, struct ldlm_namespace
*ns
)
1406 if (!((libcfs_debug
| D_ERROR
) & level
))
1409 CDEBUG(level
, "--- Namespace: %s (rc: %d, side: %s)\n",
1410 ldlm_ns_name(ns
), atomic_read(&ns
->ns_bref
),
1411 ns_is_client(ns
) ? "client" : "server");
1413 if (time_before(cfs_time_current(), ns
->ns_next_dump
))
1416 cfs_hash_for_each_nolock(ns
->ns_rs_hash
,
1418 (void *)(unsigned long)level
);
1419 spin_lock(&ns
->ns_lock
);
1420 ns
->ns_next_dump
= cfs_time_shift(10);
1421 spin_unlock(&ns
->ns_lock
);
1423 EXPORT_SYMBOL(ldlm_namespace_dump
);
1426 * Print information about all locks in this resource to debug log.
1428 void ldlm_resource_dump(int level
, struct ldlm_resource
*res
)
1430 struct ldlm_lock
*lock
;
1431 unsigned int granted
= 0;
1433 CLASSERT(RES_NAME_SIZE
== 4);
1435 if (!((libcfs_debug
| D_ERROR
) & level
))
1438 CDEBUG(level
, "--- Resource: "DLDLMRES
" (%p) refcount = %d\n",
1439 PLDLMRES(res
), res
, atomic_read(&res
->lr_refcount
));
1441 if (!list_empty(&res
->lr_granted
)) {
1442 CDEBUG(level
, "Granted locks (in reverse order):\n");
1443 list_for_each_entry_reverse(lock
, &res
->lr_granted
,
1445 LDLM_DEBUG_LIMIT(level
, lock
, "###");
1446 if (!(level
& D_CANTMASK
) &&
1447 ++granted
> ldlm_dump_granted_max
) {
1448 CDEBUG(level
, "only dump %d granted locks to avoid DDOS.\n",
1454 if (!list_empty(&res
->lr_converting
)) {
1455 CDEBUG(level
, "Converting locks:\n");
1456 list_for_each_entry(lock
, &res
->lr_converting
, l_res_link
)
1457 LDLM_DEBUG_LIMIT(level
, lock
, "###");
1459 if (!list_empty(&res
->lr_waiting
)) {
1460 CDEBUG(level
, "Waiting locks:\n");
1461 list_for_each_entry(lock
, &res
->lr_waiting
, l_res_link
)
1462 LDLM_DEBUG_LIMIT(level
, lock
, "###");