aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-crypt.c')
-rw-r--r--drivers/md/dm-crypt.c62
1 files changed, 51 insertions, 11 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index bae6c4e23d3..49da55c1528 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -30,7 +30,6 @@
30#include <linux/device-mapper.h> 30#include <linux/device-mapper.h>
31 31
32#define DM_MSG_PREFIX "crypt" 32#define DM_MSG_PREFIX "crypt"
33#define MESG_STR(x) x, sizeof(x)
34 33
35/* 34/*
36 * context holding the current state of a multi-part conversion 35 * context holding the current state of a multi-part conversion
@@ -239,7 +238,7 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv,
239 struct dm_crypt_request *dmreq) 238 struct dm_crypt_request *dmreq)
240{ 239{
241 memset(iv, 0, cc->iv_size); 240 memset(iv, 0, cc->iv_size);
242 *(u32 *)iv = cpu_to_le32(dmreq->iv_sector & 0xffffffff); 241 *(__le32 *)iv = cpu_to_le32(dmreq->iv_sector & 0xffffffff);
243 242
244 return 0; 243 return 0;
245} 244}
@@ -248,7 +247,7 @@ static int crypt_iv_plain64_gen(struct crypt_config *cc, u8 *iv,
248 struct dm_crypt_request *dmreq) 247 struct dm_crypt_request *dmreq)
249{ 248{
250 memset(iv, 0, cc->iv_size); 249 memset(iv, 0, cc->iv_size);
251 *(u64 *)iv = cpu_to_le64(dmreq->iv_sector); 250 *(__le64 *)iv = cpu_to_le64(dmreq->iv_sector);
252 251
253 return 0; 252 return 0;
254} 253}
@@ -415,7 +414,7 @@ static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv,
415 struct crypto_cipher *essiv_tfm = this_crypt_config(cc)->iv_private; 414 struct crypto_cipher *essiv_tfm = this_crypt_config(cc)->iv_private;
416 415
417 memset(iv, 0, cc->iv_size); 416 memset(iv, 0, cc->iv_size);
418 *(u64 *)iv = cpu_to_le64(dmreq->iv_sector); 417 *(__le64 *)iv = cpu_to_le64(dmreq->iv_sector);
419 crypto_cipher_encrypt_one(essiv_tfm, iv, iv); 418 crypto_cipher_encrypt_one(essiv_tfm, iv, iv);
420 419
421 return 0; 420 return 0;
@@ -1575,11 +1574,17 @@ bad_mem:
1575static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) 1574static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1576{ 1575{
1577 struct crypt_config *cc; 1576 struct crypt_config *cc;
1578 unsigned int key_size; 1577 unsigned int key_size, opt_params;
1579 unsigned long long tmpll; 1578 unsigned long long tmpll;
1580 int ret; 1579 int ret;
1580 struct dm_arg_set as;
1581 const char *opt_string;
1582
1583 static struct dm_arg _args[] = {
1584 {0, 1, "Invalid number of feature args"},
1585 };
1581 1586
1582 if (argc != 5) { 1587 if (argc < 5) {
1583 ti->error = "Not enough arguments"; 1588 ti->error = "Not enough arguments";
1584 return -EINVAL; 1589 return -EINVAL;
1585 } 1590 }
@@ -1648,6 +1653,30 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1648 } 1653 }
1649 cc->start = tmpll; 1654 cc->start = tmpll;
1650 1655
1656 argv += 5;
1657 argc -= 5;
1658
1659 /* Optional parameters */
1660 if (argc) {
1661 as.argc = argc;
1662 as.argv = argv;
1663
1664 ret = dm_read_arg_group(_args, &as, &opt_params, &ti->error);
1665 if (ret)
1666 goto bad;
1667
1668 opt_string = dm_shift_arg(&as);
1669
1670 if (opt_params == 1 && opt_string &&
1671 !strcasecmp(opt_string, "allow_discards"))
1672 ti->num_discard_requests = 1;
1673 else if (opt_params) {
1674 ret = -EINVAL;
1675 ti->error = "Invalid feature arguments";
1676 goto bad;
1677 }
1678 }
1679
1651 ret = -ENOMEM; 1680 ret = -ENOMEM;
1652 cc->io_queue = alloc_workqueue("kcryptd_io", 1681 cc->io_queue = alloc_workqueue("kcryptd_io",
1653 WQ_NON_REENTRANT| 1682 WQ_NON_REENTRANT|
@@ -1682,9 +1711,16 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
1682 struct dm_crypt_io *io; 1711 struct dm_crypt_io *io;
1683 struct crypt_config *cc; 1712 struct crypt_config *cc;
1684 1713
1685 if (bio->bi_rw & REQ_FLUSH) { 1714 /*
1715 * If bio is REQ_FLUSH or REQ_DISCARD, just bypass crypt queues.
1716 * - for REQ_FLUSH device-mapper core ensures that no IO is in-flight
1717 * - for REQ_DISCARD caller must use flush if IO ordering matters
1718 */
1719 if (unlikely(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) {
1686 cc = ti->private; 1720 cc = ti->private;
1687 bio->bi_bdev = cc->dev->bdev; 1721 bio->bi_bdev = cc->dev->bdev;
1722 if (bio_sectors(bio))
1723 bio->bi_sector = cc->start + dm_target_offset(ti, bio->bi_sector);
1688 return DM_MAPIO_REMAPPED; 1724 return DM_MAPIO_REMAPPED;
1689 } 1725 }
1690 1726
@@ -1727,6 +1763,10 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
1727 1763
1728 DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset, 1764 DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
1729 cc->dev->name, (unsigned long long)cc->start); 1765 cc->dev->name, (unsigned long long)cc->start);
1766
1767 if (ti->num_discard_requests)
1768 DMEMIT(" 1 allow_discards");
1769
1730 break; 1770 break;
1731 } 1771 }
1732 return 0; 1772 return 0;
@@ -1770,12 +1810,12 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
1770 if (argc < 2) 1810 if (argc < 2)
1771 goto error; 1811 goto error;
1772 1812
1773 if (!strnicmp(argv[0], MESG_STR("key"))) { 1813 if (!strcasecmp(argv[0], "key")) {
1774 if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) { 1814 if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) {
1775 DMWARN("not suspended during key manipulation."); 1815 DMWARN("not suspended during key manipulation.");
1776 return -EINVAL; 1816 return -EINVAL;
1777 } 1817 }
1778 if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) { 1818 if (argc == 3 && !strcasecmp(argv[1], "set")) {
1779 ret = crypt_set_key(cc, argv[2]); 1819 ret = crypt_set_key(cc, argv[2]);
1780 if (ret) 1820 if (ret)
1781 return ret; 1821 return ret;
@@ -1783,7 +1823,7 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
1783 ret = cc->iv_gen_ops->init(cc); 1823 ret = cc->iv_gen_ops->init(cc);
1784 return ret; 1824 return ret;
1785 } 1825 }
1786 if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) { 1826 if (argc == 2 && !strcasecmp(argv[1], "wipe")) {
1787 if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) { 1827 if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) {
1788 ret = cc->iv_gen_ops->wipe(cc); 1828 ret = cc->iv_gen_ops->wipe(cc);
1789 if (ret) 1829 if (ret)
@@ -1823,7 +1863,7 @@ static int crypt_iterate_devices(struct dm_target *ti,
1823 1863
1824static struct target_type crypt_target = { 1864static struct target_type crypt_target = {
1825 .name = "crypt", 1865 .name = "crypt",
1826 .version = {1, 10, 0}, 1866 .version = {1, 11, 0},
1827 .module = THIS_MODULE, 1867 .module = THIS_MODULE,
1828 .ctr = crypt_ctr, 1868 .ctr = crypt_ctr,
1829 .dtr = crypt_dtr, 1869 .dtr = crypt_dtr,