diff options
Diffstat (limited to 'drivers/md/dm-raid1.c')
-rw-r--r-- | drivers/md/dm-raid1.c | 75 |
1 files changed, 23 insertions, 52 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index fd61f98ee1f6..fa519185ebba 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -61,7 +61,6 @@ struct mirror_set { | |||
61 | struct dm_region_hash *rh; | 61 | struct dm_region_hash *rh; |
62 | struct dm_kcopyd_client *kcopyd_client; | 62 | struct dm_kcopyd_client *kcopyd_client; |
63 | struct dm_io_client *io_client; | 63 | struct dm_io_client *io_client; |
64 | mempool_t *read_record_pool; | ||
65 | 64 | ||
66 | /* recovery */ | 65 | /* recovery */ |
67 | region_t nr_regions; | 66 | region_t nr_regions; |
@@ -139,14 +138,13 @@ static void dispatch_bios(void *context, struct bio_list *bio_list) | |||
139 | queue_bio(ms, bio, WRITE); | 138 | queue_bio(ms, bio, WRITE); |
140 | } | 139 | } |
141 | 140 | ||
142 | #define MIN_READ_RECORDS 20 | 141 | struct dm_raid1_bio_record { |
143 | struct dm_raid1_read_record { | ||
144 | struct mirror *m; | 142 | struct mirror *m; |
143 | /* if details->bi_bdev == NULL, details were not saved */ | ||
145 | struct dm_bio_details details; | 144 | struct dm_bio_details details; |
145 | region_t write_region; | ||
146 | }; | 146 | }; |
147 | 147 | ||
148 | static struct kmem_cache *_dm_raid1_read_record_cache; | ||
149 | |||
150 | /* | 148 | /* |
151 | * Every mirror should look like this one. | 149 | * Every mirror should look like this one. |
152 | */ | 150 | */ |
@@ -876,19 +874,9 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, | |||
876 | atomic_set(&ms->suspend, 0); | 874 | atomic_set(&ms->suspend, 0); |
877 | atomic_set(&ms->default_mirror, DEFAULT_MIRROR); | 875 | atomic_set(&ms->default_mirror, DEFAULT_MIRROR); |
878 | 876 | ||
879 | ms->read_record_pool = mempool_create_slab_pool(MIN_READ_RECORDS, | ||
880 | _dm_raid1_read_record_cache); | ||
881 | |||
882 | if (!ms->read_record_pool) { | ||
883 | ti->error = "Error creating mirror read_record_pool"; | ||
884 | kfree(ms); | ||
885 | return NULL; | ||
886 | } | ||
887 | |||
888 | ms->io_client = dm_io_client_create(); | 877 | ms->io_client = dm_io_client_create(); |
889 | if (IS_ERR(ms->io_client)) { | 878 | if (IS_ERR(ms->io_client)) { |
890 | ti->error = "Error creating dm_io client"; | 879 | ti->error = "Error creating dm_io client"; |
891 | mempool_destroy(ms->read_record_pool); | ||
892 | kfree(ms); | 880 | kfree(ms); |
893 | return NULL; | 881 | return NULL; |
894 | } | 882 | } |
@@ -900,7 +888,6 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, | |||
900 | if (IS_ERR(ms->rh)) { | 888 | if (IS_ERR(ms->rh)) { |
901 | ti->error = "Error creating dirty region hash"; | 889 | ti->error = "Error creating dirty region hash"; |
902 | dm_io_client_destroy(ms->io_client); | 890 | dm_io_client_destroy(ms->io_client); |
903 | mempool_destroy(ms->read_record_pool); | ||
904 | kfree(ms); | 891 | kfree(ms); |
905 | return NULL; | 892 | return NULL; |
906 | } | 893 | } |
@@ -916,7 +903,6 @@ static void free_context(struct mirror_set *ms, struct dm_target *ti, | |||
916 | 903 | ||
917 | dm_io_client_destroy(ms->io_client); | 904 | dm_io_client_destroy(ms->io_client); |
918 | dm_region_hash_destroy(ms->rh); | 905 | dm_region_hash_destroy(ms->rh); |
919 | mempool_destroy(ms->read_record_pool); | ||
920 | kfree(ms); | 906 | kfree(ms); |
921 | } | 907 | } |
922 | 908 | ||
@@ -1088,6 +1074,7 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
1088 | 1074 | ||
1089 | ti->num_flush_requests = 1; | 1075 | ti->num_flush_requests = 1; |
1090 | ti->num_discard_requests = 1; | 1076 | ti->num_discard_requests = 1; |
1077 | ti->per_bio_data_size = sizeof(struct dm_raid1_bio_record); | ||
1091 | ti->discard_zeroes_data_unsupported = true; | 1078 | ti->discard_zeroes_data_unsupported = true; |
1092 | 1079 | ||
1093 | ms->kmirrord_wq = alloc_workqueue("kmirrord", | 1080 | ms->kmirrord_wq = alloc_workqueue("kmirrord", |
@@ -1155,18 +1142,20 @@ static void mirror_dtr(struct dm_target *ti) | |||
1155 | /* | 1142 | /* |
1156 | * Mirror mapping function | 1143 | * Mirror mapping function |
1157 | */ | 1144 | */ |
1158 | static int mirror_map(struct dm_target *ti, struct bio *bio, | 1145 | static int mirror_map(struct dm_target *ti, struct bio *bio) |
1159 | union map_info *map_context) | ||
1160 | { | 1146 | { |
1161 | int r, rw = bio_rw(bio); | 1147 | int r, rw = bio_rw(bio); |
1162 | struct mirror *m; | 1148 | struct mirror *m; |
1163 | struct mirror_set *ms = ti->private; | 1149 | struct mirror_set *ms = ti->private; |
1164 | struct dm_raid1_read_record *read_record = NULL; | ||
1165 | struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); | 1150 | struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); |
1151 | struct dm_raid1_bio_record *bio_record = | ||
1152 | dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record)); | ||
1153 | |||
1154 | bio_record->details.bi_bdev = NULL; | ||
1166 | 1155 | ||
1167 | if (rw == WRITE) { | 1156 | if (rw == WRITE) { |
1168 | /* Save region for mirror_end_io() handler */ | 1157 | /* Save region for mirror_end_io() handler */ |
1169 | map_context->ll = dm_rh_bio_to_region(ms->rh, bio); | 1158 | bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio); |
1170 | queue_bio(ms, bio, rw); | 1159 | queue_bio(ms, bio, rw); |
1171 | return DM_MAPIO_SUBMITTED; | 1160 | return DM_MAPIO_SUBMITTED; |
1172 | } | 1161 | } |
@@ -1194,33 +1183,29 @@ static int mirror_map(struct dm_target *ti, struct bio *bio, | |||
1194 | if (unlikely(!m)) | 1183 | if (unlikely(!m)) |
1195 | return -EIO; | 1184 | return -EIO; |
1196 | 1185 | ||
1197 | read_record = mempool_alloc(ms->read_record_pool, GFP_NOIO); | 1186 | dm_bio_record(&bio_record->details, bio); |
1198 | if (likely(read_record)) { | 1187 | bio_record->m = m; |
1199 | dm_bio_record(&read_record->details, bio); | ||
1200 | map_context->ptr = read_record; | ||
1201 | read_record->m = m; | ||
1202 | } | ||
1203 | 1188 | ||
1204 | map_bio(m, bio); | 1189 | map_bio(m, bio); |
1205 | 1190 | ||
1206 | return DM_MAPIO_REMAPPED; | 1191 | return DM_MAPIO_REMAPPED; |
1207 | } | 1192 | } |
1208 | 1193 | ||
1209 | static int mirror_end_io(struct dm_target *ti, struct bio *bio, | 1194 | static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) |
1210 | int error, union map_info *map_context) | ||
1211 | { | 1195 | { |
1212 | int rw = bio_rw(bio); | 1196 | int rw = bio_rw(bio); |
1213 | struct mirror_set *ms = (struct mirror_set *) ti->private; | 1197 | struct mirror_set *ms = (struct mirror_set *) ti->private; |
1214 | struct mirror *m = NULL; | 1198 | struct mirror *m = NULL; |
1215 | struct dm_bio_details *bd = NULL; | 1199 | struct dm_bio_details *bd = NULL; |
1216 | struct dm_raid1_read_record *read_record = map_context->ptr; | 1200 | struct dm_raid1_bio_record *bio_record = |
1201 | dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record)); | ||
1217 | 1202 | ||
1218 | /* | 1203 | /* |
1219 | * We need to dec pending if this was a write. | 1204 | * We need to dec pending if this was a write. |
1220 | */ | 1205 | */ |
1221 | if (rw == WRITE) { | 1206 | if (rw == WRITE) { |
1222 | if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) | 1207 | if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) |
1223 | dm_rh_dec(ms->rh, map_context->ll); | 1208 | dm_rh_dec(ms->rh, bio_record->write_region); |
1224 | return error; | 1209 | return error; |
1225 | } | 1210 | } |
1226 | 1211 | ||
@@ -1231,7 +1216,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, | |||
1231 | goto out; | 1216 | goto out; |
1232 | 1217 | ||
1233 | if (unlikely(error)) { | 1218 | if (unlikely(error)) { |
1234 | if (!read_record) { | 1219 | if (!bio_record->details.bi_bdev) { |
1235 | /* | 1220 | /* |
1236 | * There wasn't enough memory to record necessary | 1221 | * There wasn't enough memory to record necessary |
1237 | * information for a retry or there was no other | 1222 | * information for a retry or there was no other |
@@ -1241,7 +1226,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, | |||
1241 | return -EIO; | 1226 | return -EIO; |
1242 | } | 1227 | } |
1243 | 1228 | ||
1244 | m = read_record->m; | 1229 | m = bio_record->m; |
1245 | 1230 | ||
1246 | DMERR("Mirror read failed from %s. Trying alternative device.", | 1231 | DMERR("Mirror read failed from %s. Trying alternative device.", |
1247 | m->dev->name); | 1232 | m->dev->name); |
@@ -1253,22 +1238,18 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, | |||
1253 | * mirror. | 1238 | * mirror. |
1254 | */ | 1239 | */ |
1255 | if (default_ok(m) || mirror_available(ms, bio)) { | 1240 | if (default_ok(m) || mirror_available(ms, bio)) { |
1256 | bd = &read_record->details; | 1241 | bd = &bio_record->details; |
1257 | 1242 | ||
1258 | dm_bio_restore(bd, bio); | 1243 | dm_bio_restore(bd, bio); |
1259 | mempool_free(read_record, ms->read_record_pool); | 1244 | bio_record->details.bi_bdev = NULL; |
1260 | map_context->ptr = NULL; | ||
1261 | queue_bio(ms, bio, rw); | 1245 | queue_bio(ms, bio, rw); |
1262 | return 1; | 1246 | return DM_ENDIO_INCOMPLETE; |
1263 | } | 1247 | } |
1264 | DMERR("All replicated volumes dead, failing I/O"); | 1248 | DMERR("All replicated volumes dead, failing I/O"); |
1265 | } | 1249 | } |
1266 | 1250 | ||
1267 | out: | 1251 | out: |
1268 | if (read_record) { | 1252 | bio_record->details.bi_bdev = NULL; |
1269 | mempool_free(read_record, ms->read_record_pool); | ||
1270 | map_context->ptr = NULL; | ||
1271 | } | ||
1272 | 1253 | ||
1273 | return error; | 1254 | return error; |
1274 | } | 1255 | } |
@@ -1422,7 +1403,7 @@ static int mirror_iterate_devices(struct dm_target *ti, | |||
1422 | 1403 | ||
1423 | static struct target_type mirror_target = { | 1404 | static struct target_type mirror_target = { |
1424 | .name = "mirror", | 1405 | .name = "mirror", |
1425 | .version = {1, 12, 1}, | 1406 | .version = {1, 13, 1}, |
1426 | .module = THIS_MODULE, | 1407 | .module = THIS_MODULE, |
1427 | .ctr = mirror_ctr, | 1408 | .ctr = mirror_ctr, |
1428 | .dtr = mirror_dtr, | 1409 | .dtr = mirror_dtr, |
@@ -1439,13 +1420,6 @@ static int __init dm_mirror_init(void) | |||
1439 | { | 1420 | { |
1440 | int r; | 1421 | int r; |
1441 | 1422 | ||
1442 | _dm_raid1_read_record_cache = KMEM_CACHE(dm_raid1_read_record, 0); | ||
1443 | if (!_dm_raid1_read_record_cache) { | ||
1444 | DMERR("Can't allocate dm_raid1_read_record cache"); | ||
1445 | r = -ENOMEM; | ||
1446 | goto bad_cache; | ||
1447 | } | ||
1448 | |||
1449 | r = dm_register_target(&mirror_target); | 1423 | r = dm_register_target(&mirror_target); |
1450 | if (r < 0) { | 1424 | if (r < 0) { |
1451 | DMERR("Failed to register mirror target"); | 1425 | DMERR("Failed to register mirror target"); |
@@ -1455,15 +1429,12 @@ static int __init dm_mirror_init(void) | |||
1455 | return 0; | 1429 | return 0; |
1456 | 1430 | ||
1457 | bad_target: | 1431 | bad_target: |
1458 | kmem_cache_destroy(_dm_raid1_read_record_cache); | ||
1459 | bad_cache: | ||
1460 | return r; | 1432 | return r; |
1461 | } | 1433 | } |
1462 | 1434 | ||
1463 | static void __exit dm_mirror_exit(void) | 1435 | static void __exit dm_mirror_exit(void) |
1464 | { | 1436 | { |
1465 | dm_unregister_target(&mirror_target); | 1437 | dm_unregister_target(&mirror_target); |
1466 | kmem_cache_destroy(_dm_raid1_read_record_cache); | ||
1467 | } | 1438 | } |
1468 | 1439 | ||
1469 | /* Module hooks */ | 1440 | /* Module hooks */ |