dm-table.c (4cc96131afce3eaae7c13dff41c6ba771cf10e96) | dm-table.c (e83068a5faafb8ca65d3b58bd1e1e3959ce1ddce) |
---|---|
1/* 2 * Copyright (C) 2001 Sistina Software (UK) Limited. 3 * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. 4 * 5 * This file is released under the GPL. 6 */ 7 8#include "dm-core.h" --- 29 unchanged lines hidden (view full) --- 38 sector_t *index[MAX_DEPTH]; 39 40 unsigned int num_targets; 41 unsigned int num_allocated; 42 sector_t *highs; 43 struct dm_target *targets; 44 45 struct target_type *immutable_target_type; | 1/* 2 * Copyright (C) 2001 Sistina Software (UK) Limited. 3 * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. 4 * 5 * This file is released under the GPL. 6 */ 7 8#include "dm-core.h" --- 29 unchanged lines hidden (view full) --- 38 sector_t *index[MAX_DEPTH]; 39 40 unsigned int num_targets; 41 unsigned int num_allocated; 42 sector_t *highs; 43 struct dm_target *targets; 44 45 struct target_type *immutable_target_type; |
46 unsigned integrity_supported:1; 47 unsigned singleton:1; | |
48 | 46 |
47 bool integrity_supported:1; 48 bool singleton:1; 49 bool all_blk_mq:1; 50 |
|
49 /* 50 * Indicates the rw permissions for the new logical 51 * device. This should be a combination of FMODE_READ 52 * and FMODE_WRITE. 53 */ 54 fmode_t mode; 55 56 /* a list of devices used by this table */ --- 144 unchanged lines hidden (view full) --- 201 return -ENOMEM; 202 } 203 204 if (alloc_targets(t, num_targets)) { 205 kfree(t); 206 return -ENOMEM; 207 } 208 | 51 /* 52 * Indicates the rw permissions for the new logical 53 * device. This should be a combination of FMODE_READ 54 * and FMODE_WRITE. 55 */ 56 fmode_t mode; 57 58 /* a list of devices used by this table */ --- 144 unchanged lines hidden (view full) --- 203 return -ENOMEM; 204 } 205 206 if (alloc_targets(t, num_targets)) { 207 kfree(t); 208 return -ENOMEM; 209 } 210 |
211 t->type = DM_TYPE_NONE; |
|
209 t->mode = mode; 210 t->md = md; 211 *result = t; 212 return 0; 213} 214 215static void free_devices(struct list_head *devices, struct mapped_device *md) 216{ --- 481 unchanged lines hidden (view full) --- 698 } 699 700 if (dm_target_needs_singleton(tgt->type)) { 701 if (t->num_targets) { 702 DMERR("%s: target type %s must appear alone in table", 703 dm_device_name(t->md), type); 704 return -EINVAL; 705 } | 212 t->mode = mode; 213 t->md = md; 214 *result = t; 215 return 0; 216} 217 218static void free_devices(struct list_head *devices, struct mapped_device *md) 219{ --- 481 unchanged lines hidden (view full) --- 701 } 702 703 if (dm_target_needs_singleton(tgt->type)) { 704 if (t->num_targets) { 705 DMERR("%s: target type %s must appear alone in table", 706 dm_device_name(t->md), type); 707 return -EINVAL; 708 } |
706 t->singleton = 1; | 709 t->singleton = true; |
707 } 708 709 if (dm_target_always_writeable(tgt->type) && !(t->mode & FMODE_WRITE)) { 710 DMERR("%s: target type %s may not be included in read-only tables", 711 dm_device_name(t->md), type); 712 return -EINVAL; 713 } 714 --- 110 unchanged lines hidden (view full) --- 825EXPORT_SYMBOL(dm_consume_args); 826 827static bool __table_type_request_based(unsigned table_type) 828{ 829 return (table_type == DM_TYPE_REQUEST_BASED || 830 table_type == DM_TYPE_MQ_REQUEST_BASED); 831} 832 | 710 } 711 712 if (dm_target_always_writeable(tgt->type) && !(t->mode & FMODE_WRITE)) { 713 DMERR("%s: target type %s may not be included in read-only tables", 714 dm_device_name(t->md), type); 715 return -EINVAL; 716 } 717 --- 110 unchanged lines hidden (view full) --- 828EXPORT_SYMBOL(dm_consume_args); 829 830static bool __table_type_request_based(unsigned table_type) 831{ 832 return (table_type == DM_TYPE_REQUEST_BASED || 833 table_type == DM_TYPE_MQ_REQUEST_BASED); 834} 835 |
833static int dm_table_set_type(struct dm_table *t) | 836void dm_table_set_type(struct dm_table *t, unsigned type) |
834{ | 837{ |
838 t->type = type; 839} 840EXPORT_SYMBOL_GPL(dm_table_set_type); 841 842static int dm_table_determine_type(struct dm_table *t) 843{ |
|
835 unsigned i; 836 unsigned bio_based = 0, request_based = 0, hybrid = 0; | 844 unsigned i; 845 unsigned bio_based = 0, request_based = 0, hybrid = 0; |
837 bool use_blk_mq = false; | 846 bool verify_blk_mq = false; |
838 struct dm_target *tgt; 839 struct dm_dev_internal *dd; | 847 struct dm_target *tgt; 848 struct dm_dev_internal *dd; |
840 struct list_head *devices; | 849 struct list_head *devices = dm_table_get_devices(t); |
841 unsigned live_md_type = dm_get_md_type(t->md); 842 | 850 unsigned live_md_type = dm_get_md_type(t->md); 851 |
852 if (t->type != DM_TYPE_NONE) { 853 /* target already set the table's type */ 854 if (t->type == DM_TYPE_BIO_BASED) 855 return 0; 856 goto verify_rq_based; 857 } 858 |
|
843 for (i = 0; i < t->num_targets; i++) { 844 tgt = t->targets + i; 845 if (dm_target_hybrid(tgt)) 846 hybrid = 1; 847 else if (dm_target_request_based(tgt)) 848 request_based = 1; 849 else 850 bio_based = 1; --- 20 unchanged lines hidden (view full) --- 871 if (bio_based) { 872 /* We must use this table as bio-based */ 873 t->type = DM_TYPE_BIO_BASED; 874 return 0; 875 } 876 877 BUG_ON(!request_based); /* No targets in this table */ 878 | 859 for (i = 0; i < t->num_targets; i++) { 860 tgt = t->targets + i; 861 if (dm_target_hybrid(tgt)) 862 hybrid = 1; 863 else if (dm_target_request_based(tgt)) 864 request_based = 1; 865 else 866 bio_based = 1; --- 20 unchanged lines hidden (view full) --- 887 if (bio_based) { 888 /* We must use this table as bio-based */ 889 t->type = DM_TYPE_BIO_BASED; 890 return 0; 891 } 892 893 BUG_ON(!request_based); /* No targets in this table */ 894 |
895 if (list_empty(devices) && __table_type_request_based(live_md_type)) { 896 /* inherit live MD type */ 897 t->type = live_md_type; 898 return 0; 899 } 900 |
|
879 /* | 901 /* |
902 * The only way to establish DM_TYPE_MQ_REQUEST_BASED is by 903 * having a compatible target use dm_table_set_type. 904 */ 905 t->type = DM_TYPE_REQUEST_BASED; 906 907verify_rq_based: 908 /* |
|
880 * Request-based dm supports only tables that have a single target now. 881 * To support multiple targets, request splitting support is needed, 882 * and that needs lots of changes in the block-layer. 883 * (e.g. request completion process for partial completion.) 884 */ 885 if (t->num_targets > 1) { 886 DMWARN("Request-based dm doesn't support multiple targets yet"); 887 return -EINVAL; 888 } 889 890 /* Non-request-stackable devices can't be used for request-based dm */ | 909 * Request-based dm supports only tables that have a single target now. 910 * To support multiple targets, request splitting support is needed, 911 * and that needs lots of changes in the block-layer. 912 * (e.g. request completion process for partial completion.) 913 */ 914 if (t->num_targets > 1) { 915 DMWARN("Request-based dm doesn't support multiple targets yet"); 916 return -EINVAL; 917 } 918 919 /* Non-request-stackable devices can't be used for request-based dm */ |
891 devices = dm_table_get_devices(t); | |
892 list_for_each_entry(dd, devices, list) { 893 struct request_queue *q = bdev_get_queue(dd->dm_dev->bdev); 894 895 if (!blk_queue_stackable(q)) { 896 DMERR("table load rejected: including" 897 " non-request-stackable devices"); 898 return -EINVAL; 899 } 900 901 if (q->mq_ops) | 920 list_for_each_entry(dd, devices, list) { 921 struct request_queue *q = bdev_get_queue(dd->dm_dev->bdev); 922 923 if (!blk_queue_stackable(q)) { 924 DMERR("table load rejected: including" 925 " non-request-stackable devices"); 926 return -EINVAL; 927 } 928 929 if (q->mq_ops) |
902 use_blk_mq = true; | 930 verify_blk_mq = true; |
903 } 904 | 931 } 932 |
905 if (use_blk_mq) { | 933 if (verify_blk_mq) { |
906 /* verify _all_ devices in the table are blk-mq devices */ 907 list_for_each_entry(dd, devices, list) 908 if (!bdev_get_queue(dd->dm_dev->bdev)->mq_ops) { 909 DMERR("table load rejected: not all devices" 910 " are blk-mq request-stackable"); 911 return -EINVAL; 912 } | 934 /* verify _all_ devices in the table are blk-mq devices */ 935 list_for_each_entry(dd, devices, list) 936 if (!bdev_get_queue(dd->dm_dev->bdev)->mq_ops) { 937 DMERR("table load rejected: not all devices" 938 " are blk-mq request-stackable"); 939 return -EINVAL; 940 } |
913 t->type = DM_TYPE_MQ_REQUEST_BASED; | |
914 | 941 |
915 } else if (list_empty(devices) && __table_type_request_based(live_md_type)) { 916 /* inherit live MD type */ 917 t->type = live_md_type; | 942 t->all_blk_mq = true; 943 } |
918 | 944 |
919 } else 920 t->type = DM_TYPE_REQUEST_BASED; 921 | |
922 return 0; 923} 924 925unsigned dm_table_get_type(struct dm_table *t) 926{ 927 return t->type; 928} 929 --- 26 unchanged lines hidden (view full) --- 956 return NULL; 957} 958 959bool dm_table_request_based(struct dm_table *t) 960{ 961 return __table_type_request_based(dm_table_get_type(t)); 962} 963 | 945 return 0; 946} 947 948unsigned dm_table_get_type(struct dm_table *t) 949{ 950 return t->type; 951} 952 --- 26 unchanged lines hidden (view full) --- 979 return NULL; 980} 981 982bool dm_table_request_based(struct dm_table *t) 983{ 984 return __table_type_request_based(dm_table_get_type(t)); 985} 986 |
964bool dm_table_mq_request_based(struct dm_table *t) | 987bool dm_table_all_blk_mq_devices(struct dm_table *t) |
965{ | 988{ |
966 return dm_table_get_type(t) == DM_TYPE_MQ_REQUEST_BASED; | 989 return t->all_blk_mq; |
967} 968 969static int dm_table_alloc_md_mempools(struct dm_table *t, struct mapped_device *md) 970{ 971 unsigned type = dm_table_get_type(t); 972 unsigned per_io_data_size = 0; 973 struct dm_target *tgt; 974 unsigned i; --- 126 unchanged lines hidden (view full) --- 1101 struct mapped_device *md = t->md; 1102 struct gendisk *template_disk = NULL; 1103 1104 template_disk = dm_table_get_integrity_disk(t); 1105 if (!template_disk) 1106 return 0; 1107 1108 if (!integrity_profile_exists(dm_disk(md))) { | 990} 991 992static int dm_table_alloc_md_mempools(struct dm_table *t, struct mapped_device *md) 993{ 994 unsigned type = dm_table_get_type(t); 995 unsigned per_io_data_size = 0; 996 struct dm_target *tgt; 997 unsigned i; --- 126 unchanged lines hidden (view full) --- 1124 struct mapped_device *md = t->md; 1125 struct gendisk *template_disk = NULL; 1126 1127 template_disk = dm_table_get_integrity_disk(t); 1128 if (!template_disk) 1129 return 0; 1130 1131 if (!integrity_profile_exists(dm_disk(md))) { |
1109 t->integrity_supported = 1; | 1132 t->integrity_supported = true; |
1110 /* 1111 * Register integrity profile during table load; we can do 1112 * this because the final profile must match during resume. 1113 */ 1114 blk_integrity_register(dm_disk(md), 1115 blk_get_integrity(template_disk)); 1116 return 0; 1117 } --- 6 unchanged lines hidden (view full) --- 1124 DMWARN("%s: conflict with existing integrity profile: " 1125 "%s profile mismatch", 1126 dm_device_name(t->md), 1127 template_disk->disk_name); 1128 return 1; 1129 } 1130 1131 /* Preserve existing integrity profile */ | 1133 /* 1134 * Register integrity profile during table load; we can do 1135 * this because the final profile must match during resume. 1136 */ 1137 blk_integrity_register(dm_disk(md), 1138 blk_get_integrity(template_disk)); 1139 return 0; 1140 } --- 6 unchanged lines hidden (view full) --- 1147 DMWARN("%s: conflict with existing integrity profile: " 1148 "%s profile mismatch", 1149 dm_device_name(t->md), 1150 template_disk->disk_name); 1151 return 1; 1152 } 1153 1154 /* Preserve existing integrity profile */ |
1132 t->integrity_supported = 1; | 1155 t->integrity_supported = true; |
1133 return 0; 1134} 1135 1136/* 1137 * Prepares the table for use by building the indices, 1138 * setting the type, and allocating mempools. 1139 */ 1140int dm_table_complete(struct dm_table *t) 1141{ 1142 int r; 1143 | 1156 return 0; 1157} 1158 1159/* 1160 * Prepares the table for use by building the indices, 1161 * setting the type, and allocating mempools. 1162 */ 1163int dm_table_complete(struct dm_table *t) 1164{ 1165 int r; 1166 |
1144 r = dm_table_set_type(t); | 1167 r = dm_table_determine_type(t); |
1145 if (r) { | 1168 if (r) { |
1146 DMERR("unable to set table type"); | 1169 DMERR("unable to determine table type"); |
1147 return r; 1148 } 1149 1150 r = dm_table_build_index(t); 1151 if (r) { 1152 DMERR("unable to build btrees"); 1153 return r; 1154 } --- 574 unchanged lines hidden --- | 1170 return r; 1171 } 1172 1173 r = dm_table_build_index(t); 1174 if (r) { 1175 DMERR("unable to build btrees"); 1176 return r; 1177 } --- 574 unchanged lines hidden --- |