Hi Jens, Today's linux-next merge of the block tree got a conflict in mm/backing-dev.c between commit aad653a0bc09 ("block: discard bdi_unregister() in favour of bdi_destroy()") from Linus' tree and various commits from the block tree. I fixed it up (I think - see below) and can carry the fix as necessary (no action is required - though it may be worth while merging what you had Linus merge and fixing up the conflicts yourself). -- Cheers, Stephen Rothwell sfr@xxxxxxxxxxxxxxxx diff --cc mm/backing-dev.c index 000e7b3b9896,887d72a85b5e..000000000000 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@@ -387,49 -744,91 +744,75 @@@ int bdi_init(struct backing_dev_info *b bdi->min_ratio = 0; bdi->max_ratio = 100; bdi->max_prop_frac = FPROP_FRAC_BASE; - spin_lock_init(&bdi->wb_lock); INIT_LIST_HEAD(&bdi->bdi_list); - INIT_LIST_HEAD(&bdi->work_list); + init_waitqueue_head(&bdi->wb_waitq); - bdi_wb_init(&bdi->wb, bdi); + err = wb_init(&bdi->wb, bdi, GFP_KERNEL); + if (err) + return err; - for (i = 0; i < NR_BDI_STAT_ITEMS; i++) { - err = percpu_counter_init(&bdi->bdi_stat[i], 0, GFP_KERNEL); - if (err) - goto err; - } + bdi->wb_congested.state = 0; + bdi->wb.congested = &bdi->wb_congested; - bdi->dirty_exceeded = 0; + cgwb_bdi_init(bdi); + return 0; + } + EXPORT_SYMBOL(bdi_init); - bdi->bw_time_stamp = jiffies; - bdi->written_stamp = 0; + int bdi_register(struct backing_dev_info *bdi, struct device *parent, + const char *fmt, ...) + { + va_list args; + struct device *dev; - bdi->balanced_dirty_ratelimit = INIT_BW; - bdi->dirty_ratelimit = INIT_BW; - bdi->write_bandwidth = INIT_BW; - bdi->avg_write_bandwidth = INIT_BW; + if (bdi->dev) /* The driver needs to use separate queues per device */ + return 0; - err = fprop_local_init_percpu(&bdi->completions, GFP_KERNEL); + va_start(args, fmt); + dev = device_create_vargs(bdi_class, parent, MKDEV(0, 0), bdi, fmt, args); + va_end(args); + if (IS_ERR(dev)) + return PTR_ERR(dev); - if (err) { - err: - while (i--) - percpu_counter_destroy(&bdi->bdi_stat[i]); - } + bdi->dev = dev; - return err; + bdi_debug_register(bdi, dev_name(dev)); + set_bit(WB_registered, &bdi->wb.state); + + spin_lock_bh(&bdi_lock); + list_add_tail_rcu(&bdi->bdi_list, &bdi_list); + spin_unlock_bh(&bdi_lock); + + trace_writeback_bdi_register(bdi); + return 0; } - EXPORT_SYMBOL(bdi_init); + EXPORT_SYMBOL(bdi_register); - void bdi_destroy(struct backing_dev_info *bdi) + int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev) { - int i; + return bdi_register(bdi, NULL, "%u:%u", MAJOR(dev), MINOR(dev)); + } + EXPORT_SYMBOL(bdi_register_dev); - bdi_wb_shutdown(bdi); - bdi_set_min_ratio(bdi, 0); + /* + * Remove bdi from bdi_list, and ensure that it is no longer visible + */ + static void bdi_remove_from_list(struct backing_dev_info *bdi) + { + spin_lock_bh(&bdi_lock); + list_del_rcu(&bdi->bdi_list); + spin_unlock_bh(&bdi_lock); - WARN_ON(!list_empty(&bdi->work_list)); - WARN_ON(delayed_work_pending(&bdi->wb.dwork)); + synchronize_rcu_expedited(); + } + -/* - * Called when the device behind @bdi has been removed or ejected. - * - * We can't really do much here except for reducing the dirty ratio at - * the moment. In the future we should be able to set a flag so that - * the filesystem can handle errors at mark_inode_dirty time instead - * of only at writeback time. - */ -void bdi_unregister(struct backing_dev_info *bdi) -{ - if (WARN_ON_ONCE(!bdi->dev)) - return; - - bdi_set_min_ratio(bdi, 0); -} -EXPORT_SYMBOL(bdi_unregister); - + void bdi_destroy(struct backing_dev_info *bdi) + { + /* make sure nobody finds us on the bdi_list anymore */ + bdi_remove_from_list(bdi); + wb_shutdown(&bdi->wb); ++ bdi_set_min_ratio(bdi, 0); + cgwb_bdi_destroy(bdi); if (bdi->dev) { bdi_debug_unregister(bdi);
Attachment:
pgp15hB6K1YnR.pgp
Description: OpenPGP digital signature