* [PATCH 1/5] ext4: clean up superblock encryption mode fields
@ 2015-05-12 18:59 Theodore Ts'o
2015-05-12 18:59 ` [PATCH 2/5] ext4 crypto: use slab caches Theodore Ts'o
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Theodore Ts'o @ 2015-05-12 18:59 UTC (permalink / raw)
To: Ext4 Developers List; +Cc: jaegeuk, Theodore Ts'o
The superblock fields s_file_encryption_mode and s_dir_encryption_mode
are vestigal, so remove them as a cleanup. While we're at it, allow
file systems with both encryption and inline_data enabled at the same
time to work correctly. We can't have encrypted inodes with inline
data, but there's no reason to prohibit unencrypted inodes from using
the inline data feature.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
fs/ext4/crypto_policy.c | 9 +++++++--
fs/ext4/ext4.h | 6 ------
fs/ext4/ialloc.c | 19 -------------------
fs/ext4/super.c | 5 -----
4 files changed, 7 insertions(+), 32 deletions(-)
diff --git a/fs/ext4/crypto_policy.c b/fs/ext4/crypto_policy.c
index 370d3aa..683391f 100644
--- a/fs/ext4/crypto_policy.c
+++ b/fs/ext4/crypto_policy.c
@@ -51,6 +51,10 @@ static int ext4_create_encryption_context_from_policy(
struct ext4_encryption_context ctx;
int res = 0;
+ res = ext4_convert_inline_data(inode);
+ if (res)
+ return res;
+
ctx.format = EXT4_ENCRYPTION_CONTEXT_FORMAT_V1;
memcpy(ctx.master_key_descriptor, policy->master_key_descriptor,
EXT4_KEY_DESCRIPTOR_SIZE);
@@ -199,8 +203,9 @@ int ext4_inherit_context(struct inode *parent, struct inode *child)
res = ext4_xattr_set(child, EXT4_XATTR_INDEX_ENCRYPTION,
EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, &ctx,
sizeof(ctx), 0);
- if (!res)
+ if (!res) {
ext4_set_inode_flag(child, EXT4_INODE_ENCRYPT);
+ ext4_clear_inode_state(child, EXT4_STATE_MAY_INLINE_DATA);
+ }
return res;
-
}
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 1db3bfa..641b781 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1374,12 +1374,6 @@ struct ext4_sb_info {
struct ratelimit_state s_err_ratelimit_state;
struct ratelimit_state s_warning_ratelimit_state;
struct ratelimit_state s_msg_ratelimit_state;
-
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
- /* Encryption */
- uint32_t s_file_encryption_mode;
- uint32_t s_dir_encryption_mode;
-#endif
};
static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 1eaa6cb..ddca169 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -1034,28 +1034,9 @@ got:
ext4_set_inode_state(inode, EXT4_STATE_NEW);
ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
- if ((sbi->s_file_encryption_mode == EXT4_ENCRYPTION_MODE_INVALID) &&
- (sbi->s_dir_encryption_mode == EXT4_ENCRYPTION_MODE_INVALID)) {
- ei->i_inline_off = 0;
- if (EXT4_HAS_INCOMPAT_FEATURE(sb,
- EXT4_FEATURE_INCOMPAT_INLINE_DATA))
- ext4_set_inode_state(inode,
- EXT4_STATE_MAY_INLINE_DATA);
- } else {
- /* Inline data and encryption are incompatible
- * We turn off inline data since encryption is enabled */
- ei->i_inline_off = 1;
- if (EXT4_HAS_INCOMPAT_FEATURE(sb,
- EXT4_FEATURE_INCOMPAT_INLINE_DATA))
- ext4_clear_inode_state(inode,
- EXT4_STATE_MAY_INLINE_DATA);
- }
-#else
ei->i_inline_off = 0;
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_INLINE_DATA))
ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
-#endif
ret = inode;
err = dquot_alloc_inode(inode);
if (err)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index ef19bda..79311e0 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3450,11 +3450,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
if (sb->s_bdev->bd_part)
sbi->s_sectors_written_start =
part_stat_read(sb->s_bdev->bd_part, sectors[1]);
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
- /* Modes of operations for file and directory encryption. */
- sbi->s_file_encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
- sbi->s_dir_encryption_mode = EXT4_ENCRYPTION_MODE_INVALID;
-#endif
/* Cleanup superblock name */
for (cp = sb->s_id; (cp = strchr(cp, '/'));)
--
2.3.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/5] ext4 crypto: use slab caches
2015-05-12 18:59 [PATCH 1/5] ext4: clean up superblock encryption mode fields Theodore Ts'o
@ 2015-05-12 18:59 ` Theodore Ts'o
2015-05-12 18:59 ` [PATCH 3/5] ext4 crypto: get rid of ci_mode from struct ext4_crypt_info Theodore Ts'o
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Theodore Ts'o @ 2015-05-12 18:59 UTC (permalink / raw)
To: Ext4 Developers List; +Cc: jaegeuk, Theodore Ts'o
Use slab caches the ext4_crypto_ctx and ext4_crypt_info structures for
slighly better memory efficiency and debuggability.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
fs/ext4/crypto.c | 60 +++++++++++++++++++++++++---------------------------
fs/ext4/crypto_key.c | 12 ++++++++---
fs/ext4/ext4.h | 1 +
3 files changed, 39 insertions(+), 34 deletions(-)
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
index 3a25aa4..1c34f0e 100644
--- a/fs/ext4/crypto.c
+++ b/fs/ext4/crypto.c
@@ -55,6 +55,9 @@ static mempool_t *ext4_bounce_page_pool;
static LIST_HEAD(ext4_free_crypto_ctxs);
static DEFINE_SPINLOCK(ext4_crypto_ctx_lock);
+static struct kmem_cache *ext4_crypto_ctx_cachep;
+struct kmem_cache *ext4_crypt_info_cachep;
+
/**
* ext4_release_crypto_ctx() - Releases an encryption context
* @ctx: The encryption context to release.
@@ -79,7 +82,7 @@ void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx)
if (ctx->flags & EXT4_CTX_REQUIRES_FREE_ENCRYPT_FL) {
if (ctx->tfm)
crypto_free_tfm(ctx->tfm);
- kfree(ctx);
+ kmem_cache_free(ext4_crypto_ctx_cachep, ctx);
} else {
spin_lock_irqsave(&ext4_crypto_ctx_lock, flags);
list_add(&ctx->free_list, &ext4_free_crypto_ctxs);
@@ -88,23 +91,6 @@ void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx)
}
/**
- * ext4_alloc_and_init_crypto_ctx() - Allocates and inits an encryption context
- * @mask: The allocation mask.
- *
- * Return: An allocated and initialized encryption context on success. An error
- * value or NULL otherwise.
- */
-static struct ext4_crypto_ctx *ext4_alloc_and_init_crypto_ctx(gfp_t mask)
-{
- struct ext4_crypto_ctx *ctx = kzalloc(sizeof(struct ext4_crypto_ctx),
- mask);
-
- if (!ctx)
- return ERR_PTR(-ENOMEM);
- return ctx;
-}
-
-/**
* ext4_get_crypto_ctx() - Gets an encryption context
* @inode: The inode for which we are doing the crypto
*
@@ -121,8 +107,6 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
BUG_ON(ci == NULL);
- if (!ext4_read_workqueue)
- ext4_init_crypto();
/*
* We first try getting the ctx from a free list because in
@@ -141,9 +125,9 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
list_del(&ctx->free_list);
spin_unlock_irqrestore(&ext4_crypto_ctx_lock, flags);
if (!ctx) {
- ctx = ext4_alloc_and_init_crypto_ctx(GFP_NOFS);
- if (IS_ERR(ctx)) {
- res = PTR_ERR(ctx);
+ ctx = kmem_cache_zalloc(ext4_crypto_ctx_cachep, GFP_NOFS);
+ if (!ctx) {
+ res = -ENOMEM;
goto out;
}
ctx->flags |= EXT4_CTX_REQUIRES_FREE_ENCRYPT_FL;
@@ -217,7 +201,7 @@ void ext4_exit_crypto(void)
}
if (pos->tfm)
crypto_free_tfm(pos->tfm);
- kfree(pos);
+ kmem_cache_free(ext4_crypto_ctx_cachep, pos);
}
INIT_LIST_HEAD(&ext4_free_crypto_ctxs);
if (ext4_bounce_page_pool)
@@ -226,6 +210,12 @@ void ext4_exit_crypto(void)
if (ext4_read_workqueue)
destroy_workqueue(ext4_read_workqueue);
ext4_read_workqueue = NULL;
+ if (ext4_crypto_ctx_cachep)
+ kmem_cache_destroy(ext4_crypto_ctx_cachep);
+ ext4_crypto_ctx_cachep = NULL;
+ if (ext4_crypt_info_cachep)
+ kmem_cache_destroy(ext4_crypt_info_cachep);
+ ext4_crypt_info_cachep = NULL;
}
/**
@@ -238,23 +228,31 @@ void ext4_exit_crypto(void)
*/
int ext4_init_crypto(void)
{
- int i, res;
+ int i, res = -ENOMEM;
mutex_lock(&crypto_init);
if (ext4_read_workqueue)
goto already_initialized;
ext4_read_workqueue = alloc_workqueue("ext4_crypto", WQ_HIGHPRI, 0);
- if (!ext4_read_workqueue) {
- res = -ENOMEM;
+ if (!ext4_read_workqueue)
+ goto fail;
+
+ ext4_crypto_ctx_cachep = KMEM_CACHE(ext4_crypto_ctx,
+ SLAB_RECLAIM_ACCOUNT);
+ if (!ext4_crypto_ctx_cachep)
+ goto fail;
+
+ ext4_crypt_info_cachep = KMEM_CACHE(ext4_crypt_info,
+ SLAB_RECLAIM_ACCOUNT);
+ if (!ext4_crypt_info_cachep)
goto fail;
- }
for (i = 0; i < num_prealloc_crypto_ctxs; i++) {
struct ext4_crypto_ctx *ctx;
- ctx = ext4_alloc_and_init_crypto_ctx(GFP_KERNEL);
- if (IS_ERR(ctx)) {
- res = PTR_ERR(ctx);
+ ctx = kmem_cache_zalloc(ext4_crypto_ctx_cachep, GFP_NOFS);
+ if (!ctx) {
+ res = -ENOMEM;
goto fail;
}
list_add(&ctx->free_list, &ext4_free_crypto_ctxs);
diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c
index 0075e43..d6abe46 100644
--- a/fs/ext4/crypto_key.c
+++ b/fs/ext4/crypto_key.c
@@ -96,7 +96,7 @@ void ext4_free_encryption_info(struct inode *inode)
key_put(ci->ci_keyring_key);
crypto_free_ablkcipher(ci->ci_ctfm);
memzero_explicit(&ci->ci_raw, sizeof(ci->ci_raw));
- kfree(ci);
+ kmem_cache_free(ext4_crypt_info_cachep, ci);
ei->i_crypt_info = NULL;
}
@@ -113,6 +113,12 @@ int _ext4_get_encryption_info(struct inode *inode)
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
int res;
+ if (!ext4_read_workqueue) {
+ res = ext4_init_crypto();
+ if (res)
+ return res;
+ }
+
if (ei->i_crypt_info) {
if (!ei->i_crypt_info->ci_keyring_key ||
key_validate(ei->i_crypt_info->ci_keyring_key) == 0)
@@ -134,7 +140,7 @@ int _ext4_get_encryption_info(struct inode *inode)
return -EINVAL;
res = 0;
- crypt_info = kmalloc(sizeof(struct ext4_crypt_info), GFP_KERNEL);
+ crypt_info = kmem_cache_alloc(ext4_crypt_info_cachep, GFP_KERNEL);
if (!crypt_info)
return -ENOMEM;
@@ -188,7 +194,7 @@ out:
if (res < 0) {
if (res == -ENOKEY)
res = 0;
- kfree(crypt_info);
+ kmem_cache_free(ext4_crypt_info_cachep, crypt_info);
} else {
ei->i_crypt_info = crypt_info;
crypt_info->ci_keyring_key = keyring_key;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 641b781..550fe95 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2059,6 +2059,7 @@ int ext4_get_policy(struct inode *inode,
struct ext4_encryption_policy *policy);
/* crypto.c */
+extern struct kmem_cache *ext4_crypt_info_cachep;
bool ext4_valid_contents_enc_mode(uint32_t mode);
uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size);
extern struct workqueue_struct *ext4_read_workqueue;
--
2.3.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/5] ext4 crypto: get rid of ci_mode from struct ext4_crypt_info
2015-05-12 18:59 [PATCH 1/5] ext4: clean up superblock encryption mode fields Theodore Ts'o
2015-05-12 18:59 ` [PATCH 2/5] ext4 crypto: use slab caches Theodore Ts'o
@ 2015-05-12 18:59 ` Theodore Ts'o
2015-05-12 18:59 ` [PATCH 4/5] ext4 crypto: shrink size of the ext4_crypto_ctx structure Theodore Ts'o
2015-05-12 18:59 ` [PATCH 5/5] ext4 crypto: require CONFIG_CRYPTO_CTR if ext4 encryption is enabled Theodore Ts'o
3 siblings, 0 replies; 5+ messages in thread
From: Theodore Ts'o @ 2015-05-12 18:59 UTC (permalink / raw)
To: Ext4 Developers List; +Cc: jaegeuk, Theodore Ts'o
The ci_mode field was superfluous, and getting rid of it gets rid of
an unused hole in the structure.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
fs/ext4/crypto.c | 11 +++++------
fs/ext4/crypto_fname.c | 4 ++--
fs/ext4/crypto_key.c | 11 +++++------
fs/ext4/ext4_crypto.h | 1 -
4 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
index 1c34f0e..9969d05 100644
--- a/fs/ext4/crypto.c
+++ b/fs/ext4/crypto.c
@@ -137,14 +137,13 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
/* Allocate a new Crypto API context if we don't already have
* one or if it isn't the right mode. */
- BUG_ON(ci->ci_mode == EXT4_ENCRYPTION_MODE_INVALID);
- if (ctx->tfm && (ctx->mode != ci->ci_mode)) {
+ if (ctx->tfm && (ctx->mode != ci->ci_data_mode)) {
crypto_free_tfm(ctx->tfm);
ctx->tfm = NULL;
ctx->mode = EXT4_ENCRYPTION_MODE_INVALID;
}
if (!ctx->tfm) {
- switch (ci->ci_mode) {
+ switch (ci->ci_data_mode) {
case EXT4_ENCRYPTION_MODE_AES_256_XTS:
ctx->tfm = crypto_ablkcipher_tfm(
crypto_alloc_ablkcipher("xts(aes)", 0, 0));
@@ -162,9 +161,9 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
ctx->tfm = NULL;
goto out;
}
- ctx->mode = ci->ci_mode;
+ ctx->mode = ci->ci_data_mode;
}
- BUG_ON(ci->ci_size != ext4_encryption_key_size(ci->ci_mode));
+ BUG_ON(ci->ci_size != ext4_encryption_key_size(ci->ci_data_mode));
/* There shouldn't be a bounce page attached to the crypto
* context at this point. */
@@ -321,7 +320,7 @@ static int ext4_page_crypto(struct ext4_crypto_ctx *ctx,
int res = 0;
BUG_ON(!ctx->tfm);
- BUG_ON(ctx->mode != ei->i_crypt_info->ci_mode);
+ BUG_ON(ctx->mode != ei->i_crypt_info->ci_data_mode);
if (ctx->mode != EXT4_ENCRYPTION_MODE_AES_256_XTS) {
printk_ratelimited(KERN_ERR
diff --git a/fs/ext4/crypto_fname.c b/fs/ext4/crypto_fname.c
index 374d0e7..e63dd29 100644
--- a/fs/ext4/crypto_fname.c
+++ b/fs/ext4/crypto_fname.c
@@ -272,9 +272,9 @@ int ext4_setup_fname_crypto(struct inode *inode)
if (!ci || ci->ci_ctfm)
return 0;
- if (ci->ci_mode != EXT4_ENCRYPTION_MODE_AES_256_CTS) {
+ if (ci->ci_filename_mode != EXT4_ENCRYPTION_MODE_AES_256_CTS) {
printk_once(KERN_WARNING "ext4: unsupported key mode %d\n",
- ci->ci_mode);
+ ci->ci_filename_mode);
return -ENOKEY;
}
diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c
index d6abe46..858d7d6 100644
--- a/fs/ext4/crypto_key.c
+++ b/fs/ext4/crypto_key.c
@@ -152,14 +152,13 @@ int _ext4_get_encryption_info(struct inode *inode)
memcpy(crypt_info->ci_master_key, ctx.master_key_descriptor,
sizeof(crypt_info->ci_master_key));
if (S_ISREG(inode->i_mode))
- crypt_info->ci_mode = ctx.contents_encryption_mode;
+ crypt_info->ci_size =
+ ext4_encryption_key_size(crypt_info->ci_data_mode);
else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
- crypt_info->ci_mode = ctx.filenames_encryption_mode;
- else {
- printk(KERN_ERR "ext4 crypto: Unsupported inode type.\n");
+ crypt_info->ci_size =
+ ext4_encryption_key_size(crypt_info->ci_filename_mode);
+ else
BUG();
- }
- crypt_info->ci_size = ext4_encryption_key_size(crypt_info->ci_mode);
BUG_ON(!crypt_info->ci_size);
if (DUMMY_ENCRYPTION_ENABLED(sbi)) {
memset(crypt_info->ci_raw, 0x42, EXT4_AES_256_XTS_KEY_SIZE);
diff --git a/fs/ext4/ext4_crypto.h b/fs/ext4/ext4_crypto.h
index d29687c..69faf0e 100644
--- a/fs/ext4/ext4_crypto.h
+++ b/fs/ext4/ext4_crypto.h
@@ -74,7 +74,6 @@ struct ext4_encryption_key {
} __attribute__((__packed__));
struct ext4_crypt_info {
- unsigned char ci_mode;
unsigned char ci_size;
char ci_data_mode;
char ci_filename_mode;
--
2.3.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 4/5] ext4 crypto: shrink size of the ext4_crypto_ctx structure
2015-05-12 18:59 [PATCH 1/5] ext4: clean up superblock encryption mode fields Theodore Ts'o
2015-05-12 18:59 ` [PATCH 2/5] ext4 crypto: use slab caches Theodore Ts'o
2015-05-12 18:59 ` [PATCH 3/5] ext4 crypto: get rid of ci_mode from struct ext4_crypt_info Theodore Ts'o
@ 2015-05-12 18:59 ` Theodore Ts'o
2015-05-12 18:59 ` [PATCH 5/5] ext4 crypto: require CONFIG_CRYPTO_CTR if ext4 encryption is enabled Theodore Ts'o
3 siblings, 0 replies; 5+ messages in thread
From: Theodore Ts'o @ 2015-05-12 18:59 UTC (permalink / raw)
To: Ext4 Developers List; +Cc: jaegeuk, Theodore Ts'o
Some fields are only used when the crypto_ctx is being used on the
read path, some are only used on the write path, and some are only
used when the structure is on free list. Optimize memory use by using
a union.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
fs/ext4/crypto.c | 28 +++++++++++++---------------
fs/ext4/ext4_crypto.h | 21 ++++++++++++++-------
fs/ext4/page-io.c | 2 +-
fs/ext4/readpage.c | 10 +++++-----
4 files changed, 33 insertions(+), 28 deletions(-)
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
index 9969d05..1484b58 100644
--- a/fs/ext4/crypto.c
+++ b/fs/ext4/crypto.c
@@ -71,14 +71,14 @@ void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx)
{
unsigned long flags;
- if (ctx->bounce_page) {
+ if (ctx->flags & EXT4_WRITE_PATH_FL && ctx->w.bounce_page) {
if (ctx->flags & EXT4_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL)
- __free_page(ctx->bounce_page);
+ __free_page(ctx->w.bounce_page);
else
- mempool_free(ctx->bounce_page, ext4_bounce_page_pool);
- ctx->bounce_page = NULL;
+ mempool_free(ctx->w.bounce_page, ext4_bounce_page_pool);
+ ctx->w.bounce_page = NULL;
}
- ctx->control_page = NULL;
+ ctx->w.control_page = NULL;
if (ctx->flags & EXT4_CTX_REQUIRES_FREE_ENCRYPT_FL) {
if (ctx->tfm)
crypto_free_tfm(ctx->tfm);
@@ -134,6 +134,7 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
} else {
ctx->flags &= ~EXT4_CTX_REQUIRES_FREE_ENCRYPT_FL;
}
+ ctx->flags &= ~EXT4_WRITE_PATH_FL;
/* Allocate a new Crypto API context if we don't already have
* one or if it isn't the right mode. */
@@ -165,10 +166,6 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
}
BUG_ON(ci->ci_size != ext4_encryption_key_size(ci->ci_data_mode));
- /* There shouldn't be a bounce page attached to the crypto
- * context at this point. */
- BUG_ON(ctx->bounce_page);
-
out:
if (res) {
if (!IS_ERR_OR_NULL(ctx))
@@ -189,12 +186,12 @@ void ext4_exit_crypto(void)
struct ext4_crypto_ctx *pos, *n;
list_for_each_entry_safe(pos, n, &ext4_free_crypto_ctxs, free_list) {
- if (pos->bounce_page) {
+ if (pos->w.bounce_page) {
if (pos->flags &
EXT4_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL) {
- __free_page(pos->bounce_page);
+ __free_page(pos->w.bounce_page);
} else {
- mempool_free(pos->bounce_page,
+ mempool_free(pos->w.bounce_page,
ext4_bounce_page_pool);
}
}
@@ -425,8 +422,9 @@ struct page *ext4_encrypt(struct inode *inode,
} else {
ctx->flags |= EXT4_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL;
}
- ctx->bounce_page = ciphertext_page;
- ctx->control_page = plaintext_page;
+ ctx->flags |= EXT4_WRITE_PATH_FL;
+ ctx->w.bounce_page = ciphertext_page;
+ ctx->w.control_page = plaintext_page;
err = ext4_page_crypto(ctx, inode, EXT4_ENCRYPT, plaintext_page->index,
plaintext_page, ciphertext_page);
if (err) {
@@ -505,7 +503,7 @@ int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
} else {
ctx->flags |= EXT4_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL;
}
- ctx->bounce_page = ciphertext_page;
+ ctx->w.bounce_page = ciphertext_page;
while (len--) {
err = ext4_page_crypto(ctx, inode, EXT4_ENCRYPT, lblk,
diff --git a/fs/ext4/ext4_crypto.h b/fs/ext4/ext4_crypto.h
index 69faf0e..c5258f2 100644
--- a/fs/ext4/ext4_crypto.h
+++ b/fs/ext4/ext4_crypto.h
@@ -86,16 +86,23 @@ struct ext4_crypt_info {
#define EXT4_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
#define EXT4_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL 0x00000002
+#define EXT4_WRITE_PATH_FL 0x00000004
struct ext4_crypto_ctx {
struct crypto_tfm *tfm; /* Crypto API context */
- struct page *bounce_page; /* Ciphertext page on write path */
- struct page *control_page; /* Original page on write path */
- struct bio *bio; /* The bio for this context */
- struct work_struct work; /* Work queue for read complete path */
- struct list_head free_list; /* Free list */
- int flags; /* Flags */
- int mode; /* Encryption mode for tfm */
+ union {
+ struct {
+ struct page *bounce_page; /* Ciphertext page */
+ struct page *control_page; /* Original page */
+ } w;
+ struct {
+ struct bio *bio;
+ struct work_struct work;
+ } r;
+ struct list_head free_list; /* Free list */
+ };
+ char flags; /* Flags */
+ char mode; /* Encryption mode for tfm */
};
struct ext4_completion_result {
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 5765f88..79636e2 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -84,7 +84,7 @@ static void ext4_finish_bio(struct bio *bio)
/* The bounce data pages are unmapped. */
data_page = page;
ctx = (struct ext4_crypto_ctx *)page_private(data_page);
- page = ctx->control_page;
+ page = ctx->w.control_page;
}
#endif
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index 171b9ac..ec3ef93 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -54,8 +54,8 @@ static void completion_pages(struct work_struct *work)
{
#ifdef CONFIG_EXT4_FS_ENCRYPTION
struct ext4_crypto_ctx *ctx =
- container_of(work, struct ext4_crypto_ctx, work);
- struct bio *bio = ctx->bio;
+ container_of(work, struct ext4_crypto_ctx, r.work);
+ struct bio *bio = ctx->r.bio;
struct bio_vec *bv;
int i;
@@ -109,9 +109,9 @@ static void mpage_end_io(struct bio *bio, int err)
if (err) {
ext4_release_crypto_ctx(ctx);
} else {
- INIT_WORK(&ctx->work, completion_pages);
- ctx->bio = bio;
- queue_work(ext4_read_workqueue, &ctx->work);
+ INIT_WORK(&ctx->r.work, completion_pages);
+ ctx->r.bio = bio;
+ queue_work(ext4_read_workqueue, &ctx->r.work);
return;
}
}
--
2.3.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 5/5] ext4 crypto: require CONFIG_CRYPTO_CTR if ext4 encryption is enabled
2015-05-12 18:59 [PATCH 1/5] ext4: clean up superblock encryption mode fields Theodore Ts'o
` (2 preceding siblings ...)
2015-05-12 18:59 ` [PATCH 4/5] ext4 crypto: shrink size of the ext4_crypto_ctx structure Theodore Ts'o
@ 2015-05-12 18:59 ` Theodore Ts'o
3 siblings, 0 replies; 5+ messages in thread
From: Theodore Ts'o @ 2015-05-12 18:59 UTC (permalink / raw)
To: Ext4 Developers List; +Cc: jaegeuk, Theodore Ts'o
On arm64 this is apparently needed for CTS mode to function correctly.
Otherwise attempts to use CTS return ENOENT.
Change-Id: I732ea9a5157acc76de5b89edec195d0365f4ca63
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
fs/ext4/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index 024f228..bf8bc8a 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -72,6 +72,7 @@ config EXT4_ENCRYPTION
select CRYPTO_ECB
select CRYPTO_XTS
select CRYPTO_CTS
+ select CRYPTO_CTR
select CRYPTO_SHA256
select KEYS
select ENCRYPTED_KEYS
--
2.3.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-05-12 19:00 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-12 18:59 [PATCH 1/5] ext4: clean up superblock encryption mode fields Theodore Ts'o
2015-05-12 18:59 ` [PATCH 2/5] ext4 crypto: use slab caches Theodore Ts'o
2015-05-12 18:59 ` [PATCH 3/5] ext4 crypto: get rid of ci_mode from struct ext4_crypt_info Theodore Ts'o
2015-05-12 18:59 ` [PATCH 4/5] ext4 crypto: shrink size of the ext4_crypto_ctx structure Theodore Ts'o
2015-05-12 18:59 ` [PATCH 5/5] ext4 crypto: require CONFIG_CRYPTO_CTR if ext4 encryption is enabled Theodore Ts'o
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).