aboutsummaryrefslogtreecommitdiffstats
path: root/mm/backing-dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/backing-dev.c')
-rw-r--r--mm/backing-dev.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index c86edd244294..6f163e0f0509 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -22,6 +22,8 @@ struct backing_dev_info default_backing_dev_info = {
22EXPORT_SYMBOL_GPL(default_backing_dev_info); 22EXPORT_SYMBOL_GPL(default_backing_dev_info);
23 23
24static struct class *bdi_class; 24static struct class *bdi_class;
25DEFINE_MUTEX(bdi_lock);
26LIST_HEAD(bdi_list);
25 27
26#ifdef CONFIG_DEBUG_FS 28#ifdef CONFIG_DEBUG_FS
27#include <linux/debugfs.h> 29#include <linux/debugfs.h>
@@ -211,6 +213,10 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
211 goto exit; 213 goto exit;
212 } 214 }
213 215
216 mutex_lock(&bdi_lock);
217 list_add_tail(&bdi->bdi_list, &bdi_list);
218 mutex_unlock(&bdi_lock);
219
214 bdi->dev = dev; 220 bdi->dev = dev;
215 bdi_debug_register(bdi, dev_name(dev)); 221 bdi_debug_register(bdi, dev_name(dev));
216 222
@@ -225,9 +231,17 @@ int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev)
225} 231}
226EXPORT_SYMBOL(bdi_register_dev); 232EXPORT_SYMBOL(bdi_register_dev);
227 233
234static void bdi_remove_from_list(struct backing_dev_info *bdi)
235{
236 mutex_lock(&bdi_lock);
237 list_del(&bdi->bdi_list);
238 mutex_unlock(&bdi_lock);
239}
240
228void bdi_unregister(struct backing_dev_info *bdi) 241void bdi_unregister(struct backing_dev_info *bdi)
229{ 242{
230 if (bdi->dev) { 243 if (bdi->dev) {
244 bdi_remove_from_list(bdi);
231 bdi_debug_unregister(bdi); 245 bdi_debug_unregister(bdi);
232 device_unregister(bdi->dev); 246 device_unregister(bdi->dev);
233 bdi->dev = NULL; 247 bdi->dev = NULL;
@@ -245,6 +259,10 @@ int bdi_init(struct backing_dev_info *bdi)
245 bdi->min_ratio = 0; 259 bdi->min_ratio = 0;
246 bdi->max_ratio = 100; 260 bdi->max_ratio = 100;
247 bdi->max_prop_frac = PROP_FRAC_BASE; 261 bdi->max_prop_frac = PROP_FRAC_BASE;
262 INIT_LIST_HEAD(&bdi->bdi_list);
263 INIT_LIST_HEAD(&bdi->b_io);
264 INIT_LIST_HEAD(&bdi->b_dirty);
265 INIT_LIST_HEAD(&bdi->b_more_io);
248 266
249 for (i = 0; i < NR_BDI_STAT_ITEMS; i++) { 267 for (i = 0; i < NR_BDI_STAT_ITEMS; i++) {
250 err = percpu_counter_init(&bdi->bdi_stat[i], 0); 268 err = percpu_counter_init(&bdi->bdi_stat[i], 0);
@@ -259,6 +277,8 @@ int bdi_init(struct backing_dev_info *bdi)
259err: 277err:
260 while (i--) 278 while (i--)
261 percpu_counter_destroy(&bdi->bdi_stat[i]); 279 percpu_counter_destroy(&bdi->bdi_stat[i]);
280
281 bdi_remove_from_list(bdi);
262 } 282 }
263 283
264 return err; 284 return err;
@@ -269,6 +289,10 @@ void bdi_destroy(struct backing_dev_info *bdi)
269{ 289{
270 int i; 290 int i;
271 291
292 WARN_ON(!list_empty(&bdi->b_dirty));
293 WARN_ON(!list_empty(&bdi->b_io));
294 WARN_ON(!list_empty(&bdi->b_more_io));
295
272 bdi_unregister(bdi); 296 bdi_unregister(bdi);
273 297
274 for (i = 0; i < NR_BDI_STAT_ITEMS; i++) 298 for (i = 0; i < NR_BDI_STAT_ITEMS; i++)