Commit 930d4539 authored by Eric Biggers's avatar Eric Biggers

fscrypt: handle blocksize < PAGE_SIZE in fscrypt_zeroout_range()

Adjust fscrypt_zeroout_range() to encrypt a block at a time rather than
a page at a time, so that it works when blocksize < PAGE_SIZE.

This isn't optimized for performance, but then again this function
already wasn't optimized for performance.  As a future optimization, we
could submit much larger bios here.

This is in preparation for allowing encryption on ext4 filesystems with
blocksize != PAGE_SIZE.

This is based on work by Chandan Rajendra.
Reviewed-by: default avatarChandan Rajendra <chandan@linux.ibm.com>
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
parent 53bc1d85
...@@ -72,12 +72,12 @@ EXPORT_SYMBOL(fscrypt_enqueue_decrypt_bio); ...@@ -72,12 +72,12 @@ EXPORT_SYMBOL(fscrypt_enqueue_decrypt_bio);
int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
sector_t pblk, unsigned int len) sector_t pblk, unsigned int len)
{ {
const unsigned int blockbits = inode->i_blkbits;
const unsigned int blocksize = 1 << blockbits;
struct page *ciphertext_page; struct page *ciphertext_page;
struct bio *bio; struct bio *bio;
int ret, err = 0; int ret, err = 0;
BUG_ON(inode->i_sb->s_blocksize != PAGE_SIZE);
ciphertext_page = fscrypt_alloc_bounce_page(GFP_NOWAIT); ciphertext_page = fscrypt_alloc_bounce_page(GFP_NOWAIT);
if (!ciphertext_page) if (!ciphertext_page)
return -ENOMEM; return -ENOMEM;
...@@ -85,7 +85,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, ...@@ -85,7 +85,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
while (len--) { while (len--) {
err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk, err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk,
ZERO_PAGE(0), ciphertext_page, ZERO_PAGE(0), ciphertext_page,
PAGE_SIZE, 0, GFP_NOFS); blocksize, 0, GFP_NOFS);
if (err) if (err)
goto errout; goto errout;
...@@ -95,14 +95,11 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, ...@@ -95,14 +95,11 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
goto errout; goto errout;
} }
bio_set_dev(bio, inode->i_sb->s_bdev); bio_set_dev(bio, inode->i_sb->s_bdev);
bio->bi_iter.bi_sector = bio->bi_iter.bi_sector = pblk << (blockbits - 9);
pblk << (inode->i_sb->s_blocksize_bits - 9);
bio_set_op_attrs(bio, REQ_OP_WRITE, 0); bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
ret = bio_add_page(bio, ciphertext_page, ret = bio_add_page(bio, ciphertext_page, blocksize, 0);
inode->i_sb->s_blocksize, 0); if (WARN_ON(ret != blocksize)) {
if (ret != inode->i_sb->s_blocksize) {
/* should never happen! */ /* should never happen! */
WARN_ON(1);
bio_put(bio); bio_put(bio);
err = -EIO; err = -EIO;
goto errout; goto errout;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment