Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'dm-4.0-fix-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fix from Mike Snitzer:
"Fix DM core device cleanup regression -- due to a latent race that was
exposed by the bdi changes that were introduced during the 4.0 merge"

* tag 'dm-4.0-fix-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm: fix add_disk() NULL pointer due to race with free_dev()

+16 -10
+16 -10
drivers/md/dm.c
··· 433 433 434 434 dm_get(md); 435 435 atomic_inc(&md->open_count); 436 - 437 436 out: 438 437 spin_unlock(&_minor_lock); 439 438 ··· 441 442 442 443 static void dm_blk_close(struct gendisk *disk, fmode_t mode) 443 444 { 444 - struct mapped_device *md = disk->private_data; 445 + struct mapped_device *md; 445 446 446 447 spin_lock(&_minor_lock); 448 + 449 + md = disk->private_data; 450 + if (WARN_ON(!md)) 451 + goto out; 447 452 448 453 if (atomic_dec_and_test(&md->open_count) && 449 454 (test_bit(DMF_DEFERRED_REMOVE, &md->flags))) 450 455 queue_work(deferred_remove_workqueue, &deferred_remove_work); 451 456 452 457 dm_put(md); 453 - 458 + out: 454 459 spin_unlock(&_minor_lock); 455 460 } 456 461 ··· 2244 2241 int minor = MINOR(disk_devt(md->disk)); 2245 2242 2246 2243 unlock_fs(md); 2247 - bdput(md->bdev); 2248 2244 destroy_workqueue(md->wq); 2249 2245 2250 2246 if (md->kworker_task) ··· 2254 2252 mempool_destroy(md->rq_pool); 2255 2253 if (md->bs) 2256 2254 bioset_free(md->bs); 2257 - blk_integrity_unregister(md->disk); 2258 - del_gendisk(md->disk); 2255 + 2259 2256 cleanup_srcu_struct(&md->io_barrier); 2260 2257 free_table_devices(&md->table_devices); 2261 - free_minor(minor); 2258 + dm_stats_cleanup(&md->stats); 2262 2259 2263 2260 spin_lock(&_minor_lock); 2264 2261 md->disk->private_data = NULL; 2265 2262 spin_unlock(&_minor_lock); 2266 - 2263 + if (blk_get_integrity(md->disk)) 2264 + blk_integrity_unregister(md->disk); 2265 + del_gendisk(md->disk); 2267 2266 put_disk(md->disk); 2268 2267 blk_cleanup_queue(md->queue); 2269 - dm_stats_cleanup(&md->stats); 2268 + bdput(md->bdev); 2269 + free_minor(minor); 2270 + 2270 2271 module_put(THIS_MODULE); 2271 2272 kfree(md); 2272 2273 } ··· 2647 2642 2648 2643 might_sleep(); 2649 2644 2650 - spin_lock(&_minor_lock); 2651 2645 map = dm_get_live_table(md, &srcu_idx); 2646 + 2647 + spin_lock(&_minor_lock); 2652 2648 idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md)))); 2653 2649 set_bit(DMF_FREEING, &md->flags); 2654 2650 spin_unlock(&_minor_lock);