diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bitmap.h | 2 | ||||
-rw-r--r-- | drivers/md/dm-region-hash.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-table.c | 114 | ||||
-rw-r--r-- | drivers/md/faulty.c | 2 | ||||
-rw-r--r-- | drivers/md/md.c | 2 | ||||
-rw-r--r-- | drivers/md/md.h | 2 | ||||
-rw-r--r-- | drivers/md/raid10.c | 6 | ||||
-rw-r--r-- | drivers/md/raid10.h | 4 |
8 files changed, 90 insertions, 44 deletions
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h index 931a7a7c3796..d0aeaf46d932 100644 --- a/drivers/md/bitmap.h +++ b/drivers/md/bitmap.h | |||
@@ -45,7 +45,7 @@ | |||
45 | * | 45 | * |
46 | * The counter counts pending write requests, plus the on-disk bit. | 46 | * The counter counts pending write requests, plus the on-disk bit. |
47 | * When the counter is '1' and the resync bits are clear, the on-disk | 47 | * When the counter is '1' and the resync bits are clear, the on-disk |
48 | * bit can be cleared aswell, thus setting the counter to 0. | 48 | * bit can be cleared as well, thus setting the counter to 0. |
49 | * When we set a bit, or in the counter (to start a write), if the fields is | 49 | * When we set a bit, or in the counter (to start a write), if the fields is |
50 | * 0, we first set the disk bit and set the counter to 1. | 50 | * 0, we first set the disk bit and set the counter to 1. |
51 | * | 51 | * |
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index dad011aed0c9..7771ed212182 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c | |||
@@ -419,7 +419,7 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio) | |||
419 | /* | 419 | /* |
420 | * Possible cases: | 420 | * Possible cases: |
421 | * 1) DM_RH_DIRTY | 421 | * 1) DM_RH_DIRTY |
422 | * 2) DM_RH_NOSYNC: was dirty, other preceeding writes failed | 422 | * 2) DM_RH_NOSYNC: was dirty, other preceding writes failed |
423 | * 3) DM_RH_RECOVERING: flushing pending writes | 423 | * 3) DM_RH_RECOVERING: flushing pending writes |
424 | * Either case, the region should have not been connected to list. | 424 | * Either case, the region should have not been connected to list. |
425 | */ | 425 | */ |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 416d4e258df6..cb8380c9767f 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -927,20 +927,80 @@ static int dm_table_build_index(struct dm_table *t) | |||
927 | } | 927 | } |
928 | 928 | ||
929 | /* | 929 | /* |
930 | * Get a disk whose integrity profile reflects the table's profile. | ||
931 | * If %match_all is true, all devices' profiles must match. | ||
932 | * If %match_all is false, all devices must at least have an | ||
933 | * allocated integrity profile; but uninitialized is ok. | ||
934 | * Returns NULL if integrity support was inconsistent or unavailable. | ||
935 | */ | ||
936 | static struct gendisk * dm_table_get_integrity_disk(struct dm_table *t, | ||
937 | bool match_all) | ||
938 | { | ||
939 | struct list_head *devices = dm_table_get_devices(t); | ||
940 | struct dm_dev_internal *dd = NULL; | ||
941 | struct gendisk *prev_disk = NULL, *template_disk = NULL; | ||
942 | |||
943 | list_for_each_entry(dd, devices, list) { | ||
944 | template_disk = dd->dm_dev.bdev->bd_disk; | ||
945 | if (!blk_get_integrity(template_disk)) | ||
946 | goto no_integrity; | ||
947 | if (!match_all && !blk_integrity_is_initialized(template_disk)) | ||
948 | continue; /* skip uninitialized profiles */ | ||
949 | else if (prev_disk && | ||
950 | blk_integrity_compare(prev_disk, template_disk) < 0) | ||
951 | goto no_integrity; | ||
952 | prev_disk = template_disk; | ||
953 | } | ||
954 | |||
955 | return template_disk; | ||
956 | |||
957 | no_integrity: | ||
958 | if (prev_disk) | ||
959 | DMWARN("%s: integrity not set: %s and %s profile mismatch", | ||
960 | dm_device_name(t->md), | ||
961 | prev_disk->disk_name, | ||
962 | template_disk->disk_name); | ||
963 | return NULL; | ||
964 | } | ||
965 | |||
966 | /* | ||
930 | * Register the mapped device for blk_integrity support if | 967 | * Register the mapped device for blk_integrity support if |
931 | * the underlying devices support it. | 968 | * the underlying devices have an integrity profile. But all devices |
969 | * may not have matching profiles (checking all devices isn't reliable | ||
970 | * during table load because this table may use other DM device(s) which | ||
971 | * must be resumed before they will have an initialized integity profile). | ||
972 | * Stacked DM devices force a 2 stage integrity profile validation: | ||
973 | * 1 - during load, validate all initialized integrity profiles match | ||
974 | * 2 - during resume, validate all integrity profiles match | ||
932 | */ | 975 | */ |
933 | static int dm_table_prealloc_integrity(struct dm_table *t, struct mapped_device *md) | 976 | static int dm_table_prealloc_integrity(struct dm_table *t, struct mapped_device *md) |
934 | { | 977 | { |
935 | struct list_head *devices = dm_table_get_devices(t); | 978 | struct gendisk *template_disk = NULL; |
936 | struct dm_dev_internal *dd; | ||
937 | 979 | ||
938 | list_for_each_entry(dd, devices, list) | 980 | template_disk = dm_table_get_integrity_disk(t, false); |
939 | if (bdev_get_integrity(dd->dm_dev.bdev)) { | 981 | if (!template_disk) |
940 | t->integrity_supported = 1; | 982 | return 0; |
941 | return blk_integrity_register(dm_disk(md), NULL); | ||
942 | } | ||
943 | 983 | ||
984 | if (!blk_integrity_is_initialized(dm_disk(md))) { | ||
985 | t->integrity_supported = 1; | ||
986 | return blk_integrity_register(dm_disk(md), NULL); | ||
987 | } | ||
988 | |||
989 | /* | ||
990 | * If DM device already has an initalized integrity | ||
991 | * profile the new profile should not conflict. | ||
992 | */ | ||
993 | if (blk_integrity_is_initialized(template_disk) && | ||
994 | blk_integrity_compare(dm_disk(md), template_disk) < 0) { | ||
995 | DMWARN("%s: conflict with existing integrity profile: " | ||
996 | "%s profile mismatch", | ||
997 | dm_device_name(t->md), | ||
998 | template_disk->disk_name); | ||
999 | return 1; | ||
1000 | } | ||
1001 | |||
1002 | /* Preserve existing initialized integrity profile */ | ||
1003 | t->integrity_supported = 1; | ||
944 | return 0; | 1004 | return 0; |
945 | } | 1005 | } |
946 | 1006 | ||
@@ -1094,41 +1154,27 @@ combine_limits: | |||
1094 | 1154 | ||
1095 | /* | 1155 | /* |
1096 | * Set the integrity profile for this device if all devices used have | 1156 | * Set the integrity profile for this device if all devices used have |
1097 | * matching profiles. | 1157 | * matching profiles. We're quite deep in the resume path but still |
1158 | * don't know if all devices (particularly DM devices this device | ||
1159 | * may be stacked on) have matching profiles. Even if the profiles | ||
1160 | * don't match we have no way to fail (to resume) at this point. | ||
1098 | */ | 1161 | */ |
1099 | static void dm_table_set_integrity(struct dm_table *t) | 1162 | static void dm_table_set_integrity(struct dm_table *t) |
1100 | { | 1163 | { |
1101 | struct list_head *devices = dm_table_get_devices(t); | 1164 | struct gendisk *template_disk = NULL; |
1102 | struct dm_dev_internal *prev = NULL, *dd = NULL; | ||
1103 | 1165 | ||
1104 | if (!blk_get_integrity(dm_disk(t->md))) | 1166 | if (!blk_get_integrity(dm_disk(t->md))) |
1105 | return; | 1167 | return; |
1106 | 1168 | ||
1107 | list_for_each_entry(dd, devices, list) { | 1169 | template_disk = dm_table_get_integrity_disk(t, true); |
1108 | if (prev && | 1170 | if (!template_disk && |
1109 | blk_integrity_compare(prev->dm_dev.bdev->bd_disk, | 1171 | blk_integrity_is_initialized(dm_disk(t->md))) { |
1110 | dd->dm_dev.bdev->bd_disk) < 0) { | 1172 | DMWARN("%s: device no longer has a valid integrity profile", |
1111 | DMWARN("%s: integrity not set: %s and %s mismatch", | 1173 | dm_device_name(t->md)); |
1112 | dm_device_name(t->md), | 1174 | return; |
1113 | prev->dm_dev.bdev->bd_disk->disk_name, | ||
1114 | dd->dm_dev.bdev->bd_disk->disk_name); | ||
1115 | goto no_integrity; | ||
1116 | } | ||
1117 | prev = dd; | ||
1118 | } | 1175 | } |
1119 | |||
1120 | if (!prev || !bdev_get_integrity(prev->dm_dev.bdev)) | ||
1121 | goto no_integrity; | ||
1122 | |||
1123 | blk_integrity_register(dm_disk(t->md), | 1176 | blk_integrity_register(dm_disk(t->md), |
1124 | bdev_get_integrity(prev->dm_dev.bdev)); | 1177 | blk_get_integrity(template_disk)); |
1125 | |||
1126 | return; | ||
1127 | |||
1128 | no_integrity: | ||
1129 | blk_integrity_register(dm_disk(t->md), NULL); | ||
1130 | |||
1131 | return; | ||
1132 | } | 1178 | } |
1133 | 1179 | ||
1134 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | 1180 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, |
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index 339fdc670751..23078dabb6df 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c | |||
@@ -30,7 +30,7 @@ | |||
30 | * | 30 | * |
31 | * Different modes can be active at a time, but only | 31 | * Different modes can be active at a time, but only |
32 | * one can be set at array creation. Others can be added later. | 32 | * one can be set at array creation. Others can be added later. |
33 | * A mode can be one-shot or recurrent with the recurrance being | 33 | * A mode can be one-shot or recurrent with the recurrence being |
34 | * once in every N requests. | 34 | * once in every N requests. |
35 | * The bottom 5 bits of the "layout" indicate the mode. The | 35 | * The bottom 5 bits of the "layout" indicate the mode. The |
36 | * remainder indicate a period, or 0 for one-shot. | 36 | * remainder indicate a period, or 0 for one-shot. |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 8b66e04c2ea6..b12b3776c0c0 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -6266,7 +6266,7 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev) | |||
6266 | * rt is a sector_t, so could be 32bit or 64bit. | 6266 | * rt is a sector_t, so could be 32bit or 64bit. |
6267 | * So we divide before multiply in case it is 32bit and close | 6267 | * So we divide before multiply in case it is 32bit and close |
6268 | * to the limit. | 6268 | * to the limit. |
6269 | * We scale the divisor (db) by 32 to avoid loosing precision | 6269 | * We scale the divisor (db) by 32 to avoid losing precision |
6270 | * near the end of resync when the number of remaining sectors | 6270 | * near the end of resync when the number of remaining sectors |
6271 | * is close to 'db'. | 6271 | * is close to 'db'. |
6272 | * We then divide rt by 32 after multiplying by db to compensate. | 6272 | * We then divide rt by 32 after multiplying by db to compensate. |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 12215d437fcc..52b407369e13 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -94,7 +94,7 @@ struct mdk_rdev_s | |||
94 | #define In_sync 2 /* device is in_sync with rest of array */ | 94 | #define In_sync 2 /* device is in_sync with rest of array */ |
95 | #define WriteMostly 4 /* Avoid reading if at all possible */ | 95 | #define WriteMostly 4 /* Avoid reading if at all possible */ |
96 | #define AutoDetected 7 /* added by auto-detect */ | 96 | #define AutoDetected 7 /* added by auto-detect */ |
97 | #define Blocked 8 /* An error occured on an externally | 97 | #define Blocked 8 /* An error occurred on an externally |
98 | * managed array, don't allow writes | 98 | * managed array, don't allow writes |
99 | * until it is cleared */ | 99 | * until it is cleared */ |
100 | wait_queue_head_t blocked_wait; | 100 | wait_queue_head_t blocked_wait; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index f7b62370b374..2da83d566592 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * RAID-10 support for md. | 6 | * RAID-10 support for md. |
7 | * | 7 | * |
8 | * Base on code in raid1.c. See raid1.c for futher copyright information. | 8 | * Base on code in raid1.c. See raid1.c for further copyright information. |
9 | * | 9 | * |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
@@ -340,14 +340,14 @@ static void raid10_end_write_request(struct bio *bio, int error) | |||
340 | 340 | ||
341 | /* | 341 | /* |
342 | * RAID10 layout manager | 342 | * RAID10 layout manager |
343 | * Aswell as the chunksize and raid_disks count, there are two | 343 | * As well as the chunksize and raid_disks count, there are two |
344 | * parameters: near_copies and far_copies. | 344 | * parameters: near_copies and far_copies. |
345 | * near_copies * far_copies must be <= raid_disks. | 345 | * near_copies * far_copies must be <= raid_disks. |
346 | * Normally one of these will be 1. | 346 | * Normally one of these will be 1. |
347 | * If both are 1, we get raid0. | 347 | * If both are 1, we get raid0. |
348 | * If near_copies == raid_disks, we get raid1. | 348 | * If near_copies == raid_disks, we get raid1. |
349 | * | 349 | * |
350 | * Chunks are layed out in raid0 style with near_copies copies of the | 350 | * Chunks are laid out in raid0 style with near_copies copies of the |
351 | * first chunk, followed by near_copies copies of the next chunk and | 351 | * first chunk, followed by near_copies copies of the next chunk and |
352 | * so on. | 352 | * so on. |
353 | * If far_copies > 1, then after 1/far_copies of the array has been assigned | 353 | * If far_copies > 1, then after 1/far_copies of the array has been assigned |
diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 2316ac2e8e21..944b1104d3b4 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h | |||
@@ -17,8 +17,8 @@ struct r10_private_data_s { | |||
17 | spinlock_t device_lock; | 17 | spinlock_t device_lock; |
18 | 18 | ||
19 | /* geometry */ | 19 | /* geometry */ |
20 | int near_copies; /* number of copies layed out raid0 style */ | 20 | int near_copies; /* number of copies laid out raid0 style */ |
21 | int far_copies; /* number of copies layed out | 21 | int far_copies; /* number of copies laid out |
22 | * at large strides across drives | 22 | * at large strides across drives |
23 | */ | 23 | */ |
24 | int far_offset; /* far_copies are offset by 1 stripe | 24 | int far_offset; /* far_copies are offset by 1 stripe |