• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  *   You should have received a copy of the GNU General Public License
21  *   along with Lustre; if not, write to the Free Software
22  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 
26 #ifndef __LUSTRE_LU_REF_H
27 #define __LUSTRE_LU_REF_H
28 
29 #include <linux/list.h>
30 
31 /** \defgroup lu_ref lu_ref
32  *
33  * An interface to track references between objects. Mostly for debugging.
34  *
35  * Suppose there is a reference counted data-structure struct foo. To track
36  * who acquired references to instance of struct foo, add lu_ref field to it:
37  *
38  * \code
39  *	 struct foo {
40  *		 atomic_t      foo_refcount;
41  *		 struct lu_ref foo_reference;
42  *		 ...
43  *	 };
44  * \endcode
45  *
46  * foo::foo_reference has to be initialized by calling
47  * lu_ref_init(). Typically there will be functions or macros to increment and
48  * decrement foo::foo_refcount, let's say they are foo_get(struct foo *foo)
49  * and foo_put(struct foo *foo), respectively.
50  *
51  * Whenever foo_get() is called to acquire a reference on a foo, lu_ref_add()
52  * has to be called to insert into foo::foo_reference a record, describing
53  * acquired reference. Dually, lu_ref_del() removes matching record. Typical
54  * usages are:
55  *
56  * \code
57  *	struct bar *bar;
58  *
59  *	// bar owns a reference to foo.
60  *	bar->bar_foo = foo_get(foo);
61  *	lu_ref_add(&foo->foo_reference, "bar", bar);
62  *
63  *	...
64  *
65  *	// reference from bar to foo is released.
66  *	lu_ref_del(&foo->foo_reference, "bar", bar);
67  *	foo_put(bar->bar_foo);
68  *
69  *
70  *	// current thread acquired a temporary reference to foo.
71  *	foo_get(foo);
72  *	lu_ref_add(&foo->reference, __func__, current);
73  *
74  *	...
75  *
76  *	// temporary reference is released.
77  *	lu_ref_del(&foo->reference, __func__, current);
78  *	foo_put(foo);
79  * \endcode
80  *
81  * \e Et \e cetera. Often it makes sense to include lu_ref_add() and
82  * lu_ref_del() calls into foo_get() and foo_put(). When an instance of struct
83  * foo is destroyed, lu_ref_fini() has to be called that checks that no
84  * pending references remain. lu_ref_print() can be used to dump a list of
85  * pending references, while hunting down a leak.
86  *
87  * For objects to which a large number of references can be acquired,
88  * lu_ref_del() can become cpu consuming, as it has to scan the list of
89  * references. To work around this, remember result of lu_ref_add() (usually
90  * in the same place where pointer to struct foo is stored), and use
91  * lu_ref_del_at():
92  *
93  * \code
94  *	// There is a large number of bar's for a single foo.
95  *	bar->bar_foo     = foo_get(foo);
96  *	bar->bar_foo_ref = lu_ref_add(&foo->foo_reference, "bar", bar);
97  *
98  *	...
99  *
100  *	// reference from bar to foo is released.
101  *	lu_ref_del_at(&foo->foo_reference, bar->bar_foo_ref, "bar", bar);
102  *	foo_put(bar->bar_foo);
103  * \endcode
104  *
105  * lu_ref interface degrades gracefully in case of memory shortages.
106  *
107  * @{
108  */
109 
110 /*
111  * dummy data structures/functions to pass compile for now.
112  * We need to reimplement them with kref.
113  */
114 struct lu_ref {};
115 struct lu_ref_link {};
116 
lu_ref_init(struct lu_ref * ref)117 static inline void lu_ref_init(struct lu_ref *ref)
118 {
119 }
120 
lu_ref_fini(struct lu_ref * ref)121 static inline void lu_ref_fini(struct lu_ref *ref)
122 {
123 }
124 
lu_ref_add(struct lu_ref * ref,const char * scope,const void * source)125 static inline struct lu_ref_link *lu_ref_add(struct lu_ref *ref,
126 					     const char *scope,
127 					     const void *source)
128 {
129 	return NULL;
130 }
131 
lu_ref_add_atomic(struct lu_ref * ref,const char * scope,const void * source)132 static inline struct lu_ref_link *lu_ref_add_atomic(struct lu_ref *ref,
133 						    const char *scope,
134 						    const void *source)
135 {
136 	return NULL;
137 }
138 
lu_ref_add_at(struct lu_ref * ref,struct lu_ref_link * link,const char * scope,const void * source)139 static inline void lu_ref_add_at(struct lu_ref *ref,
140 				 struct lu_ref_link *link,
141 				 const char *scope,
142 				 const void *source)
143 {
144 }
145 
lu_ref_del(struct lu_ref * ref,const char * scope,const void * source)146 static inline void lu_ref_del(struct lu_ref *ref, const char *scope,
147 			      const void *source)
148 {
149 }
150 
lu_ref_set_at(struct lu_ref * ref,struct lu_ref_link * link,const char * scope,const void * source0,const void * source1)151 static inline void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link,
152 				 const char *scope, const void *source0,
153 				 const void *source1)
154 {
155 }
156 
lu_ref_del_at(struct lu_ref * ref,struct lu_ref_link * link,const char * scope,const void * source)157 static inline void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link,
158 				 const char *scope, const void *source)
159 {
160 }
161 
lu_ref_global_init(void)162 static inline int lu_ref_global_init(void)
163 {
164 	return 0;
165 }
166 
lu_ref_global_fini(void)167 static inline void lu_ref_global_fini(void)
168 {
169 }
170 
lu_ref_print(const struct lu_ref * ref)171 static inline void lu_ref_print(const struct lu_ref *ref)
172 {
173 }
174 
lu_ref_print_all(void)175 static inline void lu_ref_print_all(void)
176 {
177 }
178 
179 /** @} lu */
180 
181 #endif /* __LUSTRE_LU_REF_H */
182