diff options
Diffstat (limited to 'fs/ext4/crypto.c')
-rw-r--r-- | fs/ext4/crypto.c | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c index edc053a81914..db9ae6e18154 100644 --- a/fs/ext4/crypto.c +++ b/fs/ext4/crypto.c | |||
@@ -91,7 +91,8 @@ void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx) | |||
91 | * Return: An allocated and initialized encryption context on success; error | 91 | * Return: An allocated and initialized encryption context on success; error |
92 | * value or NULL otherwise. | 92 | * value or NULL otherwise. |
93 | */ | 93 | */ |
94 | struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode) | 94 | struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode, |
95 | gfp_t gfp_flags) | ||
95 | { | 96 | { |
96 | struct ext4_crypto_ctx *ctx = NULL; | 97 | struct ext4_crypto_ctx *ctx = NULL; |
97 | int res = 0; | 98 | int res = 0; |
@@ -118,7 +119,7 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode) | |||
118 | list_del(&ctx->free_list); | 119 | list_del(&ctx->free_list); |
119 | spin_unlock_irqrestore(&ext4_crypto_ctx_lock, flags); | 120 | spin_unlock_irqrestore(&ext4_crypto_ctx_lock, flags); |
120 | if (!ctx) { | 121 | if (!ctx) { |
121 | ctx = kmem_cache_zalloc(ext4_crypto_ctx_cachep, GFP_NOFS); | 122 | ctx = kmem_cache_zalloc(ext4_crypto_ctx_cachep, gfp_flags); |
122 | if (!ctx) { | 123 | if (!ctx) { |
123 | res = -ENOMEM; | 124 | res = -ENOMEM; |
124 | goto out; | 125 | goto out; |
@@ -255,7 +256,8 @@ static int ext4_page_crypto(struct inode *inode, | |||
255 | ext4_direction_t rw, | 256 | ext4_direction_t rw, |
256 | pgoff_t index, | 257 | pgoff_t index, |
257 | struct page *src_page, | 258 | struct page *src_page, |
258 | struct page *dest_page) | 259 | struct page *dest_page, |
260 | gfp_t gfp_flags) | ||
259 | 261 | ||
260 | { | 262 | { |
261 | u8 xts_tweak[EXT4_XTS_TWEAK_SIZE]; | 263 | u8 xts_tweak[EXT4_XTS_TWEAK_SIZE]; |
@@ -266,7 +268,7 @@ static int ext4_page_crypto(struct inode *inode, | |||
266 | struct crypto_skcipher *tfm = ci->ci_ctfm; | 268 | struct crypto_skcipher *tfm = ci->ci_ctfm; |
267 | int res = 0; | 269 | int res = 0; |
268 | 270 | ||
269 | req = skcipher_request_alloc(tfm, GFP_NOFS); | 271 | req = skcipher_request_alloc(tfm, gfp_flags); |
270 | if (!req) { | 272 | if (!req) { |
271 | printk_ratelimited(KERN_ERR | 273 | printk_ratelimited(KERN_ERR |
272 | "%s: crypto_request_alloc() failed\n", | 274 | "%s: crypto_request_alloc() failed\n", |
@@ -283,10 +285,10 @@ static int ext4_page_crypto(struct inode *inode, | |||
283 | EXT4_XTS_TWEAK_SIZE - sizeof(index)); | 285 | EXT4_XTS_TWEAK_SIZE - sizeof(index)); |
284 | 286 | ||
285 | sg_init_table(&dst, 1); | 287 | sg_init_table(&dst, 1); |
286 | sg_set_page(&dst, dest_page, PAGE_CACHE_SIZE, 0); | 288 | sg_set_page(&dst, dest_page, PAGE_SIZE, 0); |
287 | sg_init_table(&src, 1); | 289 | sg_init_table(&src, 1); |
288 | sg_set_page(&src, src_page, PAGE_CACHE_SIZE, 0); | 290 | sg_set_page(&src, src_page, PAGE_SIZE, 0); |
289 | skcipher_request_set_crypt(req, &src, &dst, PAGE_CACHE_SIZE, | 291 | skcipher_request_set_crypt(req, &src, &dst, PAGE_SIZE, |
290 | xts_tweak); | 292 | xts_tweak); |
291 | if (rw == EXT4_DECRYPT) | 293 | if (rw == EXT4_DECRYPT) |
292 | res = crypto_skcipher_decrypt(req); | 294 | res = crypto_skcipher_decrypt(req); |
@@ -307,9 +309,10 @@ static int ext4_page_crypto(struct inode *inode, | |||
307 | return 0; | 309 | return 0; |
308 | } | 310 | } |
309 | 311 | ||
310 | static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx) | 312 | static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx, |
313 | gfp_t gfp_flags) | ||
311 | { | 314 | { |
312 | ctx->w.bounce_page = mempool_alloc(ext4_bounce_page_pool, GFP_NOWAIT); | 315 | ctx->w.bounce_page = mempool_alloc(ext4_bounce_page_pool, gfp_flags); |
313 | if (ctx->w.bounce_page == NULL) | 316 | if (ctx->w.bounce_page == NULL) |
314 | return ERR_PTR(-ENOMEM); | 317 | return ERR_PTR(-ENOMEM); |
315 | ctx->flags |= EXT4_WRITE_PATH_FL; | 318 | ctx->flags |= EXT4_WRITE_PATH_FL; |
@@ -332,7 +335,8 @@ static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx) | |||
332 | * error value or NULL. | 335 | * error value or NULL. |
333 | */ | 336 | */ |
334 | struct page *ext4_encrypt(struct inode *inode, | 337 | struct page *ext4_encrypt(struct inode *inode, |
335 | struct page *plaintext_page) | 338 | struct page *plaintext_page, |
339 | gfp_t gfp_flags) | ||
336 | { | 340 | { |
337 | struct ext4_crypto_ctx *ctx; | 341 | struct ext4_crypto_ctx *ctx; |
338 | struct page *ciphertext_page = NULL; | 342 | struct page *ciphertext_page = NULL; |
@@ -340,17 +344,17 @@ struct page *ext4_encrypt(struct inode *inode, | |||
340 | 344 | ||
341 | BUG_ON(!PageLocked(plaintext_page)); | 345 | BUG_ON(!PageLocked(plaintext_page)); |
342 | 346 | ||
343 | ctx = ext4_get_crypto_ctx(inode); | 347 | ctx = ext4_get_crypto_ctx(inode, gfp_flags); |
344 | if (IS_ERR(ctx)) | 348 | if (IS_ERR(ctx)) |
345 | return (struct page *) ctx; | 349 | return (struct page *) ctx; |
346 | 350 | ||
347 | /* The encryption operation will require a bounce page. */ | 351 | /* The encryption operation will require a bounce page. */ |
348 | ciphertext_page = alloc_bounce_page(ctx); | 352 | ciphertext_page = alloc_bounce_page(ctx, gfp_flags); |
349 | if (IS_ERR(ciphertext_page)) | 353 | if (IS_ERR(ciphertext_page)) |
350 | goto errout; | 354 | goto errout; |
351 | ctx->w.control_page = plaintext_page; | 355 | ctx->w.control_page = plaintext_page; |
352 | err = ext4_page_crypto(inode, EXT4_ENCRYPT, plaintext_page->index, | 356 | err = ext4_page_crypto(inode, EXT4_ENCRYPT, plaintext_page->index, |
353 | plaintext_page, ciphertext_page); | 357 | plaintext_page, ciphertext_page, gfp_flags); |
354 | if (err) { | 358 | if (err) { |
355 | ciphertext_page = ERR_PTR(err); | 359 | ciphertext_page = ERR_PTR(err); |
356 | errout: | 360 | errout: |
@@ -378,8 +382,8 @@ int ext4_decrypt(struct page *page) | |||
378 | { | 382 | { |
379 | BUG_ON(!PageLocked(page)); | 383 | BUG_ON(!PageLocked(page)); |
380 | 384 | ||
381 | return ext4_page_crypto(page->mapping->host, | 385 | return ext4_page_crypto(page->mapping->host, EXT4_DECRYPT, |
382 | EXT4_DECRYPT, page->index, page, page); | 386 | page->index, page, page, GFP_NOFS); |
383 | } | 387 | } |
384 | 388 | ||
385 | int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk, | 389 | int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk, |
@@ -396,13 +400,13 @@ int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk, | |||
396 | (unsigned long) inode->i_ino, lblk, len); | 400 | (unsigned long) inode->i_ino, lblk, len); |
397 | #endif | 401 | #endif |
398 | 402 | ||
399 | BUG_ON(inode->i_sb->s_blocksize != PAGE_CACHE_SIZE); | 403 | BUG_ON(inode->i_sb->s_blocksize != PAGE_SIZE); |
400 | 404 | ||
401 | ctx = ext4_get_crypto_ctx(inode); | 405 | ctx = ext4_get_crypto_ctx(inode, GFP_NOFS); |
402 | if (IS_ERR(ctx)) | 406 | if (IS_ERR(ctx)) |
403 | return PTR_ERR(ctx); | 407 | return PTR_ERR(ctx); |
404 | 408 | ||
405 | ciphertext_page = alloc_bounce_page(ctx); | 409 | ciphertext_page = alloc_bounce_page(ctx, GFP_NOWAIT); |
406 | if (IS_ERR(ciphertext_page)) { | 410 | if (IS_ERR(ciphertext_page)) { |
407 | err = PTR_ERR(ciphertext_page); | 411 | err = PTR_ERR(ciphertext_page); |
408 | goto errout; | 412 | goto errout; |
@@ -410,11 +414,12 @@ int ext4_encrypted_zeroout(struct inode *inode, ext4_lblk_t lblk, | |||
410 | 414 | ||
411 | while (len--) { | 415 | while (len--) { |
412 | err = ext4_page_crypto(inode, EXT4_ENCRYPT, lblk, | 416 | err = ext4_page_crypto(inode, EXT4_ENCRYPT, lblk, |
413 | ZERO_PAGE(0), ciphertext_page); | 417 | ZERO_PAGE(0), ciphertext_page, |
418 | GFP_NOFS); | ||
414 | if (err) | 419 | if (err) |
415 | goto errout; | 420 | goto errout; |
416 | 421 | ||
417 | bio = bio_alloc(GFP_KERNEL, 1); | 422 | bio = bio_alloc(GFP_NOWAIT, 1); |
418 | if (!bio) { | 423 | if (!bio) { |
419 | err = -ENOMEM; | 424 | err = -ENOMEM; |
420 | goto errout; | 425 | goto errout; |
@@ -473,13 +478,16 @@ uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size) | |||
473 | */ | 478 | */ |
474 | static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags) | 479 | static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags) |
475 | { | 480 | { |
476 | struct inode *dir = d_inode(dentry->d_parent); | 481 | struct dentry *dir; |
477 | struct ext4_crypt_info *ci = EXT4_I(dir)->i_crypt_info; | 482 | struct ext4_crypt_info *ci; |
478 | int dir_has_key, cached_with_key; | 483 | int dir_has_key, cached_with_key; |
479 | 484 | ||
480 | if (!ext4_encrypted_inode(dir)) | 485 | dir = dget_parent(dentry); |
486 | if (!ext4_encrypted_inode(d_inode(dir))) { | ||
487 | dput(dir); | ||
481 | return 0; | 488 | return 0; |
482 | 489 | } | |
490 | ci = EXT4_I(d_inode(dir))->i_crypt_info; | ||
483 | if (ci && ci->ci_keyring_key && | 491 | if (ci && ci->ci_keyring_key && |
484 | (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) | | 492 | (ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) | |
485 | (1 << KEY_FLAG_REVOKED) | | 493 | (1 << KEY_FLAG_REVOKED) | |
@@ -489,6 +497,7 @@ static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags) | |||
489 | /* this should eventually be an flag in d_flags */ | 497 | /* this should eventually be an flag in d_flags */ |
490 | cached_with_key = dentry->d_fsdata != NULL; | 498 | cached_with_key = dentry->d_fsdata != NULL; |
491 | dir_has_key = (ci != NULL); | 499 | dir_has_key = (ci != NULL); |
500 | dput(dir); | ||
492 | 501 | ||
493 | /* | 502 | /* |
494 | * If the dentry was cached without the key, and it is a | 503 | * If the dentry was cached without the key, and it is a |