]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
fscrypt: handle blocksize < PAGE_SIZE in fscrypt_zeroout_range()
authorEric Biggers <ebiggers@google.com>
Mon, 20 May 2019 16:29:45 +0000 (09:29 -0700)
committerEric Biggers <ebiggers@google.com>
Tue, 28 May 2019 17:27:53 +0000 (10:27 -0700)
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: Chandan Rajendra <chandan@linux.ibm.com>
Signed-off-by: Eric Biggers <ebiggers@google.com>
fs/crypto/bio.c

index 92b2d5da5d8e1b5cb958d0c58e88b2a2901f6c68..f9111ffa12ffd3d8bddb069f7d30a0001ae5d433 100644 (file)
@@ -72,12 +72,12 @@ EXPORT_SYMBOL(fscrypt_enqueue_decrypt_bio);
 int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
                                sector_t pblk, unsigned int len)
 {
+       const unsigned int blockbits = inode->i_blkbits;
+       const unsigned int blocksize = 1 << blockbits;
        struct page *ciphertext_page;
        struct bio *bio;
        int ret, err = 0;
 
-       BUG_ON(inode->i_sb->s_blocksize != PAGE_SIZE);
-
        ciphertext_page = fscrypt_alloc_bounce_page(GFP_NOWAIT);
        if (!ciphertext_page)
                return -ENOMEM;
@@ -85,7 +85,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
        while (len--) {
                err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk,
                                          ZERO_PAGE(0), ciphertext_page,
-                                         PAGE_SIZE, 0, GFP_NOFS);
+                                         blocksize, 0, GFP_NOFS);
                if (err)
                        goto errout;
 
@@ -95,14 +95,11 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
                        goto errout;
                }
                bio_set_dev(bio, inode->i_sb->s_bdev);
-               bio->bi_iter.bi_sector =
-                       pblk << (inode->i_sb->s_blocksize_bits - 9);
+               bio->bi_iter.bi_sector = pblk << (blockbits - 9);
                bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
-               ret = bio_add_page(bio, ciphertext_page,
-                                       inode->i_sb->s_blocksize, 0);
-               if (ret != inode->i_sb->s_blocksize) {
+               ret = bio_add_page(bio, ciphertext_page, blocksize, 0);
+               if (WARN_ON(ret != blocksize)) {
                        /* should never happen! */
-                       WARN_ON(1);
                        bio_put(bio);
                        err = -EIO;
                        goto errout;