예제 #1
0
파일: backing-dev.c 프로젝트: 020gzh/linux
static void cgwb_bdi_destroy(struct backing_dev_info *bdi)
{
	struct radix_tree_iter iter;
	struct rb_node *rbn;
	void **slot;

	WARN_ON(test_bit(WB_registered, &bdi->wb.state));

	spin_lock_irq(&cgwb_lock);

	radix_tree_for_each_slot(slot, &bdi->cgwb_tree, &iter, 0)
		cgwb_kill(*slot);

	while ((rbn = rb_first(&bdi->cgwb_congested_tree))) {
		struct bdi_writeback_congested *congested =
			rb_entry(rbn, struct bdi_writeback_congested, rb_node);

		rb_erase(rbn, &bdi->cgwb_congested_tree);
		congested->bdi = NULL;	/* mark @congested unlinked */
	}

	spin_unlock_irq(&cgwb_lock);

	/*
	 * All cgwb's and their congested states must be shutdown and
	 * released before returning.  Drain the usage counter to wait for
	 * all cgwb's and cgwb_congested's ever created on @bdi.
	 */
	atomic_dec(&bdi->usage_cnt);
	wait_event(cgwb_release_wait, !atomic_read(&bdi->usage_cnt));
}
예제 #2
0
static void cgwb_bdi_unregister(struct backing_dev_info *bdi)
{
	struct radix_tree_iter iter;
	void **slot;
	struct bdi_writeback *wb;

	WARN_ON(test_bit(WB_registered, &bdi->wb.state));

	spin_lock_irq(&cgwb_lock);
	radix_tree_for_each_slot(slot, &bdi->cgwb_tree, &iter, 0)
		cgwb_kill(*slot);

	while (!list_empty(&bdi->wb_list)) {
		wb = list_first_entry(&bdi->wb_list, struct bdi_writeback,
				      bdi_node);
		spin_unlock_irq(&cgwb_lock);
		wb_shutdown(wb);
		spin_lock_irq(&cgwb_lock);
	}
	spin_unlock_irq(&cgwb_lock);
}