summaryrefslogtreecommitdiff
path: root/fs/f2fs/crypto.c
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2015-05-15 15:37:24 -0700
committerJaegeuk Kim <jaegeuk@kernel.org>2015-06-01 16:20:59 -0700
commitcfc4d971df411c68e27d903f749e0f6fffd9da40 (patch)
tree912d0fe1b1492daf8fe8ff3322092aba8554b4b5 /fs/f2fs/crypto.c
parentb9da898b05859ac4a0ea4460d798b6bb655790f3 (diff)
f2fs crypto: split f2fs_crypto_init/exit with two parts
This patch splits f2fs_crypto_init/exit with two parts: base initialization and memory allocation. Firstly, f2fs module declares the base encryption memory pointers. Then, allocating internal memories is done at the first encrypted inode access. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/crypto.c')
-rw-r--r--fs/f2fs/crypto.c90
1 files changed, 52 insertions, 38 deletions
diff --git a/fs/f2fs/crypto.c b/fs/f2fs/crypto.c
index 7f1ee9e8fc70..c6d11229aee4 100644
--- a/fs/f2fs/crypto.c
+++ b/fs/f2fs/crypto.c
@@ -63,7 +63,7 @@ static mempool_t *f2fs_bounce_page_pool;
static LIST_HEAD(f2fs_free_crypto_ctxs);
static DEFINE_SPINLOCK(f2fs_crypto_ctx_lock);
-struct workqueue_struct *f2fs_read_workqueue;
+static struct workqueue_struct *f2fs_read_workqueue;
static DEFINE_MUTEX(crypto_init);
static struct kmem_cache *f2fs_crypto_ctx_cachep;
@@ -225,10 +225,7 @@ void f2fs_end_io_crypto_work(struct f2fs_crypto_ctx *ctx, struct bio *bio)
queue_work(f2fs_read_workqueue, &ctx->r.work);
}
-/**
- * f2fs_exit_crypto() - Shutdown the f2fs encryption system
- */
-void f2fs_exit_crypto(void)
+static void f2fs_crypto_destroy(void)
{
struct f2fs_crypto_ctx *pos, *n;
@@ -241,73 +238,90 @@ void f2fs_exit_crypto(void)
if (f2fs_bounce_page_pool)
mempool_destroy(f2fs_bounce_page_pool);
f2fs_bounce_page_pool = NULL;
- if (f2fs_read_workqueue)
- destroy_workqueue(f2fs_read_workqueue);
- f2fs_read_workqueue = NULL;
- if (f2fs_crypto_ctx_cachep)
- kmem_cache_destroy(f2fs_crypto_ctx_cachep);
- f2fs_crypto_ctx_cachep = NULL;
- if (f2fs_crypt_info_cachep)
- kmem_cache_destroy(f2fs_crypt_info_cachep);
- f2fs_crypt_info_cachep = NULL;
}
/**
- * f2fs_init_crypto() - Set up for f2fs encryption.
+ * f2fs_crypto_initialize() - Set up for f2fs encryption.
*
* We only call this when we start accessing encrypted files, since it
* results in memory getting allocated that wouldn't otherwise be used.
*
* Return: Zero on success, non-zero otherwise.
*/
-int f2fs_init_crypto(void)
+int f2fs_crypto_initialize(void)
{
int i, res = -ENOMEM;
+ if (f2fs_bounce_page_pool)
+ return 0;
+
mutex_lock(&crypto_init);
- if (f2fs_read_workqueue)
+ if (f2fs_bounce_page_pool)
goto already_initialized;
- f2fs_read_workqueue = alloc_workqueue("f2fs_crypto", WQ_HIGHPRI, 0);
- if (!f2fs_read_workqueue)
- goto fail;
-
- f2fs_crypto_ctx_cachep = KMEM_CACHE(f2fs_crypto_ctx,
- SLAB_RECLAIM_ACCOUNT);
- if (!f2fs_crypto_ctx_cachep)
- goto fail;
-
- f2fs_crypt_info_cachep = KMEM_CACHE(f2fs_crypt_info,
- SLAB_RECLAIM_ACCOUNT);
- if (!f2fs_crypt_info_cachep)
- goto fail;
-
for (i = 0; i < num_prealloc_crypto_ctxs; i++) {
struct f2fs_crypto_ctx *ctx;
ctx = kmem_cache_zalloc(f2fs_crypto_ctx_cachep, GFP_KERNEL);
- if (!ctx) {
- res = -ENOMEM;
+ if (!ctx)
goto fail;
- }
list_add(&ctx->free_list, &f2fs_free_crypto_ctxs);
}
+ /* must be allocated at the last step to avoid race condition above */
f2fs_bounce_page_pool =
mempool_create_page_pool(num_prealloc_crypto_pages, 0);
- if (!f2fs_bounce_page_pool) {
- res = -ENOMEM;
+ if (!f2fs_bounce_page_pool)
goto fail;
- }
+
already_initialized:
mutex_unlock(&crypto_init);
return 0;
fail:
- f2fs_exit_crypto();
+ f2fs_crypto_destroy();
mutex_unlock(&crypto_init);
return res;
}
+/**
+ * f2fs_exit_crypto() - Shutdown the f2fs encryption system
+ */
+void f2fs_exit_crypto(void)
+{
+ f2fs_crypto_destroy();
+
+ if (f2fs_read_workqueue)
+ destroy_workqueue(f2fs_read_workqueue);
+ if (f2fs_crypto_ctx_cachep)
+ kmem_cache_destroy(f2fs_crypto_ctx_cachep);
+ if (f2fs_crypt_info_cachep)
+ kmem_cache_destroy(f2fs_crypt_info_cachep);
+}
+
+int __init f2fs_init_crypto(void)
+{
+ int res = -ENOMEM;
+
+ f2fs_read_workqueue = alloc_workqueue("f2fs_crypto", WQ_HIGHPRI, 0);
+ if (!f2fs_read_workqueue)
+ goto fail;
+
+ f2fs_crypto_ctx_cachep = KMEM_CACHE(f2fs_crypto_ctx,
+ SLAB_RECLAIM_ACCOUNT);
+ if (!f2fs_crypto_ctx_cachep)
+ goto fail;
+
+ f2fs_crypt_info_cachep = KMEM_CACHE(f2fs_crypt_info,
+ SLAB_RECLAIM_ACCOUNT);
+ if (!f2fs_crypt_info_cachep)
+ goto fail;
+
+ return 0;
+fail:
+ f2fs_exit_crypto();
+ return res;
+}
+
void f2fs_restore_and_release_control_page(struct page **page)
{
struct f2fs_crypto_ctx *ctx;