diff options
author | Denis Semakin <d.semakin@omprussia.ru> | 2018-03-13 05:23:45 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2018-04-03 15:04:21 -0400 |
commit | 00716545c894fc464e00612809d9cb836b180c99 (patch) | |
tree | 7492fc26be641c58a49b4c81ab707f60a597f629 | |
parent | 0519c71e8d461ac3ef9a555bb7339243c9128d37 (diff) |
dm: add support for secure erase forwarding
Set QUEUE_FLAG_SECERASE in DM device's queue_flags if a DM table's
data devices support secure erase.
Also, add support for secure erase to both the linear and striped
targets.
Signed-off-by: Denis Semakin <d.semakin@omprussia.ru>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r-- | drivers/md/dm-linear.c | 1 | ||||
-rw-r--r-- | drivers/md/dm-stripe.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-table.c | 31 | ||||
-rw-r--r-- | drivers/md/dm.c | 12 | ||||
-rw-r--r-- | include/linux/device-mapper.h | 6 |
5 files changed, 52 insertions, 0 deletions
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index d5f8eff7c11d..ff751b00aacd 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c | |||
@@ -59,6 +59,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
59 | 59 | ||
60 | ti->num_flush_bios = 1; | 60 | ti->num_flush_bios = 1; |
61 | ti->num_discard_bios = 1; | 61 | ti->num_discard_bios = 1; |
62 | ti->num_secure_erase_bios = 1; | ||
62 | ti->num_write_same_bios = 1; | 63 | ti->num_write_same_bios = 1; |
63 | ti->num_write_zeroes_bios = 1; | 64 | ti->num_write_zeroes_bios = 1; |
64 | ti->private = lc; | 65 | ti->private = lc; |
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index cd209e8902a6..bb907cb3e60d 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c | |||
@@ -169,6 +169,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
169 | 169 | ||
170 | ti->num_flush_bios = stripes; | 170 | ti->num_flush_bios = stripes; |
171 | ti->num_discard_bios = stripes; | 171 | ti->num_discard_bios = stripes; |
172 | ti->num_secure_erase_bios = stripes; | ||
172 | ti->num_write_same_bios = stripes; | 173 | ti->num_write_same_bios = stripes; |
173 | ti->num_write_zeroes_bios = stripes; | 174 | ti->num_write_zeroes_bios = stripes; |
174 | 175 | ||
@@ -295,6 +296,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio) | |||
295 | return DM_MAPIO_REMAPPED; | 296 | return DM_MAPIO_REMAPPED; |
296 | } | 297 | } |
297 | if (unlikely(bio_op(bio) == REQ_OP_DISCARD) || | 298 | if (unlikely(bio_op(bio) == REQ_OP_DISCARD) || |
299 | unlikely(bio_op(bio) == REQ_OP_SECURE_ERASE) || | ||
298 | unlikely(bio_op(bio) == REQ_OP_WRITE_ZEROES) || | 300 | unlikely(bio_op(bio) == REQ_OP_WRITE_ZEROES) || |
299 | unlikely(bio_op(bio) == REQ_OP_WRITE_SAME)) { | 301 | unlikely(bio_op(bio) == REQ_OP_WRITE_SAME)) { |
300 | target_bio_nr = dm_bio_get_target_bio_nr(bio); | 302 | target_bio_nr = dm_bio_get_target_bio_nr(bio); |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 7eb3e2a3c07d..f20fbc96a805 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -1846,6 +1846,34 @@ static bool dm_table_supports_discards(struct dm_table *t) | |||
1846 | return true; | 1846 | return true; |
1847 | } | 1847 | } |
1848 | 1848 | ||
1849 | static int device_not_secure_erase_capable(struct dm_target *ti, | ||
1850 | struct dm_dev *dev, sector_t start, | ||
1851 | sector_t len, void *data) | ||
1852 | { | ||
1853 | struct request_queue *q = bdev_get_queue(dev->bdev); | ||
1854 | |||
1855 | return q && !blk_queue_secure_erase(q); | ||
1856 | } | ||
1857 | |||
1858 | static bool dm_table_supports_secure_erase(struct dm_table *t) | ||
1859 | { | ||
1860 | struct dm_target *ti; | ||
1861 | unsigned int i; | ||
1862 | |||
1863 | for (i = 0; i < dm_table_get_num_targets(t); i++) { | ||
1864 | ti = dm_table_get_target(t, i); | ||
1865 | |||
1866 | if (!ti->num_secure_erase_bios) | ||
1867 | return false; | ||
1868 | |||
1869 | if (!ti->type->iterate_devices || | ||
1870 | ti->type->iterate_devices(ti, device_not_secure_erase_capable, NULL)) | ||
1871 | return false; | ||
1872 | } | ||
1873 | |||
1874 | return true; | ||
1875 | } | ||
1876 | |||
1849 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | 1877 | void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, |
1850 | struct queue_limits *limits) | 1878 | struct queue_limits *limits) |
1851 | { | 1879 | { |
@@ -1867,6 +1895,9 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | |||
1867 | } else | 1895 | } else |
1868 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | 1896 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); |
1869 | 1897 | ||
1898 | if (dm_table_supports_secure_erase(t)) | ||
1899 | queue_flag_set_unlocked(QUEUE_FLAG_SECERASE, q); | ||
1900 | |||
1870 | if (dm_table_supports_flush(t, (1UL << QUEUE_FLAG_WC))) { | 1901 | if (dm_table_supports_flush(t, (1UL << QUEUE_FLAG_WC))) { |
1871 | wc = true; | 1902 | wc = true; |
1872 | if (dm_table_supports_flush(t, (1UL << QUEUE_FLAG_FUA))) | 1903 | if (dm_table_supports_flush(t, (1UL << QUEUE_FLAG_FUA))) |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 038c7572fdd4..3b3cbd1a1659 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -1414,6 +1414,11 @@ static unsigned get_num_discard_bios(struct dm_target *ti) | |||
1414 | return ti->num_discard_bios; | 1414 | return ti->num_discard_bios; |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | static unsigned get_num_secure_erase_bios(struct dm_target *ti) | ||
1418 | { | ||
1419 | return ti->num_secure_erase_bios; | ||
1420 | } | ||
1421 | |||
1417 | static unsigned get_num_write_same_bios(struct dm_target *ti) | 1422 | static unsigned get_num_write_same_bios(struct dm_target *ti) |
1418 | { | 1423 | { |
1419 | return ti->num_write_same_bios; | 1424 | return ti->num_write_same_bios; |
@@ -1467,6 +1472,11 @@ static int __send_discard(struct clone_info *ci, struct dm_target *ti) | |||
1467 | is_split_required_for_discard); | 1472 | is_split_required_for_discard); |
1468 | } | 1473 | } |
1469 | 1474 | ||
1475 | static int __send_secure_erase(struct clone_info *ci, struct dm_target *ti) | ||
1476 | { | ||
1477 | return __send_changing_extent_only(ci, ti, get_num_secure_erase_bios, NULL); | ||
1478 | } | ||
1479 | |||
1470 | static int __send_write_same(struct clone_info *ci, struct dm_target *ti) | 1480 | static int __send_write_same(struct clone_info *ci, struct dm_target *ti) |
1471 | { | 1481 | { |
1472 | return __send_changing_extent_only(ci, ti, get_num_write_same_bios, NULL); | 1482 | return __send_changing_extent_only(ci, ti, get_num_write_same_bios, NULL); |
@@ -1484,6 +1494,8 @@ static bool __process_abnormal_io(struct clone_info *ci, struct dm_target *ti, | |||
1484 | 1494 | ||
1485 | if (bio_op(bio) == REQ_OP_DISCARD) | 1495 | if (bio_op(bio) == REQ_OP_DISCARD) |
1486 | *result = __send_discard(ci, ti); | 1496 | *result = __send_discard(ci, ti); |
1497 | else if (bio_op(bio) == REQ_OP_SECURE_ERASE) | ||
1498 | *result = __send_secure_erase(ci, ti); | ||
1487 | else if (bio_op(bio) == REQ_OP_WRITE_SAME) | 1499 | else if (bio_op(bio) == REQ_OP_WRITE_SAME) |
1488 | *result = __send_write_same(ci, ti); | 1500 | *result = __send_write_same(ci, ti); |
1489 | else if (bio_op(bio) == REQ_OP_WRITE_ZEROES) | 1501 | else if (bio_op(bio) == REQ_OP_WRITE_ZEROES) |
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 1e2426c18eb4..019e2efc6c25 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h | |||
@@ -268,6 +268,12 @@ struct dm_target { | |||
268 | unsigned num_discard_bios; | 268 | unsigned num_discard_bios; |
269 | 269 | ||
270 | /* | 270 | /* |
271 | * The number of secure erase bios that will be submitted to the target. | ||
272 | * The bio number can be accessed with dm_bio_get_target_bio_nr. | ||
273 | */ | ||
274 | unsigned num_secure_erase_bios; | ||
275 | |||
276 | /* | ||
271 | * The number of WRITE SAME bios that will be submitted to the target. | 277 | * The number of WRITE SAME bios that will be submitted to the target. |
272 | * The bio number can be accessed with dm_bio_get_target_bio_nr. | 278 | * The bio number can be accessed with dm_bio_get_target_bio_nr. |
273 | */ | 279 | */ |