aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-crypt.c
diff options
context:
space:
mode:
authorMilan Broz <mbroz@redhat.com>2011-08-02 07:32:08 -0400
committerAlasdair G Kergon <agk@redhat.com>2011-08-02 07:32:08 -0400
commit772ae5f54d69c38a5e3c4352c5fdbdaff141af21 (patch)
tree727b6dc7596b8250d644214695f09e3d6c7e43d1 /drivers/md/dm-crypt.c
parent327372797c88b24953f454cd51a3734c02697bdd (diff)
dm crypt: optionally support discard requests
Add optional parameter field to dmcrypt table and support "allow_discards" option. Discard requests bypass crypt queue processing. Bio is simple remapped to underlying device. Note that discard will be never enabled by default because of security consequences. It is up to the administrator to enable it for encrypted devices. (Note that userspace cryptsetup does not understand new optional parameters yet. Support for this will come later. Until then, you should use 'dmsetup' to enable and disable this.) Signed-off-by: Milan Broz <mbroz@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-crypt.c')
-rw-r--r--drivers/md/dm-crypt.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index b79e7472a9b3..49da55c1528a 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1574,11 +1574,17 @@ bad_mem:
1574static 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)
1575{ 1575{
1576 struct crypt_config *cc; 1576 struct crypt_config *cc;
1577 unsigned int key_size; 1577 unsigned int key_size, opt_params;
1578 unsigned long long tmpll; 1578 unsigned long long tmpll;
1579 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 };
1580 1586
1581 if (argc != 5) { 1587 if (argc < 5) {
1582 ti->error = "Not enough arguments"; 1588 ti->error = "Not enough arguments";
1583 return -EINVAL; 1589 return -EINVAL;
1584 } 1590 }
@@ -1647,6 +1653,30 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1647 } 1653 }
1648 cc->start = tmpll; 1654 cc->start = tmpll;
1649 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
1650 ret = -ENOMEM; 1680 ret = -ENOMEM;
1651 cc->io_queue = alloc_workqueue("kcryptd_io", 1681 cc->io_queue = alloc_workqueue("kcryptd_io",
1652 WQ_NON_REENTRANT| 1682 WQ_NON_REENTRANT|
@@ -1681,9 +1711,16 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
1681 struct dm_crypt_io *io; 1711 struct dm_crypt_io *io;
1682 struct crypt_config *cc; 1712 struct crypt_config *cc;
1683 1713
1684 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))) {
1685 cc = ti->private; 1720 cc = ti->private;
1686 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);
1687 return DM_MAPIO_REMAPPED; 1724 return DM_MAPIO_REMAPPED;
1688 } 1725 }
1689 1726
@@ -1726,6 +1763,10 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
1726 1763
1727 DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset, 1764 DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
1728 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
1729 break; 1770 break;
1730 } 1771 }
1731 return 0; 1772 return 0;
@@ -1822,7 +1863,7 @@ static int crypt_iterate_devices(struct dm_target *ti,
1822 1863
1823static struct target_type crypt_target = { 1864static struct target_type crypt_target = {
1824 .name = "crypt", 1865 .name = "crypt",
1825 .version = {1, 10, 0}, 1866 .version = {1, 11, 0},
1826 .module = THIS_MODULE, 1867 .module = THIS_MODULE,
1827 .ctr = crypt_ctr, 1868 .ctr = crypt_ctr,
1828 .dtr = crypt_dtr, 1869 .dtr = crypt_dtr,