Re: [f2fs-dev] [PATCH 06/13] fscrypt: support encrypting multiple filesystem blocks per page

2019-05-06 Thread Chandan Rajendra
On Thursday, May 2, 2019 4:15:08 AM IST Eric Biggers wrote:
> From: Eric Biggers 
> 
> Rename fscrypt_encrypt_page() to fscrypt_encrypt_pagecache_blocks() and
> redefine its behavior to encrypt all filesystem blocks from the given
> region of the given page, rather than assuming that the region consists
> of just one filesystem block.  Also remove the 'inode' and 'lblk_num'
> parameters, since they can be retrieved from the page as it's already
> assumed to be a pagecache page.
> 
> This is in preparation for allowing encryption on ext4 filesystems with
> blocksize != PAGE_SIZE.
> 
> This is based on work by Chandan Rajendra.

Looks good to me,

Reviewed-by: Chandan Rajendra 

-- 
chandan





___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 06/13] fscrypt: support encrypting multiple filesystem blocks per page

2019-05-01 Thread Eric Biggers
From: Eric Biggers 

Rename fscrypt_encrypt_page() to fscrypt_encrypt_pagecache_blocks() and
redefine its behavior to encrypt all filesystem blocks from the given
region of the given page, rather than assuming that the region consists
of just one filesystem block.  Also remove the 'inode' and 'lblk_num'
parameters, since they can be retrieved from the page as it's already
assumed to be a pagecache page.

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

This is based on work by Chandan Rajendra.

Signed-off-by: Eric Biggers 
---
 fs/crypto/crypto.c  | 67 -
 fs/ext4/page-io.c   |  4 +--
 fs/f2fs/data.c  |  5 +--
 include/linux/fscrypt.h | 17 ++-
 4 files changed, 53 insertions(+), 40 deletions(-)

diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index e978541e2ec19..7bdb985126d97 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -121,8 +121,8 @@ struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags)
 /**
  * fscrypt_free_bounce_page() - free a ciphertext bounce page
  *
- * Free a bounce page that was allocated by fscrypt_encrypt_page(), or by
- * fscrypt_alloc_bounce_page() directly.
+ * Free a bounce page that was allocated by fscrypt_encrypt_pagecache_blocks(),
+ * or by fscrypt_alloc_bounce_page() directly.
  */
 void fscrypt_free_bounce_page(struct page *bounce_page)
 {
@@ -197,52 +197,63 @@ int fscrypt_crypt_block(const struct inode *inode, 
fscrypt_direction_t rw,
 }
 
 /**
- * fscypt_encrypt_page() - Encrypts a page
- * @inode: The inode for which the encryption should take place
- * @page:  The page to encrypt. Must be locked.
- * @len:   Length of data to encrypt in @page and encrypted
- * data in returned page.
- * @offs:  Offset of data within @page and returned
- * page holding encrypted data.
- * @lblk_num:  Logical block number. This must be unique for multiple
- * calls with same inode, except when overwriting
- * previously written data.
- * @gfp_flags: The gfp flag for memory allocation
+ * fscrypt_encrypt_pagecache_blocks() - Encrypt filesystem blocks from a 
pagecache page
+ * @page:  The locked pagecache page containing the block(s) to encrypt
+ * @len:   Total size of the block(s) to encrypt.  Must be a nonzero
+ * multiple of the filesystem's block size.
+ * @offs:  Byte offset within @page of the first block to encrypt.  Must be
+ * a multiple of the filesystem's block size.
+ * @gfp_flags: Memory allocation flags
+ *
+ * A new bounce page is allocated, and the specified block(s) are encrypted 
into
+ * it.  In the bounce page, the ciphertext block(s) will be located at the same
+ * offsets at which the plaintext block(s) were located in the source page; any
+ * other parts of the bounce page will be left uninitialized.  However, 
normally
+ * blocksize == PAGE_SIZE and the whole page is encrypted at once.
  *
- * Encrypts @page.  A bounce page is allocated, the data is encrypted into the
- * bounce page, and the bounce page is returned.  The caller is responsible for
- * calling fscrypt_free_bounce_page().
+ * This is for use by the filesystem's ->writepages() method.
  *
- * Return: A page containing the encrypted data on success; else an ERR_PTR()
+ * Return: the new encrypted bounce page on success; an ERR_PTR() on failure
  */
-struct page *fscrypt_encrypt_page(const struct inode *inode,
-   struct page *page,
-   unsigned int len,
-   unsigned int offs,
-   u64 lblk_num, gfp_t gfp_flags)
+struct page *fscrypt_encrypt_pagecache_blocks(struct page *page,
+ unsigned int len,
+ unsigned int offs,
+ gfp_t gfp_flags)
 
 {
+   const struct inode *inode = page->mapping->host;
+   const unsigned int blockbits = inode->i_blkbits;
+   const unsigned int blocksize = 1 << blockbits;
struct page *ciphertext_page;
+   u64 lblk_num = ((u64)page->index << (PAGE_SHIFT - blockbits)) +
+  (offs >> blockbits);
+   unsigned int i;
int err;
 
if (WARN_ON_ONCE(!PageLocked(page)))
return ERR_PTR(-EINVAL);
 
+   if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize)))
+   return ERR_PTR(-EINVAL);
+
ciphertext_page = fscrypt_alloc_bounce_page(gfp_flags);
if (!ciphertext_page)
return ERR_PTR(-ENOMEM);
 
-   err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page,
- ciphertext_page, len, offs, gfp_flags);
-   if (err) {
-   fscrypt_free_bounce_page(ciphertext_page);
-   return ERR_PTR(err);
+   for (i = offs; i < offs + len; i += blocksize,