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

Commit 4fd953eb authored by Barani Muthukumaran's avatar Barani Muthukumaran Committed by Gerrit - the friendly Code Review server
Browse files

[ANDROID] 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: Ica020ddb2c44f39cbf02a829df2a3e0bdfc0cca4
Signed-off-by: default avatarMichael Halcrow <mhalcrow@google.com>
Git-repo: https://android.googlesource.com/kernel/common/


[bmuthuku@codeaurora.org: resolved trivial merge conflicts]
Signed-off-by: default avatarBarani Muthukumaran <bmuthuku@codeaurora.org>
parent 99080dfb
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -125,7 +125,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 };

enum cipher_flags {
	CRYPT_MODE_INTEGRITY_AEAD,	/* Use authenticated mode for cihper */
@@ -2663,6 +2664,8 @@ static int crypt_ctr_optional(struct dm_target *ti, unsigned int argc, char **ar
			cc->sector_shift = __ffs(cc->sector_size) - SECTOR_SHIFT;
		} else if (!strcasecmp(opt_string, "iv_large_sectors"))
			set_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags);
		else if (!strcasecmp(opt_string, "allow_encrypt_override"))
			set_bit(DM_CRYPT_ENCRYPT_OVERRIDE, &cc->flags);
		else {
			ti->error = "Invalid feature arguments";
			return -EINVAL;
@@ -2868,12 +2871,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_set_dev(bio, cc->dev->bdev);
		if (bio_sectors(bio))
			bio->bi_iter.bi_sector = cc->start +
@@ -2960,6 +2966,8 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
		num_feature_args += test_bit(DM_CRYPT_NO_OFFLOAD, &cc->flags);
		num_feature_args += cc->sector_size != (1 << SECTOR_SHIFT);
		num_feature_args += test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags);
		num_feature_args += test_bit(DM_CRYPT_ENCRYPT_OVERRIDE,
							&cc->flags);
		if (cc->on_disk_tag_size)
			num_feature_args++;
		if (num_feature_args) {
@@ -2976,6 +2984,8 @@ static void crypt_status(struct dm_target *ti, status_type_t type,
				DMEMIT(" sector_size:%d", cc->sector_size);
			if (test_bit(CRYPT_IV_LARGE_SECTORS, &cc->cipher_flags))
				DMEMIT(" iv_large_sectors");
			if (test_bit(DM_CRYPT_ENCRYPT_OVERRIDE, &cc->flags))
				DMEMIT(" allow_encrypt_override");
		}

		break;
+6 −8
Original line number Diff line number Diff line
@@ -333,17 +333,17 @@ enum req_flag_bits {

	__REQ_SORTED = __REQ_RAHEAD, /* elevator knows about this request */
	__REQ_URGENT,		/* urgent request */
	/* Android specific flags */
	__REQ_NOENCRYPT,	/*
				 * ok to not encrypt (already encrypted at fs
				 * level)
				 */
	/* command specific flags for REQ_OP_WRITE_ZEROES: */
	__REQ_NOUNMAP,		/* do not free blocks when zeroing */

	/* for driver use */
	__REQ_DRV,
	__REQ_SWAP,		/* swapping request. */
	/* Android specific flags */
	__REQ_NOENCRYPT,	/*
				 * ok to not encrypt (already encrypted at fs
				 * level)
				 */
	__REQ_NR_BITS,		/* stops here */
};

@@ -362,12 +362,10 @@ enum req_flag_bits {
#define REQ_RAHEAD		(1ULL << __REQ_RAHEAD)
#define REQ_BACKGROUND		(1ULL << __REQ_BACKGROUND)
#define REQ_NOWAIT		(1ULL << __REQ_NOWAIT)
#define REQ_NOENCRYPT		(1ULL << __REQ_NOENCRYPT)

#define REQ_NOUNMAP		(1ULL << __REQ_NOUNMAP)

#define REQ_DRV			(1ULL << __REQ_DRV)
#define REQ_SWAP		(1ULL << __REQ_SWAP)
#define REQ_NOENCRYPT		(1ULL << __REQ_NOENCRYPT)

#define REQ_FAILFAST_MASK \
	(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)