]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/staging/lustre/lustre/include/lu_ref.h
Merge branch 'stable/for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-artful-kernel.git] / drivers / staging / lustre / lustre / include / lu_ref.h
1 /*
2 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
3 * Use is subject to license terms.
4 *
5 * Copyright (c) 2012, Intel Corporation.
6 *
7 * Author: Nikita Danilov <nikita.danilov@sun.com>
8 *
9 * This file is part of Lustre, http://www.lustre.org.
10 *
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
14 *
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22 #ifndef __LUSTRE_LU_REF_H
23 #define __LUSTRE_LU_REF_H
24
25 #include <linux/list.h>
26
27 /** \defgroup lu_ref lu_ref
28 *
29 * An interface to track references between objects. Mostly for debugging.
30 *
31 * Suppose there is a reference counted data-structure struct foo. To track
32 * who acquired references to instance of struct foo, add lu_ref field to it:
33 *
34 * \code
35 * struct foo {
36 * atomic_t foo_refcount;
37 * struct lu_ref foo_reference;
38 * ...
39 * };
40 * \endcode
41 *
42 * foo::foo_reference has to be initialized by calling
43 * lu_ref_init(). Typically there will be functions or macros to increment and
44 * decrement foo::foo_refcount, let's say they are foo_get(struct foo *foo)
45 * and foo_put(struct foo *foo), respectively.
46 *
47 * Whenever foo_get() is called to acquire a reference on a foo, lu_ref_add()
48 * has to be called to insert into foo::foo_reference a record, describing
49 * acquired reference. Dually, lu_ref_del() removes matching record. Typical
50 * usages are:
51 *
52 * \code
53 * struct bar *bar;
54 *
55 * // bar owns a reference to foo.
56 * bar->bar_foo = foo_get(foo);
57 * lu_ref_add(&foo->foo_reference, "bar", bar);
58 *
59 * ...
60 *
61 * // reference from bar to foo is released.
62 * lu_ref_del(&foo->foo_reference, "bar", bar);
63 * foo_put(bar->bar_foo);
64 *
65 *
66 * // current thread acquired a temporary reference to foo.
67 * foo_get(foo);
68 * lu_ref_add(&foo->reference, __func__, current);
69 *
70 * ...
71 *
72 * // temporary reference is released.
73 * lu_ref_del(&foo->reference, __func__, current);
74 * foo_put(foo);
75 * \endcode
76 *
77 * \e Et \e cetera. Often it makes sense to include lu_ref_add() and
78 * lu_ref_del() calls into foo_get() and foo_put(). When an instance of struct
79 * foo is destroyed, lu_ref_fini() has to be called that checks that no
80 * pending references remain. lu_ref_print() can be used to dump a list of
81 * pending references, while hunting down a leak.
82 *
83 * For objects to which a large number of references can be acquired,
84 * lu_ref_del() can become cpu consuming, as it has to scan the list of
85 * references. To work around this, remember result of lu_ref_add() (usually
86 * in the same place where pointer to struct foo is stored), and use
87 * lu_ref_del_at():
88 *
89 * \code
90 * // There is a large number of bar's for a single foo.
91 * bar->bar_foo = foo_get(foo);
92 * bar->bar_foo_ref = lu_ref_add(&foo->foo_reference, "bar", bar);
93 *
94 * ...
95 *
96 * // reference from bar to foo is released.
97 * lu_ref_del_at(&foo->foo_reference, bar->bar_foo_ref, "bar", bar);
98 * foo_put(bar->bar_foo);
99 * \endcode
100 *
101 * lu_ref interface degrades gracefully in case of memory shortages.
102 *
103 * @{
104 */
105
106 /*
107 * dummy data structures/functions to pass compile for now.
108 * We need to reimplement them with kref.
109 */
110 struct lu_ref {};
111 struct lu_ref_link {};
112
113 static inline void lu_ref_init(struct lu_ref *ref)
114 {
115 }
116
117 static inline void lu_ref_fini(struct lu_ref *ref)
118 {
119 }
120
121 static inline struct lu_ref_link *lu_ref_add(struct lu_ref *ref,
122 const char *scope,
123 const void *source)
124 {
125 return NULL;
126 }
127
128 static inline struct lu_ref_link *lu_ref_add_atomic(struct lu_ref *ref,
129 const char *scope,
130 const void *source)
131 {
132 return NULL;
133 }
134
135 static inline void lu_ref_add_at(struct lu_ref *ref,
136 struct lu_ref_link *link,
137 const char *scope,
138 const void *source)
139 {
140 }
141
142 static inline void lu_ref_del(struct lu_ref *ref, const char *scope,
143 const void *source)
144 {
145 }
146
147 static inline void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link,
148 const char *scope, const void *source0,
149 const void *source1)
150 {
151 }
152
153 static inline void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link,
154 const char *scope, const void *source)
155 {
156 }
157
158 static inline int lu_ref_global_init(void)
159 {
160 return 0;
161 }
162
163 static inline void lu_ref_global_fini(void)
164 {
165 }
166
167 static inline void lu_ref_print(const struct lu_ref *ref)
168 {
169 }
170
171 static inline void lu_ref_print_all(void)
172 {
173 }
174
175 /** @} lu */
176
177 #endif /* __LUSTRE_LU_REF_H */