~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux-2.6.17/drivers/md/dm-path-selector.c

Version: ~ [ 2.6.16 ] ~ [ 2.6.17 ] ~
Architecture: ~ [ ia64 ] ~ [ i386 ] ~ [ arm ] ~ [ ppc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright (C) 2003 Sistina Software.
  3  * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
  4  *
  5  * Module Author: Heinz Mauelshagen
  6  *
  7  * This file is released under the GPL.
  8  *
  9  * Path selector registration.
 10  */
 11 
 12 #include "dm.h"
 13 #include "dm-path-selector.h"
 14 
 15 #include <linux/slab.h>
 16 
 17 struct ps_internal {
 18         struct path_selector_type pst;
 19 
 20         struct list_head list;
 21         long use;
 22 };
 23 
 24 #define pst_to_psi(__pst) container_of((__pst), struct ps_internal, pst)
 25 
 26 static LIST_HEAD(_path_selectors);
 27 static DECLARE_RWSEM(_ps_lock);
 28 
 29 static struct ps_internal *__find_path_selector_type(const char *name)
 30 {
 31         struct ps_internal *psi;
 32 
 33         list_for_each_entry(psi, &_path_selectors, list) {
 34                 if (!strcmp(name, psi->pst.name))
 35                         return psi;
 36         }
 37 
 38         return NULL;
 39 }
 40 
 41 static struct ps_internal *get_path_selector(const char *name)
 42 {
 43         struct ps_internal *psi;
 44 
 45         down_read(&_ps_lock);
 46         psi = __find_path_selector_type(name);
 47         if (psi) {
 48                 if ((psi->use == 0) && !try_module_get(psi->pst.module))
 49                         psi = NULL;
 50                 else
 51                         psi->use++;
 52         }
 53         up_read(&_ps_lock);
 54 
 55         return psi;
 56 }
 57 
 58 struct path_selector_type *dm_get_path_selector(const char *name)
 59 {
 60         struct ps_internal *psi;
 61 
 62         if (!name)
 63                 return NULL;
 64 
 65         psi = get_path_selector(name);
 66         if (!psi) {
 67                 request_module("dm-%s", name);
 68                 psi = get_path_selector(name);
 69         }
 70 
 71         return psi ? &psi->pst : NULL;
 72 }
 73 
 74 void dm_put_path_selector(struct path_selector_type *pst)
 75 {
 76         struct ps_internal *psi;
 77 
 78         if (!pst)
 79                 return;
 80 
 81         down_read(&_ps_lock);
 82         psi = __find_path_selector_type(pst->name);
 83         if (!psi)
 84                 goto out;
 85 
 86         if (--psi->use == 0)
 87                 module_put(psi->pst.module);
 88 
 89         BUG_ON(psi->use < 0);
 90 
 91 out:
 92         up_read(&_ps_lock);
 93 }
 94 
 95 static struct ps_internal *_alloc_path_selector(struct path_selector_type *pst)
 96 {
 97         struct ps_internal *psi = kmalloc(sizeof(*psi), GFP_KERNEL);
 98 
 99         if (psi) {
100                 memset(psi, 0, sizeof(*psi));
101                 psi->pst = *pst;
102         }
103 
104         return psi;
105 }
106 
107 int dm_register_path_selector(struct path_selector_type *pst)
108 {
109         int r = 0;
110         struct ps_internal *psi = _alloc_path_selector(pst);
111 
112         if (!psi)
113                 return -ENOMEM;
114 
115         down_write(&_ps_lock);
116 
117         if (__find_path_selector_type(pst->name)) {
118                 kfree(psi);
119                 r = -EEXIST;
120         } else
121                 list_add(&psi->list, &_path_selectors);
122 
123         up_write(&_ps_lock);
124 
125         return r;
126 }
127 
128 int dm_unregister_path_selector(struct path_selector_type *pst)
129 {
130         struct ps_internal *psi;
131 
132         down_write(&_ps_lock);
133 
134         psi = __find_path_selector_type(pst->name);
135         if (!psi) {
136                 up_write(&_ps_lock);
137                 return -EINVAL;
138         }
139 
140         if (psi->use) {
141                 up_write(&_ps_lock);
142                 return -ETXTBSY;
143         }
144 
145         list_del(&psi->list);
146 
147         up_write(&_ps_lock);
148 
149         kfree(psi);
150 
151         return 0;
152 }
153 
154 EXPORT_SYMBOL_GPL(dm_register_path_selector);
155 EXPORT_SYMBOL_GPL(dm_unregister_path_selector);
156 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.