Skip to content

Commit

Permalink
dm-crypt: Skip encryption of file system-encrypted blocks
Browse files Browse the repository at this point in the history
File systems can encrypt some of their data blocks with their own
encryption keys, and for those blocks another round of encryption at
the dm-crypt layer may be redundant, depending on the keys being used.

This patch enables dm-crypt to observe the REQ_NOENCRYPT flag as an
indicator that a bio request should bypass the dm-crypt encryption
queue.

By default dm-crypt will ignore this request flag from the file
system.  The user must set the allow_encrypt_override option to enable
this functionality.  Once the dm-crypt has been used with the
allow_encrypt_override option for any given block device, it must
continue to be used with the option to avoid the possibility of data
corruption.

Change-Id: Ie1b4d40f4e4d96f3349ec8970c56230b2de2de1a
Signed-off-by: Michael Halcrow <mhalcrow@google.com>
Git-repo: https://android.googlesource.com/kernel/common/
Git-commit: f9341c4da4c59ef2cf8247c01abdb4a1586c84cc
Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
  • Loading branch information
mhalcrow-google authored and Sahitya Tummala committed Dec 21, 2018
1 parent e93c1c1 commit 9832c01
Showing 1 changed file with 14 additions and 4 deletions.
18 changes: 14 additions & 4 deletions drivers/md/dm-crypt.c
Expand Up @@ -113,7 +113,8 @@ struct iv_tcw_private {
* and encrypts / decrypts at the same time.
*/
enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID,
DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD };
DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD,
DM_CRYPT_ENCRYPT_OVERRIDE };

/*
* The fields in here must be read only after initialization.
Expand Down Expand Up @@ -1858,6 +1859,9 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
else if (!strcasecmp(opt_string, "submit_from_crypt_cpus"))
set_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags);

else if (!strcasecmp(opt_string, "allow_encrypt_override"))
set_bit(DM_CRYPT_ENCRYPT_OVERRIDE, &cc->flags);

else {
ti->error = "Invalid feature arguments";
goto bad;
Expand Down Expand Up @@ -1918,12 +1922,15 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
struct crypt_config *cc = ti->private;

/*
* If bio is REQ_PREFLUSH or REQ_OP_DISCARD, just bypass crypt queues.
* If bio is REQ_PREFLUSH, REQ_NOENCRYPT, or REQ_OP_DISCARD,
* just bypass crypt queues.
* - for REQ_PREFLUSH device-mapper core ensures that no IO is in-flight
* - for REQ_OP_DISCARD caller must use flush if IO ordering matters
*/
if (unlikely(bio->bi_opf & REQ_PREFLUSH ||
bio_op(bio) == REQ_OP_DISCARD)) {
if (unlikely(bio->bi_opf & REQ_PREFLUSH) ||
(unlikely(bio->bi_opf & REQ_NOENCRYPT) &&
test_bit(DM_CRYPT_ENCRYPT_OVERRIDE, &cc->flags)) ||
bio_op(bio) == REQ_OP_DISCARD) {
bio->bi_bdev = cc->dev->bdev;
if (bio_sectors(bio))
bio->bi_iter.bi_sector = cc->start +
Expand Down Expand Up @@ -1978,6 +1985,7 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
num_feature_args += !!ti->num_discard_bios;
num_feature_args += test_bit(DM_CRYPT_SAME_CPU, &cc->flags);
num_feature_args += test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags);
num_feature_args += test_bit(DM_CRYPT_ENCRYPT_OVERRIDE, &cc->flags);
if (num_feature_args) {
DMEMIT(" %d", num_feature_args);
if (ti->num_discard_bios)
Expand All @@ -1986,6 +1994,8 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
DMEMIT(" same_cpu_crypt");
if (test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags))
DMEMIT(" submit_from_crypt_cpus");
if (test_bit(DM_CRYPT_ENCRYPT_OVERRIDE, &cc->flags))
DMEMIT(" allow_encrypt_override");
}

break;
Expand Down

0 comments on commit 9832c01

Please sign in to comment.