summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/f2fs/crypto.c40
-rw-r--r--fs/f2fs/f2fs_crypto.h21
-rw-r--r--fs/f2fs/segment.c2
3 files changed, 33 insertions, 30 deletions
diff --git a/fs/f2fs/crypto.c b/fs/f2fs/crypto.c
index e4058b92c774..6d38da11918d 100644
--- a/fs/f2fs/crypto.c
+++ b/fs/f2fs/crypto.c
@@ -82,14 +82,14 @@ void f2fs_release_crypto_ctx(struct f2fs_crypto_ctx *ctx)
{
unsigned long flags;
- if (ctx->bounce_page) {
+ if (ctx->flags & F2FS_WRITE_PATH_FL && ctx->w.bounce_page) {
if (ctx->flags & F2FS_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL)
- __free_page(ctx->bounce_page);
+ __free_page(ctx->w.bounce_page);
else
- mempool_free(ctx->bounce_page, f2fs_bounce_page_pool);
- ctx->bounce_page = NULL;
+ mempool_free(ctx->w.bounce_page, f2fs_bounce_page_pool);
+ ctx->w.bounce_page = NULL;
}
- ctx->control_page = NULL;
+ ctx->w.control_page = NULL;
if (ctx->flags & F2FS_CTX_REQUIRES_FREE_ENCRYPT_FL) {
if (ctx->tfm)
crypto_free_tfm(ctx->tfm);
@@ -146,6 +146,7 @@ struct f2fs_crypto_ctx *f2fs_get_crypto_ctx(struct inode *inode)
} else {
ctx->flags &= ~F2FS_CTX_REQUIRES_FREE_ENCRYPT_FL;
}
+ ctx->flags &= ~F2FS_WRITE_PATH_FL;
/*
* Allocate a new Crypto API context if we don't already have
@@ -181,12 +182,6 @@ struct f2fs_crypto_ctx *f2fs_get_crypto_ctx(struct inode *inode)
}
BUG_ON(ci->ci_size != f2fs_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))
@@ -203,8 +198,8 @@ out:
static void completion_pages(struct work_struct *work)
{
struct f2fs_crypto_ctx *ctx =
- container_of(work, struct f2fs_crypto_ctx, work);
- struct bio *bio = ctx->bio;
+ container_of(work, struct f2fs_crypto_ctx, r.work);
+ struct bio *bio = ctx->r.bio;
struct bio_vec *bv;
int i;
@@ -225,9 +220,9 @@ static void completion_pages(struct work_struct *work)
void f2fs_end_io_crypto_work(struct f2fs_crypto_ctx *ctx, struct bio *bio)
{
- INIT_WORK(&ctx->work, completion_pages);
- ctx->bio = bio;
- queue_work(f2fs_read_workqueue, &ctx->work);
+ INIT_WORK(&ctx->r.work, completion_pages);
+ ctx->r.bio = bio;
+ queue_work(f2fs_read_workqueue, &ctx->r.work);
}
/**
@@ -238,12 +233,12 @@ void f2fs_exit_crypto(void)
struct f2fs_crypto_ctx *pos, *n;
list_for_each_entry_safe(pos, n, &f2fs_free_crypto_ctxs, free_list) {
- if (pos->bounce_page) {
+ if (pos->w.bounce_page) {
if (pos->flags &
F2FS_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,
f2fs_bounce_page_pool);
}
if (pos->tfm)
@@ -335,7 +330,7 @@ void f2fs_restore_and_release_control_page(struct page **page)
ctx = (struct f2fs_crypto_ctx *)page_private(bounce_page);
/* restore control page */
- *page = ctx->control_page;
+ *page = ctx->w.control_page;
f2fs_restore_control_page(bounce_page);
}
@@ -492,8 +487,9 @@ struct page *f2fs_encrypt(struct inode *inode,
} else {
ctx->flags |= F2FS_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL;
}
- ctx->bounce_page = ciphertext_page;
- ctx->control_page = plaintext_page;
+ ctx->flags |= F2FS_WRITE_PATH_FL;
+ ctx->w.bounce_page = ciphertext_page;
+ ctx->w.control_page = plaintext_page;
err = f2fs_page_crypto(ctx, inode, F2FS_ENCRYPT, plaintext_page->index,
plaintext_page, ciphertext_page);
if (err) {
diff --git a/fs/f2fs/f2fs_crypto.h b/fs/f2fs/f2fs_crypto.h
index 58682d2830e9..e33cec9c3f36 100644
--- a/fs/f2fs/f2fs_crypto.h
+++ b/fs/f2fs/f2fs_crypto.h
@@ -87,16 +87,23 @@ struct f2fs_crypt_info {
#define F2FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
#define F2FS_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL 0x00000002
+#define F2FS_WRITE_PATH_FL 0x00000004
struct f2fs_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 f2fs_completion_result {
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 190e0558de39..e0821d2c39e4 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1382,7 +1382,7 @@ static inline bool is_merged_page(struct f2fs_sb_info *sbi,
/* encrypted page */
ctx = (struct f2fs_crypto_ctx *)page_private(
bvec->bv_page);
- target = ctx->control_page;
+ target = ctx->w.control_page;
}
if (page == target) {