diff --git a/block/bio.c b/block/bio.c index a4c8c99351da..a44b52572540 100644 --- a/block/bio.c +++ b/block/bio.c @@ -568,8 +568,11 @@ EXPORT_SYMBOL(bio_phys_segments); static inline void bio_clone_crypt_key(struct bio *dst, const struct bio *src) { #ifdef CONFIG_PFK - dst->bi_crypt_key = src->bi_crypt_key; dst->bi_iter.bi_dun = src->bi_iter.bi_dun; +#ifdef CONFIG_DM_DEFAULT_KEY + dst->bi_crypt_key = src->bi_crypt_key; + dst->bi_crypt_skip = src->bi_crypt_skip; +#endif dst->bi_dio_inode = src->bi_dio_inode; #endif } diff --git a/fs/crypto/fscrypt_ice.c b/fs/crypto/fscrypt_ice.c index 62dae83cf732..ae28cdfd83e4 100644 --- a/fs/crypto/fscrypt_ice.c +++ b/fs/crypto/fscrypt_ice.c @@ -126,16 +126,29 @@ void fscrypt_set_ice_dun(const struct inode *inode, struct bio *bio, u64 dun) } EXPORT_SYMBOL(fscrypt_set_ice_dun); +void fscrypt_set_ice_skip(struct bio *bio, int bi_crypt_skip) +{ +#ifdef CONFIG_DM_DEFAULT_KEY + bio->bi_crypt_skip = bi_crypt_skip; +#endif +} +EXPORT_SYMBOL(fscrypt_set_ice_skip); + /* * This function will be used for filesystem when deciding to merge bios. * Basic assumption is, if inline_encryption is set, single bio has to * guarantee consecutive LBAs as well as ino|pg->index. */ -bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted) +bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted, + int bi_crypt_skip) { if (!bio) return true; +#ifdef CONFIG_DM_DEFAULT_KEY + if (bi_crypt_skip != bio->bi_crypt_skip) + return false; +#endif /* if both of them are not encrypted, no further check is needed */ if (!bio_dun(bio) && !bio_encrypted) return true; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 25256aed7d15..8bc9e2244850 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -448,7 +448,8 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio) 1, is_read_io(fio->op), fio->type, fio->temp); if (f2fs_may_encrypt_bio(inode, fio)) - fscrypt_set_ice_dun(inode, bio, PG_DUN(inode, fio->page)); + fscrypt_set_ice_dun(inode, bio, PG_DUN(inode, fio->page)); + fscrypt_set_ice_skip(bio, fio->encrypted_page ? 1 : 0); if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { bio_put(bio); @@ -471,6 +472,7 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio) struct page *bio_page; struct inode *inode; bool bio_encrypted; + int bi_crypt_skip; u64 dun; int err = 0; @@ -497,6 +499,7 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio) bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page; inode = fio->page->mapping->host; dun = PG_DUN(inode, fio->page); + bi_crypt_skip = fio->encrypted_page ? 1 : 0; bio_encrypted = f2fs_may_encrypt_bio(inode, fio); /* set submitted = true as a return value */ @@ -510,7 +513,7 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio) __submit_merged_bio(io); /* ICE support */ - if (!fscrypt_mergeable_bio(io->bio, dun, bio_encrypted)) + if (!fscrypt_mergeable_bio(io->bio, dun, bio_encrypted, bi_crypt_skip)) __submit_merged_bio(io); alloc_new: @@ -526,7 +529,7 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio) fio->type, fio->temp); if (bio_encrypted) fscrypt_set_ice_dun(inode, io->bio, dun); - + fscrypt_set_ice_skip(io->bio, bi_crypt_skip); io->fio = *fio; } @@ -1538,7 +1541,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping, dun = PG_DUN(inode, page); bio_encrypted = f2fs_may_encrypt_bio(inode, NULL); - if (!fscrypt_mergeable_bio(bio, dun, bio_encrypted)) { + if (!fscrypt_mergeable_bio(bio, dun, bio_encrypted, 0)) { __submit_bio(F2FS_I_SB(inode), bio, DATA); bio = NULL; } diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 42ad6b5de619..a14967198d60 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -78,6 +78,9 @@ struct bio { */ struct inode *bi_dio_inode; #endif +#ifdef CONFIG_DM_DEFAULT_KEY + int bi_crypt_skip; +#endif unsigned short bi_vcnt; /* how many bio_vec's */ diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 1e036141ab4d..f5371c2ce84b 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -257,7 +257,9 @@ static inline int fscrypt_encrypt_symlink(struct inode *inode, extern int fscrypt_using_hardware_encryption(const struct inode *inode); extern void fscrypt_set_ice_dun(const struct inode *inode, struct bio *bio, u64 dun); -extern bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted); +extern bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted, + int bi_crypt_skip); +extern void fscrypt_set_ice_skip(struct bio *bio, int bi_crypt_skip); #else static inline int fscrypt_using_hardware_encryption(const struct inode *inode) { @@ -270,8 +272,12 @@ static inline void fscrypt_set_ice_dun(const struct inode *inode, return; } +static inline void fscrypt_set_ice_skip(struct bio *bio, int bi_crypt_skip) +{ +} + static inline bool fscrypt_mergeable_bio(struct bio *bio, - u64 dun, bool bio_encrypted) + u64 dun, bool bio_encrypted, int bi_crypt_skip) { return true; } diff --git a/security/pfe/pfk.c b/security/pfe/pfk.c index f9a629214091..6518ac9e5deb 100644 --- a/security/pfe/pfk.c +++ b/security/pfe/pfk.c @@ -287,8 +287,8 @@ static int pfk_get_key_for_bio(const struct bio *bio, { const struct inode *inode; enum pfe_type which_pfe; - const struct blk_encryption_key *key; char *s_type = NULL; + const struct blk_encryption_key *key = NULL; inode = pfk_bio_get_inode(bio); which_pfe = pfk_get_pfe_type(inode); @@ -307,7 +307,9 @@ static int pfk_get_key_for_bio(const struct bio *bio, * bio is not for an encrypted file. Use ->bi_crypt_key if it was set. * Otherwise, don't encrypt/decrypt the bio. */ +#ifdef CONFIG_DM_DEFAULT_KEY key = bio->bi_crypt_key; +#endif if (!key) { *is_pfe = false; return -EINVAL; @@ -469,13 +471,18 @@ int pfk_load_key_end(const struct bio *bio, bool *is_pfe) */ bool pfk_allow_merge_bio(const struct bio *bio1, const struct bio *bio2) { - const struct blk_encryption_key *key1; - const struct blk_encryption_key *key2; + const struct blk_encryption_key *key1 = NULL; + const struct blk_encryption_key *key2 = NULL; const struct inode *inode1; const struct inode *inode2; enum pfe_type which_pfe1; enum pfe_type which_pfe2; +#ifdef CONFIG_DM_DEFAULT_KEY + key1 = bio1->bi_crypt_key; + key2 = bio2->bi_crypt_key; +#endif + if (!pfk_is_ready()) return false;