[go: nahoru, domu]

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/*
112 * dummy data structures/functions to pass compile for now.
113 * We need to reimplement them with kref.
114 */
115struct lu_ref {};
116struct lu_ref_link {};
117
118static inline void lu_ref_init(struct lu_ref *ref)
119{
120}
121
122static inline void lu_ref_fini(struct lu_ref *ref)
123{
124}
125
126static inline struct lu_ref_link *lu_ref_add(struct lu_ref *ref,
127					     const char *scope,
128					     const void *source)
129{
130	return NULL;
131}
132
133static inline struct lu_ref_link *lu_ref_add_atomic(struct lu_ref *ref,
134						    const char *scope,
135						    const void *source)
136{
137	return NULL;
138}
139
140static inline void lu_ref_add_at(struct lu_ref *ref,
141				 struct lu_ref_link *link,
142				 const char *scope,
143				 const void *source)
144{
145}
146
147static inline void lu_ref_del(struct lu_ref *ref, const char *scope,
148			      const void *source)
149{
150}
151
152static inline void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link,
153				 const char *scope, const void *source0,
154				 const void *source1)
155{
156}
157
158static inline void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link,
159				 const char *scope, const void *source)
160{
161}
162
163static inline int lu_ref_global_init(void)
164{
165	return 0;
166}
167
168static inline void lu_ref_global_fini(void)
169{
170}
171
172static inline void lu_ref_print(const struct lu_ref *ref)
173{
174}
175
176static inline void lu_ref_print_all(void)
177{
178}
179
180/** @} lu */
181
182#endif /* __LUSTRE_LU_REF_H */
183