diff options
Diffstat (limited to 'mm/backing-dev.c')
-rw-r--r-- | mm/backing-dev.c | 24 |
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 = { | |||
22 | EXPORT_SYMBOL_GPL(default_backing_dev_info); | 22 | EXPORT_SYMBOL_GPL(default_backing_dev_info); |
23 | 23 | ||
24 | static struct class *bdi_class; | 24 | static struct class *bdi_class; |
25 | DEFINE_MUTEX(bdi_lock); | ||
26 | LIST_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 | } |
226 | EXPORT_SYMBOL(bdi_register_dev); | 232 | EXPORT_SYMBOL(bdi_register_dev); |
227 | 233 | ||
234 | static 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 | |||
228 | void bdi_unregister(struct backing_dev_info *bdi) | 241 | void 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) | |||
259 | err: | 277 | err: |
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++) |