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 ---