linux/drivers/staging/lustre/lustre/include/lu_ref.h
<<
>>
Prefs
   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, __FUNCTION__, current);
  73 *
  74 *      ...
  75 *
  76 *      // temporary reference is released.
  77 *      lu_ref_del(&foo->reference, __FUNCTION__, 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
 111struct lu_ref  {};
 112
 113static inline void lu_ref_init(struct lu_ref *ref)
 114{
 115}
 116
 117static inline void lu_ref_fini(struct lu_ref *ref)
 118{
 119}
 120
 121static 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
 128static 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
 135static inline void lu_ref_del(struct lu_ref *ref, const char *scope,
 136                              const void *source)
 137{
 138}
 139
 140static inline void lu_ref_set_at(struct lu_ref *ref, struct lu_ref_link *link,
 141                                 const char *scope, const void *source0,
 142                                 const void *source1)
 143{
 144}
 145
 146static inline void lu_ref_del_at(struct lu_ref *ref, struct lu_ref_link *link,
 147                                 const char *scope, const void *source)
 148{
 149}
 150
 151static inline int lu_ref_global_init(void)
 152{
 153        return 0;
 154}
 155
 156static inline void lu_ref_global_fini(void)
 157{
 158}
 159
 160static inline void lu_ref_print(const struct lu_ref *ref)
 161{
 162}
 163
 164static inline void lu_ref_print_all(void)
 165{
 166}
 167
 168/** @} lu */
 169
 170#endif /* __LUSTRE_LU_REF_H */
 171