Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9832c018 authored by Michael Halcrow's avatar Michael Halcrow Committed by Sahitya Tummala
Browse files

dm-crypt: Skip encryption of file system-encrypted blocks



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: default avatarMichael Halcrow <mhalcrow@google.com>
Git-repo: https://android.googlesource.com/kernel/common/


Git-commit: f9341c4da4c59ef2cf8247c01abdb4a1586c84cc
Signed-off-by: default avatarSahitya Tummala <stummala@codeaurora.org>
parent e93c1c1e
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -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.
@@ -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;
@@ -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 +
@@ -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)
@@ -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;