1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45#ifndef _LUSTRE_DLM_H__
46#define _LUSTRE_DLM_H__
47
48#include <lustre_lib.h>
49#include <lustre_net.h>
50#include <lustre_import.h>
51#include <lustre_handles.h>
52#include <interval_tree.h>
53#include <lu_ref.h>
54
55#include "lustre_dlm_flags.h"
56
57struct obd_ops;
58struct obd_device;
59
60#define OBD_LDLM_DEVICENAME "ldlm"
61
62#define LDLM_DEFAULT_LRU_SIZE (100 * num_online_cpus())
63#define LDLM_DEFAULT_MAX_ALIVE (65 * 60 * HZ)
64#define LDLM_DEFAULT_PARALLEL_AST_LIMIT 1024
65
66
67
68
69enum ldlm_error {
70 ELDLM_OK = 0,
71 ELDLM_LOCK_MATCHED = 1,
72
73 ELDLM_LOCK_CHANGED = 300,
74 ELDLM_LOCK_ABORTED = 301,
75 ELDLM_LOCK_REPLACED = 302,
76 ELDLM_NO_LOCK_DATA = 303,
77 ELDLM_LOCK_WOULDBLOCK = 304,
78
79 ELDLM_NAMESPACE_EXISTS = 400,
80 ELDLM_BAD_NAMESPACE = 401
81};
82
83
84
85
86
87
88
89
90enum ldlm_side {
91 LDLM_NAMESPACE_SERVER = 1 << 0,
92 LDLM_NAMESPACE_CLIENT = 1 << 1
93};
94
95
96
97
98
99#define LDLM_CB_BLOCKING 1
100#define LDLM_CB_CANCELING 2
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136#define LCK_COMPAT_EX LCK_NL
137#define LCK_COMPAT_PW (LCK_COMPAT_EX | LCK_CR)
138#define LCK_COMPAT_PR (LCK_COMPAT_PW | LCK_PR)
139#define LCK_COMPAT_CW (LCK_COMPAT_PW | LCK_CW)
140#define LCK_COMPAT_CR (LCK_COMPAT_CW | LCK_PR | LCK_PW)
141#define LCK_COMPAT_NL (LCK_COMPAT_CR | LCK_EX | LCK_GROUP)
142#define LCK_COMPAT_GROUP (LCK_GROUP | LCK_NL)
143#define LCK_COMPAT_COS (LCK_COS)
144
145
146extern enum ldlm_mode lck_compat_array[];
147
148static inline void lockmode_verify(enum ldlm_mode mode)
149{
150 LASSERT(mode > LCK_MINMODE && mode < LCK_MAXMODE);
151}
152
153static inline int lockmode_compat(enum ldlm_mode exist_mode,
154 enum ldlm_mode new_mode)
155{
156 return (lck_compat_array[exist_mode] & new_mode);
157}
158
159
160
161
162
163
164
165#define DLM_OST_NAMESPACE 1
166#define DLM_MDS_NAMESPACE 2
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193struct ldlm_pool;
194struct ldlm_lock;
195struct ldlm_resource;
196struct ldlm_namespace;
197
198
199
200
201
202
203
204
205
206struct ldlm_pool_ops {
207
208 int (*po_recalc)(struct ldlm_pool *pl);
209
210 int (*po_shrink)(struct ldlm_pool *pl, int nr,
211 gfp_t gfp_mask);
212};
213
214
215#define LDLM_POOLS_THREAD_PERIOD (1)
216
217
218#define LDLM_POOLS_MODEST_MARGIN_SHIFT (4)
219
220
221#define LDLM_POOL_SRV_DEF_RECALC_PERIOD (1)
222
223
224#define LDLM_POOL_CLI_DEF_RECALC_PERIOD (10)
225
226
227
228
229
230
231struct ldlm_pool {
232
233 struct dentry *pl_debugfs_entry;
234
235 char pl_name[100];
236
237 spinlock_t pl_lock;
238
239 atomic_t pl_limit;
240
241 atomic_t pl_granted;
242
243 atomic_t pl_grant_rate;
244
245 atomic_t pl_cancel_rate;
246
247 __u64 pl_server_lock_volume;
248
249 __u64 pl_client_lock_volume;
250
251
252
253 atomic_t pl_lock_volume_factor;
254
255 time64_t pl_recalc_time;
256
257 time64_t pl_recalc_period;
258
259 const struct ldlm_pool_ops *pl_ops;
260
261 int pl_grant_plan;
262
263 struct lprocfs_stats *pl_stats;
264
265
266 struct kobject pl_kobj;
267 struct completion pl_kobj_unregister;
268};
269
270typedef int (*ldlm_cancel_cbt)(struct ldlm_lock *lock);
271
272
273
274
275
276
277
278
279
280
281
282struct ldlm_valblock_ops {
283 int (*lvbo_init)(struct ldlm_resource *res);
284 int (*lvbo_update)(struct ldlm_resource *res,
285 struct ptlrpc_request *r,
286 int increase);
287 int (*lvbo_free)(struct ldlm_resource *res);
288
289 int (*lvbo_size)(struct ldlm_lock *lock);
290
291 int (*lvbo_fill)(struct ldlm_lock *lock, void *buf, int buflen);
292};
293
294
295
296
297
298enum ldlm_appetite {
299 LDLM_NAMESPACE_GREEDY = 1 << 0,
300 LDLM_NAMESPACE_MODEST = 1 << 1
301};
302
303struct ldlm_ns_bucket {
304
305 struct ldlm_namespace *nsb_namespace;
306
307
308
309
310
311 struct adaptive_timeout nsb_at_estimate;
312};
313
314enum {
315
316 LDLM_NSS_LOCKS = 0,
317 LDLM_NSS_LAST
318};
319
320enum ldlm_ns_type {
321
322 LDLM_NS_TYPE_UNKNOWN = 0,
323
324 LDLM_NS_TYPE_MDC,
325
326 LDLM_NS_TYPE_MDT,
327
328 LDLM_NS_TYPE_OSC,
329
330 LDLM_NS_TYPE_OST,
331
332 LDLM_NS_TYPE_MGC,
333
334 LDLM_NS_TYPE_MGT,
335};
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358struct ldlm_namespace {
359
360 struct obd_device *ns_obd;
361
362
363 enum ldlm_side ns_client;
364
365
366 struct cfs_hash *ns_rs_hash;
367
368
369 spinlock_t ns_lock;
370
371
372 atomic_t ns_bref;
373
374
375
376
377
378 __u64 ns_connect_flags;
379
380
381 __u64 ns_orig_connect_flags;
382
383
384 struct dentry *ns_debugfs_entry;
385
386
387
388
389
390 struct list_head ns_list_chain;
391
392
393
394
395
396
397
398
399
400
401
402 struct list_head ns_unused_list;
403
404 int ns_nr_unused;
405
406
407
408
409
410
411 unsigned int ns_max_unused;
412
413 unsigned int ns_max_age;
414
415
416
417
418
419
420 unsigned long ns_next_dump;
421
422
423
424
425
426 struct ldlm_valblock_ops *ns_lvbo;
427
428
429
430
431
432 void *ns_lvbp;
433
434
435
436
437
438 wait_queue_head_t ns_waitq;
439
440 struct ldlm_pool ns_pool;
441
442 enum ldlm_appetite ns_appetite;
443
444
445 unsigned ns_max_parallel_ast;
446
447
448
449
450
451 ldlm_cancel_cbt ns_cancel;
452
453
454 struct lprocfs_stats *ns_stats;
455
456
457
458
459
460 unsigned ns_stopping:1;
461
462 struct kobject ns_kobj;
463 struct completion ns_kobj_unregister;
464};
465
466
467
468
469static inline int ns_connect_cancelset(struct ldlm_namespace *ns)
470{
471 return !!(ns->ns_connect_flags & OBD_CONNECT_CANCELSET);
472}
473
474
475
476
477static inline int ns_connect_lru_resize(struct ldlm_namespace *ns)
478{
479 return !!(ns->ns_connect_flags & OBD_CONNECT_LRU_RESIZE);
480}
481
482static inline void ns_register_cancel(struct ldlm_namespace *ns,
483 ldlm_cancel_cbt arg)
484{
485 ns->ns_cancel = arg;
486}
487
488struct ldlm_lock;
489
490
491typedef int (*ldlm_blocking_callback)(struct ldlm_lock *lock,
492 struct ldlm_lock_desc *new, void *data,
493 int flag);
494
495typedef int (*ldlm_completion_callback)(struct ldlm_lock *lock, __u64 flags,
496 void *data);
497
498typedef int (*ldlm_glimpse_callback)(struct ldlm_lock *lock, void *data);
499
500
501struct ldlm_glimpse_work {
502 struct ldlm_lock *gl_lock;
503 struct list_head gl_list;
504 __u32 gl_flags;
505 union ldlm_gl_desc *gl_desc;
506
507
508};
509
510
511#define LDLM_GL_WORK_NOFREE 0x1
512
513
514struct ldlm_interval {
515 struct interval_node li_node;
516 struct list_head li_group;
517
518
519};
520
521#define to_ldlm_interval(n) container_of(n, struct ldlm_interval, li_node)
522
523
524
525
526
527
528
529struct ldlm_interval_tree {
530
531 int lit_size;
532 enum ldlm_mode lit_mode;
533 struct interval_node *lit_root;
534};
535
536
537#define LUSTRE_TRACKS_LOCK_EXP_REFS (0)
538
539
540enum ldlm_cancel_flags {
541 LCF_ASYNC = 0x1,
542 LCF_LOCAL = 0x2,
543 LCF_BL_AST = 0x4,
544
545
546};
547
548struct ldlm_flock {
549 __u64 start;
550 __u64 end;
551 __u64 owner;
552 __u64 blocking_owner;
553 struct obd_export *blocking_export;
554 __u32 pid;
555};
556
557union ldlm_policy_data {
558 struct ldlm_extent l_extent;
559 struct ldlm_flock l_flock;
560 struct ldlm_inodebits l_inodebits;
561};
562
563void ldlm_convert_policy_to_local(struct obd_export *exp, enum ldlm_type type,
564 const union ldlm_wire_policy_data *wpolicy,
565 union ldlm_policy_data *lpolicy);
566
567enum lvb_type {
568 LVB_T_NONE = 0,
569 LVB_T_OST = 1,
570 LVB_T_LQUOTA = 2,
571 LVB_T_LAYOUT = 3,
572};
573
574
575
576
577#define LDLM_GID_ANY ((__u64)-1)
578
579
580
581
582
583
584
585
586
587
588struct ldlm_lock {
589
590
591
592
593
594
595
596
597
598
599
600 struct portals_handle l_handle;
601
602
603
604
605
606 atomic_t l_refc;
607
608
609
610
611 spinlock_t l_lock;
612
613
614
615
616 struct ldlm_resource *l_resource;
617
618
619
620
621 struct list_head l_lru;
622
623
624
625
626
627 struct list_head l_res_link;
628
629
630
631 struct ldlm_interval *l_tree_node;
632
633
634
635
636 struct hlist_node l_exp_hash;
637
638
639
640
641 struct hlist_node l_exp_flock_hash;
642
643
644
645
646 enum ldlm_mode l_req_mode;
647
648
649
650 enum ldlm_mode l_granted_mode;
651
652 ldlm_completion_callback l_completion_ast;
653
654
655
656
657
658
659
660
661
662
663 ldlm_blocking_callback l_blocking_ast;
664
665
666
667
668
669 ldlm_glimpse_callback l_glimpse_ast;
670
671
672
673
674
675
676 struct obd_export *l_export;
677
678
679
680
681 struct obd_export *l_conn_export;
682
683
684
685
686
687
688 struct lustre_handle l_remote_handle;
689
690
691
692
693
694 union ldlm_policy_data l_policy_data;
695
696
697
698
699
700 __u64 l_flags;
701
702
703
704
705
706 __u32 l_readers;
707 __u32 l_writers;
708
709
710
711
712
713 wait_queue_head_t l_waitq;
714
715
716
717
718
719 time64_t l_last_activity;
720
721
722
723
724
725 unsigned long l_last_used;
726
727
728 struct ldlm_extent l_req_extent;
729
730
731
732
733
734 enum lvb_type l_lvb_type;
735
736
737
738
739 __u32 l_lvb_len;
740 void *l_lvb_data;
741
742
743 void *l_ast_data;
744
745
746
747
748
749
750
751
752
753
754 __u64 l_client_cookie;
755
756
757
758
759
760
761
762
763
764 struct list_head l_pending_chain;
765
766
767
768
769
770
771
772
773 unsigned long l_callback_timeout;
774
775
776 __u32 l_pid;
777
778
779
780
781
782
783
784 int l_bl_ast_run;
785
786 struct list_head l_bl_ast;
787
788 struct list_head l_cp_ast;
789
790 struct list_head l_rk_ast;
791
792
793
794
795
796 struct ldlm_lock *l_blocking_lock;
797
798
799
800
801
802 struct list_head l_sl_mode;
803 struct list_head l_sl_policy;
804
805
806 struct lu_ref l_reference;
807#if LUSTRE_TRACKS_LOCK_EXP_REFS
808
809
810 int l_exp_refs_nr;
811
812 struct list_head l_exp_refs_link;
813
814 struct obd_export *l_exp_refs_target;
815#endif
816};
817
818
819
820
821
822
823
824
825
826
827
828
829struct ldlm_resource {
830 struct ldlm_ns_bucket *lr_ns_bucket;
831
832
833
834
835
836 struct hlist_node lr_hash;
837
838
839 spinlock_t lr_lock;
840
841
842
843
844
845
846 struct list_head lr_granted;
847
848
849
850
851 struct list_head lr_waiting;
852
853
854
855 enum ldlm_type lr_type;
856
857
858 struct ldlm_res_id lr_name;
859
860 atomic_t lr_refcount;
861
862
863
864
865 struct ldlm_interval_tree lr_itree[LCK_MODE_NUM];
866
867
868
869
870
871 struct mutex lr_lvb_mutex;
872 int lr_lvb_len;
873
874
875 unsigned long lr_contention_time;
876
877 struct lu_ref lr_reference;
878
879 struct inode *lr_lvb_inode;
880};
881
882static inline bool ldlm_has_layout(struct ldlm_lock *lock)
883{
884 return lock->l_resource->lr_type == LDLM_IBITS &&
885 lock->l_policy_data.l_inodebits.bits & MDS_INODELOCK_LAYOUT;
886}
887
888static inline char *
889ldlm_ns_name(struct ldlm_namespace *ns)
890{
891 return ns->ns_rs_hash->hs_name;
892}
893
894static inline struct ldlm_namespace *
895ldlm_res_to_ns(struct ldlm_resource *res)
896{
897 return res->lr_ns_bucket->nsb_namespace;
898}
899
900static inline struct ldlm_namespace *
901ldlm_lock_to_ns(struct ldlm_lock *lock)
902{
903 return ldlm_res_to_ns(lock->l_resource);
904}
905
906static inline char *
907ldlm_lock_to_ns_name(struct ldlm_lock *lock)
908{
909 return ldlm_ns_name(ldlm_lock_to_ns(lock));
910}
911
912static inline struct adaptive_timeout *
913ldlm_lock_to_ns_at(struct ldlm_lock *lock)
914{
915 return &lock->l_resource->lr_ns_bucket->nsb_at_estimate;
916}
917
918static inline int ldlm_lvbo_init(struct ldlm_resource *res)
919{
920 struct ldlm_namespace *ns = ldlm_res_to_ns(res);
921
922 if (ns->ns_lvbo && ns->ns_lvbo->lvbo_init)
923 return ns->ns_lvbo->lvbo_init(res);
924
925 return 0;
926}
927
928static inline int ldlm_lvbo_size(struct ldlm_lock *lock)
929{
930 struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
931
932 if (ns->ns_lvbo && ns->ns_lvbo->lvbo_size)
933 return ns->ns_lvbo->lvbo_size(lock);
934
935 return 0;
936}
937
938static inline int ldlm_lvbo_fill(struct ldlm_lock *lock, void *buf, int len)
939{
940 struct ldlm_namespace *ns = ldlm_lock_to_ns(lock);
941
942 if (ns->ns_lvbo)
943 return ns->ns_lvbo->lvbo_fill(lock, buf, len);
944
945 return 0;
946}
947
948struct ldlm_ast_work {
949 struct ldlm_lock *w_lock;
950 int w_blocking;
951 struct ldlm_lock_desc w_desc;
952 struct list_head w_list;
953 int w_flags;
954 void *w_data;
955 int w_datalen;
956};
957
958
959
960
961struct ldlm_enqueue_info {
962 enum ldlm_type ei_type;
963 enum ldlm_mode ei_mode;
964 void *ei_cb_bl;
965 void *ei_cb_cp;
966 void *ei_cb_gl;
967 void *ei_cbdata;
968 unsigned int ei_enq_slave:1;
969};
970
971extern struct obd_ops ldlm_obd_ops;
972
973extern char *ldlm_lockname[];
974const char *ldlm_it2str(enum ldlm_intent_flags it);
975
976
977
978
979
980
981#define LDLM_DEBUG_NOLOCK(format, a...) \
982 CDEBUG(D_DLMTRACE, "### " format "\n", ##a)
983
984
985
986
987
988#define ldlm_lock_debug(msgdata, mask, cdls, lock, fmt, a...) do { \
989 CFS_CHECK_STACK(msgdata, mask, cdls); \
990 \
991 if (((mask) & D_CANTMASK) != 0 || \
992 ((libcfs_debug & (mask)) != 0 && \
993 (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) \
994 _ldlm_lock_debug(lock, msgdata, fmt, ##a); \
995} while (0)
996
997void _ldlm_lock_debug(struct ldlm_lock *lock,
998 struct libcfs_debug_msg_data *data,
999 const char *fmt, ...)
1000 __printf(3, 4);
1001
1002
1003
1004
1005#define LDLM_DEBUG_LIMIT(mask, lock, fmt, a...) do { \
1006 static struct cfs_debug_limit_state _ldlm_cdls; \
1007 LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, &_ldlm_cdls); \
1008 ldlm_lock_debug(&msgdata, mask, &_ldlm_cdls, lock, "### " fmt, ##a);\
1009} while (0)
1010
1011#define LDLM_ERROR(lock, fmt, a...) LDLM_DEBUG_LIMIT(D_ERROR, lock, fmt, ## a)
1012#define LDLM_WARN(lock, fmt, a...) LDLM_DEBUG_LIMIT(D_WARNING, lock, fmt, ## a)
1013
1014
1015#define LDLM_DEBUG(lock, fmt, a...) do { \
1016 if (likely(lock)) { \
1017 LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_DLMTRACE, NULL); \
1018 ldlm_lock_debug(&msgdata, D_DLMTRACE, NULL, lock, \
1019 "### " fmt, ##a); \
1020 } else { \
1021 LDLM_DEBUG_NOLOCK("no dlm lock: " fmt, ##a); \
1022 } \
1023} while (0)
1024
1025typedef int (*ldlm_processing_policy)(struct ldlm_lock *lock, __u64 *flags,
1026 int first_enq, enum ldlm_error *err,
1027 struct list_head *work_list);
1028
1029
1030
1031
1032
1033#define LDLM_ITER_CONTINUE 1
1034#define LDLM_ITER_STOP 2
1035
1036typedef int (*ldlm_iterator_t)(struct ldlm_lock *, void *);
1037typedef int (*ldlm_res_iterator_t)(struct ldlm_resource *, void *);
1038
1039
1040
1041
1042
1043
1044
1045int ldlm_resource_iterate(struct ldlm_namespace *, const struct ldlm_res_id *,
1046 ldlm_iterator_t iter, void *data);
1047
1048
1049int ldlm_replay_locks(struct obd_import *imp);
1050
1051
1052int ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data);
1053
1054
1055__u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, __u64 old_kms);
1056
1057struct ldlm_callback_suite {
1058 ldlm_completion_callback lcs_completion;
1059 ldlm_blocking_callback lcs_blocking;
1060 ldlm_glimpse_callback lcs_glimpse;
1061};
1062
1063
1064int ldlm_get_ref(void);
1065void ldlm_put_ref(void);
1066struct ldlm_lock *ldlm_request_lock(struct ptlrpc_request *req);
1067
1068
1069void ldlm_lock2handle(const struct ldlm_lock *lock,
1070 struct lustre_handle *lockh);
1071struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *, __u64 flags);
1072void ldlm_cancel_callback(struct ldlm_lock *);
1073int ldlm_lock_remove_from_lru(struct ldlm_lock *);
1074int ldlm_lock_set_data(const struct lustre_handle *lockh, void *data);
1075
1076
1077
1078
1079static inline struct ldlm_lock *ldlm_handle2lock(const struct lustre_handle *h)
1080{
1081 return __ldlm_handle2lock(h, 0);
1082}
1083
1084#define LDLM_LOCK_REF_DEL(lock) \
1085 lu_ref_del(&lock->l_reference, "handle", current)
1086
1087static inline struct ldlm_lock *
1088ldlm_handle2lock_long(const struct lustre_handle *h, __u64 flags)
1089{
1090 struct ldlm_lock *lock;
1091
1092 lock = __ldlm_handle2lock(h, flags);
1093 if (lock)
1094 LDLM_LOCK_REF_DEL(lock);
1095 return lock;
1096}
1097
1098
1099
1100
1101
1102static inline int ldlm_res_lvbo_update(struct ldlm_resource *res,
1103 struct ptlrpc_request *r, int increase)
1104{
1105 if (ldlm_res_to_ns(res)->ns_lvbo &&
1106 ldlm_res_to_ns(res)->ns_lvbo->lvbo_update) {
1107 return ldlm_res_to_ns(res)->ns_lvbo->lvbo_update(res, r,
1108 increase);
1109 }
1110 return 0;
1111}
1112
1113int ldlm_error2errno(enum ldlm_error error);
1114
1115#if LUSTRE_TRACKS_LOCK_EXP_REFS
1116void ldlm_dump_export_locks(struct obd_export *exp);
1117#endif
1118
1119
1120
1121
1122
1123#define LDLM_LOCK_PUT(lock) \
1124do { \
1125 LDLM_LOCK_REF_DEL(lock); \
1126 \
1127 ldlm_lock_put(lock); \
1128} while (0)
1129
1130
1131
1132
1133
1134#define LDLM_LOCK_RELEASE(lock) \
1135do { \
1136 \
1137 ldlm_lock_put(lock); \
1138} while (0)
1139
1140#define LDLM_LOCK_GET(lock) \
1141({ \
1142 ldlm_lock_get(lock); \
1143 \
1144 lock; \
1145})
1146
1147#define ldlm_lock_list_put(head, member, count) \
1148({ \
1149 struct ldlm_lock *_lock, *_next; \
1150 int c = count; \
1151 list_for_each_entry_safe(_lock, _next, head, member) { \
1152 if (c-- == 0) \
1153 break; \
1154 list_del_init(&_lock->member); \
1155 LDLM_LOCK_RELEASE(_lock); \
1156 } \
1157 LASSERT(c <= 0); \
1158})
1159
1160struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock);
1161void ldlm_lock_put(struct ldlm_lock *lock);
1162void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc);
1163void ldlm_lock_addref(const struct lustre_handle *lockh, enum ldlm_mode mode);
1164int ldlm_lock_addref_try(const struct lustre_handle *lockh,
1165 enum ldlm_mode mode);
1166void ldlm_lock_decref(const struct lustre_handle *lockh, enum ldlm_mode mode);
1167void ldlm_lock_decref_and_cancel(const struct lustre_handle *lockh,
1168 enum ldlm_mode mode);
1169void ldlm_lock_fail_match_locked(struct ldlm_lock *lock);
1170void ldlm_lock_allow_match(struct ldlm_lock *lock);
1171void ldlm_lock_allow_match_locked(struct ldlm_lock *lock);
1172enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
1173 const struct ldlm_res_id *,
1174 enum ldlm_type type, union ldlm_policy_data *,
1175 enum ldlm_mode mode, struct lustre_handle *,
1176 int unref);
1177enum ldlm_mode ldlm_revalidate_lock_handle(const struct lustre_handle *lockh,
1178 __u64 *bits);
1179void ldlm_lock_cancel(struct ldlm_lock *lock);
1180void ldlm_lock_dump_handle(int level, const struct lustre_handle *);
1181void ldlm_unlink_lock_skiplist(struct ldlm_lock *req);
1182
1183
1184struct ldlm_namespace *
1185ldlm_namespace_new(struct obd_device *obd, char *name,
1186 enum ldlm_side client, enum ldlm_appetite apt,
1187 enum ldlm_ns_type ns_type);
1188int ldlm_namespace_cleanup(struct ldlm_namespace *ns, __u64 flags);
1189void ldlm_namespace_free_prior(struct ldlm_namespace *ns,
1190 struct obd_import *imp,
1191 int force);
1192void ldlm_namespace_free_post(struct ldlm_namespace *ns);
1193void ldlm_namespace_get(struct ldlm_namespace *ns);
1194void ldlm_namespace_put(struct ldlm_namespace *ns);
1195int ldlm_debugfs_setup(void);
1196void ldlm_debugfs_cleanup(void);
1197
1198
1199struct ldlm_resource *ldlm_resource_get(struct ldlm_namespace *ns,
1200 struct ldlm_resource *parent,
1201 const struct ldlm_res_id *,
1202 enum ldlm_type type, int create);
1203int ldlm_resource_putref(struct ldlm_resource *res);
1204void ldlm_resource_add_lock(struct ldlm_resource *res,
1205 struct list_head *head,
1206 struct ldlm_lock *lock);
1207void ldlm_resource_unlink_lock(struct ldlm_lock *lock);
1208void ldlm_res2desc(struct ldlm_resource *res, struct ldlm_resource_desc *desc);
1209void ldlm_dump_all_namespaces(enum ldlm_side client, int level);
1210void ldlm_namespace_dump(int level, struct ldlm_namespace *);
1211void ldlm_resource_dump(int level, struct ldlm_resource *);
1212int ldlm_lock_change_resource(struct ldlm_namespace *, struct ldlm_lock *,
1213 const struct ldlm_res_id *);
1214
1215#define LDLM_RESOURCE_ADDREF(res) do { \
1216 lu_ref_add_atomic(&(res)->lr_reference, __func__, current); \
1217} while (0)
1218
1219#define LDLM_RESOURCE_DELREF(res) do { \
1220 lu_ref_del(&(res)->lr_reference, __func__, current); \
1221} while (0)
1222
1223
1224
1225
1226
1227
1228
1229
1230int ldlm_completion_ast_async(struct ldlm_lock *lock, __u64 flags, void *data);
1231int ldlm_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data);
1232
1233
1234
1235
1236
1237
1238
1239int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp,
1240 struct ldlm_enqueue_info *einfo,
1241 const struct ldlm_res_id *res_id,
1242 union ldlm_policy_data const *policy, __u64 *flags,
1243 void *lvb, __u32 lvb_len, enum lvb_type lvb_type,
1244 struct lustre_handle *lockh, int async);
1245int ldlm_prep_enqueue_req(struct obd_export *exp,
1246 struct ptlrpc_request *req,
1247 struct list_head *cancels,
1248 int count);
1249int ldlm_prep_elc_req(struct obd_export *exp,
1250 struct ptlrpc_request *req,
1251 int version, int opc, int canceloff,
1252 struct list_head *cancels, int count);
1253
1254int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req,
1255 enum ldlm_type type, __u8 with_policy,
1256 enum ldlm_mode mode,
1257 __u64 *flags, void *lvb, __u32 lvb_len,
1258 const struct lustre_handle *lockh, int rc);
1259int ldlm_cli_update_pool(struct ptlrpc_request *req);
1260int ldlm_cli_cancel(const struct lustre_handle *lockh,
1261 enum ldlm_cancel_flags cancel_flags);
1262int ldlm_cli_cancel_unused(struct ldlm_namespace *, const struct ldlm_res_id *,
1263 enum ldlm_cancel_flags flags, void *opaque);
1264int ldlm_cli_cancel_unused_resource(struct ldlm_namespace *ns,
1265 const struct ldlm_res_id *res_id,
1266 union ldlm_policy_data *policy,
1267 enum ldlm_mode mode,
1268 enum ldlm_cancel_flags flags,
1269 void *opaque);
1270int ldlm_cancel_resource_local(struct ldlm_resource *res,
1271 struct list_head *cancels,
1272 union ldlm_policy_data *policy,
1273 enum ldlm_mode mode, __u64 lock_flags,
1274 enum ldlm_cancel_flags cancel_flags,
1275 void *opaque);
1276int ldlm_cli_cancel_list_local(struct list_head *cancels, int count,
1277 enum ldlm_cancel_flags flags);
1278int ldlm_cli_cancel_list(struct list_head *head, int count,
1279 struct ptlrpc_request *req,
1280 enum ldlm_cancel_flags flags);
1281
1282
1283
1284
1285int intent_disposition(struct ldlm_reply *rep, int flag);
1286void intent_set_disposition(struct ldlm_reply *rep, int flag);
1287
1288
1289
1290
1291
1292enum lock_res_type {
1293 LRT_NORMAL,
1294 LRT_NEW
1295};
1296
1297
1298static inline void lock_res(struct ldlm_resource *res)
1299{
1300 spin_lock(&res->lr_lock);
1301}
1302
1303
1304static inline void lock_res_nested(struct ldlm_resource *res,
1305 enum lock_res_type mode)
1306{
1307 spin_lock_nested(&res->lr_lock, mode);
1308}
1309
1310
1311static inline void unlock_res(struct ldlm_resource *res)
1312{
1313 spin_unlock(&res->lr_lock);
1314}
1315
1316
1317static inline void check_res_locked(struct ldlm_resource *res)
1318{
1319 assert_spin_locked(&res->lr_lock);
1320}
1321
1322struct ldlm_resource *lock_res_and_lock(struct ldlm_lock *lock);
1323void unlock_res_and_lock(struct ldlm_lock *lock);
1324
1325
1326
1327
1328
1329
1330int ldlm_pools_init(void);
1331void ldlm_pools_fini(void);
1332
1333int ldlm_pool_init(struct ldlm_pool *pl, struct ldlm_namespace *ns,
1334 int idx, enum ldlm_side client);
1335void ldlm_pool_fini(struct ldlm_pool *pl);
1336void ldlm_pool_add(struct ldlm_pool *pl, struct ldlm_lock *lock);
1337void ldlm_pool_del(struct ldlm_pool *pl, struct ldlm_lock *lock);
1338
1339
1340static inline int ldlm_extent_overlap(const struct ldlm_extent *ex1,
1341 const struct ldlm_extent *ex2)
1342{
1343 return ex1->start <= ex2->end && ex2->start <= ex1->end;
1344}
1345
1346
1347static inline int ldlm_extent_contain(const struct ldlm_extent *ex1,
1348 const struct ldlm_extent *ex2)
1349{
1350 return ex1->start <= ex2->start && ex1->end >= ex2->end;
1351}
1352
1353#endif
1354
1355