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-3.19-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mike Snitzer:
"Two stable fixes for dm-cache and one 3.19 DM core fix:

- fix potential for dm-cache metadata corruption via stale metadata
buffers being used when switching an inactive cache table to
active; this could occur due to each table having it's own bufio
client rather than sharing the client between tables.

- fix dm-cache target to properly account for discard IO while
suspending otherwise IO quiescing could complete prematurely.

- fix DM core's handling of multiple internal suspends by maintaining
an 'internal_suspend_count' and only resuming the device when this
count drops to zero"

* tag 'dm-3.19-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm: fix handling of multiple internal suspends
dm cache: fix problematic dual use of a single migration count variable
dm cache: share cache-metadata object across inactive and active DM tables

+152 -47
+95 -6
drivers/md/dm-cache-metadata.c
··· 94 94 } __packed; 95 95 96 96 struct dm_cache_metadata { 97 + atomic_t ref_count; 98 + struct list_head list; 99 + 97 100 struct block_device *bdev; 98 101 struct dm_block_manager *bm; 99 102 struct dm_space_map *metadata_sm; ··· 672 669 673 670 /*----------------------------------------------------------------*/ 674 671 675 - struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, 676 - sector_t data_block_size, 677 - bool may_format_device, 678 - size_t policy_hint_size) 672 + static struct dm_cache_metadata *metadata_open(struct block_device *bdev, 673 + sector_t data_block_size, 674 + bool may_format_device, 675 + size_t policy_hint_size) 679 676 { 680 677 int r; 681 678 struct dm_cache_metadata *cmd; ··· 686 683 return NULL; 687 684 } 688 685 686 + atomic_set(&cmd->ref_count, 1); 689 687 init_rwsem(&cmd->root_lock); 690 688 cmd->bdev = bdev; 691 689 cmd->data_block_size = data_block_size; ··· 709 705 return cmd; 710 706 } 711 707 708 + /* 709 + * We keep a little list of ref counted metadata objects to prevent two 710 + * different target instances creating separate bufio instances. This is 711 + * an issue if a table is reloaded before the suspend. 712 + */ 713 + static DEFINE_MUTEX(table_lock); 714 + static LIST_HEAD(table); 715 + 716 + static struct dm_cache_metadata *lookup(struct block_device *bdev) 717 + { 718 + struct dm_cache_metadata *cmd; 719 + 720 + list_for_each_entry(cmd, &table, list) 721 + if (cmd->bdev == bdev) { 722 + atomic_inc(&cmd->ref_count); 723 + return cmd; 724 + } 725 + 726 + return NULL; 727 + } 728 + 729 + static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev, 730 + sector_t data_block_size, 731 + bool may_format_device, 732 + size_t policy_hint_size) 733 + { 734 + struct dm_cache_metadata *cmd, *cmd2; 735 + 736 + mutex_lock(&table_lock); 737 + cmd = lookup(bdev); 738 + mutex_unlock(&table_lock); 739 + 740 + if (cmd) 741 + return cmd; 742 + 743 + cmd = metadata_open(bdev, data_block_size, may_format_device, policy_hint_size); 744 + if (cmd) { 745 + mutex_lock(&table_lock); 746 + cmd2 = lookup(bdev); 747 + if (cmd2) { 748 + mutex_unlock(&table_lock); 749 + __destroy_persistent_data_objects(cmd); 750 + kfree(cmd); 751 + return cmd2; 752 + } 753 + list_add(&cmd->list, &table); 754 + mutex_unlock(&table_lock); 755 + } 756 + 757 + return cmd; 758 + } 759 + 760 + static bool same_params(struct dm_cache_metadata *cmd, sector_t data_block_size) 761 + { 762 + if (cmd->data_block_size != data_block_size) { 763 + DMERR("data_block_size (%llu) different from that in metadata (%llu)\n", 764 + (unsigned long long) data_block_size, 765 + (unsigned long long) cmd->data_block_size); 766 + return false; 767 + } 768 + 769 + return true; 770 + } 771 + 772 + struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, 773 + sector_t data_block_size, 774 + bool may_format_device, 775 + size_t policy_hint_size) 776 + { 777 + struct dm_cache_metadata *cmd = lookup_or_open(bdev, data_block_size, 778 + may_format_device, policy_hint_size); 779 + if (cmd && !same_params(cmd, data_block_size)) { 780 + dm_cache_metadata_close(cmd); 781 + return NULL; 782 + } 783 + 784 + return cmd; 785 + } 786 + 712 787 void dm_cache_metadata_close(struct dm_cache_metadata *cmd) 713 788 { 714 - __destroy_persistent_data_objects(cmd); 715 - kfree(cmd); 789 + if (atomic_dec_and_test(&cmd->ref_count)) { 790 + mutex_lock(&table_lock); 791 + list_del(&cmd->list); 792 + mutex_unlock(&table_lock); 793 + 794 + __destroy_persistent_data_objects(cmd); 795 + kfree(cmd); 796 + } 716 797 } 717 798 718 799 /*
+50 -39
drivers/md/dm-cache-target.c
··· 221 221 struct list_head need_commit_migrations; 222 222 sector_t migration_threshold; 223 223 wait_queue_head_t migration_wait; 224 - atomic_t nr_migrations; 224 + atomic_t nr_allocated_migrations; 225 + 226 + /* 227 + * The number of in flight migrations that are performing 228 + * background io. eg, promotion, writeback. 229 + */ 230 + atomic_t nr_io_migrations; 225 231 226 232 wait_queue_head_t quiescing_wait; 227 233 atomic_t quiescing; ··· 264 258 struct dm_deferred_set *all_io_ds; 265 259 266 260 mempool_t *migration_pool; 267 - struct dm_cache_migration *next_migration; 268 261 269 262 struct dm_cache_policy *policy; 270 263 unsigned policy_nr_args; ··· 355 350 dm_bio_prison_free_cell(cache->prison, cell); 356 351 } 357 352 353 + static struct dm_cache_migration *alloc_migration(struct cache *cache) 354 + { 355 + struct dm_cache_migration *mg; 356 + 357 + mg = mempool_alloc(cache->migration_pool, GFP_NOWAIT); 358 + if (mg) { 359 + mg->cache = cache; 360 + atomic_inc(&mg->cache->nr_allocated_migrations); 361 + } 362 + 363 + return mg; 364 + } 365 + 366 + static void free_migration(struct dm_cache_migration *mg) 367 + { 368 + if (atomic_dec_and_test(&mg->cache->nr_allocated_migrations)) 369 + wake_up(&mg->cache->migration_wait); 370 + 371 + mempool_free(mg, mg->cache->migration_pool); 372 + } 373 + 358 374 static int prealloc_data_structs(struct cache *cache, struct prealloc *p) 359 375 { 360 376 if (!p->mg) { 361 - p->mg = mempool_alloc(cache->migration_pool, GFP_NOWAIT); 377 + p->mg = alloc_migration(cache); 362 378 if (!p->mg) 363 379 return -ENOMEM; 364 380 } ··· 408 382 free_prison_cell(cache, p->cell1); 409 383 410 384 if (p->mg) 411 - mempool_free(p->mg, cache->migration_pool); 385 + free_migration(p->mg); 412 386 } 413 387 414 388 static struct dm_cache_migration *prealloc_get_migration(struct prealloc *p) ··· 880 854 * Migration covers moving data from the origin device to the cache, or 881 855 * vice versa. 882 856 *--------------------------------------------------------------*/ 883 - static void free_migration(struct dm_cache_migration *mg) 857 + static void inc_io_migrations(struct cache *cache) 884 858 { 885 - mempool_free(mg, mg->cache->migration_pool); 859 + atomic_inc(&cache->nr_io_migrations); 886 860 } 887 861 888 - static void inc_nr_migrations(struct cache *cache) 862 + static void dec_io_migrations(struct cache *cache) 889 863 { 890 - atomic_inc(&cache->nr_migrations); 891 - } 892 - 893 - static void dec_nr_migrations(struct cache *cache) 894 - { 895 - atomic_dec(&cache->nr_migrations); 896 - 897 - /* 898 - * Wake the worker in case we're suspending the target. 899 - */ 900 - wake_up(&cache->migration_wait); 864 + atomic_dec(&cache->nr_io_migrations); 901 865 } 902 866 903 867 static void __cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell, ··· 910 894 wake_worker(cache); 911 895 } 912 896 913 - static void cleanup_migration(struct dm_cache_migration *mg) 897 + static void free_io_migration(struct dm_cache_migration *mg) 914 898 { 915 - struct cache *cache = mg->cache; 899 + dec_io_migrations(mg->cache); 916 900 free_migration(mg); 917 - dec_nr_migrations(cache); 918 901 } 919 902 920 903 static void migration_failure(struct dm_cache_migration *mg) ··· 938 923 cell_defer(cache, mg->new_ocell, true); 939 924 } 940 925 941 - cleanup_migration(mg); 926 + free_io_migration(mg); 942 927 } 943 928 944 929 static void migration_success_pre_commit(struct dm_cache_migration *mg) ··· 949 934 if (mg->writeback) { 950 935 clear_dirty(cache, mg->old_oblock, mg->cblock); 951 936 cell_defer(cache, mg->old_ocell, false); 952 - cleanup_migration(mg); 937 + free_io_migration(mg); 953 938 return; 954 939 955 940 } else if (mg->demote) { ··· 959 944 mg->old_oblock); 960 945 if (mg->promote) 961 946 cell_defer(cache, mg->new_ocell, true); 962 - cleanup_migration(mg); 947 + free_io_migration(mg); 963 948 return; 964 949 } 965 950 } else { 966 951 if (dm_cache_insert_mapping(cache->cmd, mg->cblock, mg->new_oblock)) { 967 952 DMWARN_LIMIT("promotion failed; couldn't update on disk metadata"); 968 953 policy_remove_mapping(cache->policy, mg->new_oblock); 969 - cleanup_migration(mg); 954 + free_io_migration(mg); 970 955 return; 971 956 } 972 957 } ··· 999 984 } else { 1000 985 if (mg->invalidate) 1001 986 policy_remove_mapping(cache->policy, mg->old_oblock); 1002 - cleanup_migration(mg); 987 + free_io_migration(mg); 1003 988 } 1004 989 1005 990 } else { ··· 1014 999 bio_endio(mg->new_ocell->holder, 0); 1015 1000 cell_defer(cache, mg->new_ocell, false); 1016 1001 } 1017 - cleanup_migration(mg); 1002 + free_io_migration(mg); 1018 1003 } 1019 1004 } 1020 1005 ··· 1266 1251 mg->new_ocell = cell; 1267 1252 mg->start_jiffies = jiffies; 1268 1253 1269 - inc_nr_migrations(cache); 1254 + inc_io_migrations(cache); 1270 1255 quiesce_migration(mg); 1271 1256 } 1272 1257 ··· 1290 1275 mg->new_ocell = NULL; 1291 1276 mg->start_jiffies = jiffies; 1292 1277 1293 - inc_nr_migrations(cache); 1278 + inc_io_migrations(cache); 1294 1279 quiesce_migration(mg); 1295 1280 } 1296 1281 ··· 1317 1302 mg->new_ocell = new_ocell; 1318 1303 mg->start_jiffies = jiffies; 1319 1304 1320 - inc_nr_migrations(cache); 1305 + inc_io_migrations(cache); 1321 1306 quiesce_migration(mg); 1322 1307 } 1323 1308 ··· 1345 1330 mg->new_ocell = NULL; 1346 1331 mg->start_jiffies = jiffies; 1347 1332 1348 - inc_nr_migrations(cache); 1333 + inc_io_migrations(cache); 1349 1334 quiesce_migration(mg); 1350 1335 } 1351 1336 ··· 1427 1412 1428 1413 static bool spare_migration_bandwidth(struct cache *cache) 1429 1414 { 1430 - sector_t current_volume = (atomic_read(&cache->nr_migrations) + 1) * 1415 + sector_t current_volume = (atomic_read(&cache->nr_io_migrations) + 1) * 1431 1416 cache->sectors_per_block; 1432 1417 return current_volume < cache->migration_threshold; 1433 1418 } ··· 1779 1764 1780 1765 static void wait_for_migrations(struct cache *cache) 1781 1766 { 1782 - wait_event(cache->migration_wait, !atomic_read(&cache->nr_migrations)); 1767 + wait_event(cache->migration_wait, !atomic_read(&cache->nr_allocated_migrations)); 1783 1768 } 1784 1769 1785 1770 static void stop_worker(struct cache *cache) ··· 1890 1875 static void destroy(struct cache *cache) 1891 1876 { 1892 1877 unsigned i; 1893 - 1894 - if (cache->next_migration) 1895 - mempool_free(cache->next_migration, cache->migration_pool); 1896 1878 1897 1879 if (cache->migration_pool) 1898 1880 mempool_destroy(cache->migration_pool); ··· 2436 2424 INIT_LIST_HEAD(&cache->quiesced_migrations); 2437 2425 INIT_LIST_HEAD(&cache->completed_migrations); 2438 2426 INIT_LIST_HEAD(&cache->need_commit_migrations); 2439 - atomic_set(&cache->nr_migrations, 0); 2427 + atomic_set(&cache->nr_allocated_migrations, 0); 2428 + atomic_set(&cache->nr_io_migrations, 0); 2440 2429 init_waitqueue_head(&cache->migration_wait); 2441 2430 2442 2431 init_waitqueue_head(&cache->quiescing_wait); ··· 2499 2486 *error = "Error creating cache's migration mempool"; 2500 2487 goto bad; 2501 2488 } 2502 - 2503 - cache->next_migration = NULL; 2504 2489 2505 2490 cache->need_tick_bio = true; 2506 2491 cache->sized = false;
+7 -2
drivers/md/dm.c
··· 206 206 /* zero-length flush that will be cloned and submitted to targets */ 207 207 struct bio flush_bio; 208 208 209 + /* the number of internal suspends */ 210 + unsigned internal_suspend_count; 211 + 209 212 struct dm_stats stats; 210 213 }; 211 214 ··· 2931 2928 { 2932 2929 struct dm_table *map = NULL; 2933 2930 2934 - if (dm_suspended_internally_md(md)) 2931 + if (md->internal_suspend_count++) 2935 2932 return; /* nested internal suspend */ 2936 2933 2937 2934 if (dm_suspended_md(md)) { ··· 2956 2953 2957 2954 static void __dm_internal_resume(struct mapped_device *md) 2958 2955 { 2959 - if (!dm_suspended_internally_md(md)) 2956 + BUG_ON(!md->internal_suspend_count); 2957 + 2958 + if (--md->internal_suspend_count) 2960 2959 return; /* resume from nested internal suspend */ 2961 2960 2962 2961 if (dm_suspended_md(md))