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.c107
1 files changed, 25 insertions, 82 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 0ae0df55000b..7690ec77c722 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -14,19 +14,10 @@
14 14
15static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0); 15static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
16 16
17struct backing_dev_info default_backing_dev_info = {
18 .name = "default",
19 .ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE,
20 .state = 0,
21 .capabilities = BDI_CAP_MAP_COPY,
22};
23EXPORT_SYMBOL_GPL(default_backing_dev_info);
24
25struct backing_dev_info noop_backing_dev_info = { 17struct backing_dev_info noop_backing_dev_info = {
26 .name = "noop", 18 .name = "noop",
27 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, 19 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
28}; 20};
29EXPORT_SYMBOL_GPL(noop_backing_dev_info);
30 21
31static struct class *bdi_class; 22static struct class *bdi_class;
32 23
@@ -40,17 +31,6 @@ LIST_HEAD(bdi_list);
40/* bdi_wq serves all asynchronous writeback tasks */ 31/* bdi_wq serves all asynchronous writeback tasks */
41struct workqueue_struct *bdi_wq; 32struct workqueue_struct *bdi_wq;
42 33
43static void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2)
44{
45 if (wb1 < wb2) {
46 spin_lock(&wb1->list_lock);
47 spin_lock_nested(&wb2->list_lock, 1);
48 } else {
49 spin_lock(&wb2->list_lock);
50 spin_lock_nested(&wb1->list_lock, 1);
51 }
52}
53
54#ifdef CONFIG_DEBUG_FS 34#ifdef CONFIG_DEBUG_FS
55#include <linux/debugfs.h> 35#include <linux/debugfs.h>
56#include <linux/seq_file.h> 36#include <linux/seq_file.h>
@@ -264,9 +244,6 @@ static int __init default_bdi_init(void)
264 if (!bdi_wq) 244 if (!bdi_wq)
265 return -ENOMEM; 245 return -ENOMEM;
266 246
267 err = bdi_init(&default_backing_dev_info);
268 if (!err)
269 bdi_register(&default_backing_dev_info, NULL, "default");
270 err = bdi_init(&noop_backing_dev_info); 247 err = bdi_init(&noop_backing_dev_info);
271 248
272 return err; 249 return err;
@@ -355,19 +332,19 @@ EXPORT_SYMBOL(bdi_register_dev);
355 */ 332 */
356static void bdi_wb_shutdown(struct backing_dev_info *bdi) 333static void bdi_wb_shutdown(struct backing_dev_info *bdi)
357{ 334{
358 if (!bdi_cap_writeback_dirty(bdi)) 335 /* Make sure nobody queues further work */
336 spin_lock_bh(&bdi->wb_lock);
337 if (!test_and_clear_bit(BDI_registered, &bdi->state)) {
338 spin_unlock_bh(&bdi->wb_lock);
359 return; 339 return;
340 }
341 spin_unlock_bh(&bdi->wb_lock);
360 342
361 /* 343 /*
362 * Make sure nobody finds us on the bdi_list anymore 344 * Make sure nobody finds us on the bdi_list anymore
363 */ 345 */
364 bdi_remove_from_list(bdi); 346 bdi_remove_from_list(bdi);
365 347
366 /* Make sure nobody queues further work */
367 spin_lock_bh(&bdi->wb_lock);
368 clear_bit(BDI_registered, &bdi->state);
369 spin_unlock_bh(&bdi->wb_lock);
370
371 /* 348 /*
372 * Drain work list and shutdown the delayed_work. At this point, 349 * Drain work list and shutdown the delayed_work. At this point,
373 * @bdi->bdi_list is empty telling bdi_Writeback_workfn() that @bdi 350 * @bdi->bdi_list is empty telling bdi_Writeback_workfn() that @bdi
@@ -375,37 +352,22 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
375 */ 352 */
376 mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0); 353 mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
377 flush_delayed_work(&bdi->wb.dwork); 354 flush_delayed_work(&bdi->wb.dwork);
378 WARN_ON(!list_empty(&bdi->work_list));
379 WARN_ON(delayed_work_pending(&bdi->wb.dwork));
380} 355}
381 356
382/* 357/*
383 * This bdi is going away now, make sure that no super_blocks point to it 358 * Called when the device behind @bdi has been removed or ejected.
359 *
360 * We can't really do much here except for reducing the dirty ratio at
361 * the moment. In the future we should be able to set a flag so that
362 * the filesystem can handle errors at mark_inode_dirty time instead
363 * of only at writeback time.
384 */ 364 */
385static void bdi_prune_sb(struct backing_dev_info *bdi)
386{
387 struct super_block *sb;
388
389 spin_lock(&sb_lock);
390 list_for_each_entry(sb, &super_blocks, s_list) {
391 if (sb->s_bdi == bdi)
392 sb->s_bdi = &default_backing_dev_info;
393 }
394 spin_unlock(&sb_lock);
395}
396
397void bdi_unregister(struct backing_dev_info *bdi) 365void bdi_unregister(struct backing_dev_info *bdi)
398{ 366{
399 if (bdi->dev) { 367 if (WARN_ON_ONCE(!bdi->dev))
400 bdi_set_min_ratio(bdi, 0); 368 return;
401 trace_writeback_bdi_unregister(bdi);
402 bdi_prune_sb(bdi);
403 369
404 bdi_wb_shutdown(bdi); 370 bdi_set_min_ratio(bdi, 0);
405 bdi_debug_unregister(bdi);
406 device_unregister(bdi->dev);
407 bdi->dev = NULL;
408 }
409} 371}
410EXPORT_SYMBOL(bdi_unregister); 372EXPORT_SYMBOL(bdi_unregister);
411 373
@@ -474,37 +436,19 @@ void bdi_destroy(struct backing_dev_info *bdi)
474{ 436{
475 int i; 437 int i;
476 438
477 /* 439 bdi_wb_shutdown(bdi);
478 * Splice our entries to the default_backing_dev_info. This
479 * condition shouldn't happen. @wb must be empty at this point and
480 * dirty inodes on it might cause other issues. This workaround is
481 * added by ce5f8e779519 ("writeback: splice dirty inode entries to
482 * default bdi on bdi_destroy()") without root-causing the issue.
483 *
484 * http://lkml.kernel.org/g/1253038617-30204-11-git-send-email-jens.axboe@oracle.com
485 * http://thread.gmane.org/gmane.linux.file-systems/35341/focus=35350
486 *
487 * We should probably add WARN_ON() to find out whether it still
488 * happens and track it down if so.
489 */
490 if (bdi_has_dirty_io(bdi)) {
491 struct bdi_writeback *dst = &default_backing_dev_info.wb;
492
493 bdi_lock_two(&bdi->wb, dst);
494 list_splice(&bdi->wb.b_dirty, &dst->b_dirty);
495 list_splice(&bdi->wb.b_io, &dst->b_io);
496 list_splice(&bdi->wb.b_more_io, &dst->b_more_io);
497 spin_unlock(&bdi->wb.list_lock);
498 spin_unlock(&dst->list_lock);
499 }
500
501 bdi_unregister(bdi);
502 440
441 WARN_ON(!list_empty(&bdi->work_list));
503 WARN_ON(delayed_work_pending(&bdi->wb.dwork)); 442 WARN_ON(delayed_work_pending(&bdi->wb.dwork));
504 443
444 if (bdi->dev) {
445 bdi_debug_unregister(bdi);
446 device_unregister(bdi->dev);
447 bdi->dev = NULL;
448 }
449
505 for (i = 0; i < NR_BDI_STAT_ITEMS; i++) 450 for (i = 0; i < NR_BDI_STAT_ITEMS; i++)
506 percpu_counter_destroy(&bdi->bdi_stat[i]); 451 percpu_counter_destroy(&bdi->bdi_stat[i]);
507
508 fprop_local_destroy_percpu(&bdi->completions); 452 fprop_local_destroy_percpu(&bdi->completions);
509} 453}
510EXPORT_SYMBOL(bdi_destroy); 454EXPORT_SYMBOL(bdi_destroy);
@@ -513,13 +457,12 @@ EXPORT_SYMBOL(bdi_destroy);
513 * For use from filesystems to quickly init and register a bdi associated 457 * For use from filesystems to quickly init and register a bdi associated
514 * with dirty writeback 458 * with dirty writeback
515 */ 459 */
516int bdi_setup_and_register(struct backing_dev_info *bdi, char *name, 460int bdi_setup_and_register(struct backing_dev_info *bdi, char *name)
517 unsigned int cap)
518{ 461{
519 int err; 462 int err;
520 463
521 bdi->name = name; 464 bdi->name = name;
522 bdi->capabilities = cap; 465 bdi->capabilities = 0;
523 err = bdi_init(bdi); 466 err = bdi_init(bdi);
524 if (err) 467 if (err)
525 return err; 468 return err;