[PATCH 2/7] ecryptfs: use a folio and a buffer in crypt_extent()

From: Tal Zussman

Date: Wed Oct 14 2026 - 21:37:01 EST


crypt_extent() currently takes its source and destination as pages, so
ecryptfs_encrypt_page() and ecryptfs_decrypt_page() have to pass
folio_page() of the folio they are given, and the ciphertext buffer in
ecryptfs_encrypt_page() is allocated as a page to match.

The source is a page cache folio, so pass it as one and set up its
scatterlist with sg_set_folio(). The destination is not: it is a
temporary buffer that is only needed to be able to write to the lower
file. There is no reason for it to be a page or folio. Convert it to a
buffer instead, with NULL meaning the operation is done in place on
the folio, which is what ecryptfs_decrypt_page() does.
ecryptfs_encrypt_page() can then kmalloc() it and write it out without
mapping it. Allocate the buffer with GFP_KERNEL. There was no reason to
use GFP_USER as it had previously been doing.

Signed-off-by: Tal Zussman <tz2294@xxxxxxxxxxxx>
---
fs/ecryptfs/crypto.c | 47 ++++++++++++++++++++---------------------------
1 file changed, 20 insertions(+), 27 deletions(-)

diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index e67119b6029c..9b8b0c5a81cd 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -271,8 +271,9 @@ static loff_t lower_offset_for_page(struct ecryptfs_crypt_stat *crypt_stat,
* crypt_extent
* @crypt_stat: crypt_stat containing cryptographic context for the
* encryption operation
- * @dst_page: The page to write the result into
- * @src_page: The page to read from
+ * @folio: The folio to read from
+ * @dst: The buffer to write the result into, or NULL to crypt the
+ * folio in place
* @page_index: The offset in the file (in units of PAGE_SIZE)
* @extent_offset: Page extent offset for use in generating IV
* @op: ENCRYPT or DECRYPT to indicate the desired operation
@@ -282,14 +283,12 @@ static loff_t lower_offset_for_page(struct ecryptfs_crypt_stat *crypt_stat,
* Return zero on success; non-zero otherwise
*/
static int crypt_extent(struct ecryptfs_crypt_stat *crypt_stat,
- struct page *dst_page,
- struct page *src_page,
- pgoff_t page_index,
+ struct folio *folio, void *dst, pgoff_t page_index,
unsigned long extent_offset, int op)
{
loff_t extent_base;
char extent_iv[ECRYPTFS_MAX_IV_BYTES];
- struct scatterlist src_sg, dst_sg;
+ struct scatterlist src_sg, dst_sg, *dst_sgp = &src_sg;
size_t extent_size = crypt_stat->extent_size;
int rc;

@@ -297,14 +296,15 @@ static int crypt_extent(struct ecryptfs_crypt_stat *crypt_stat,
ecryptfs_derive_iv(extent_iv, crypt_stat, extent_base + extent_offset);

sg_init_table(&src_sg, 1);
- sg_init_table(&dst_sg, 1);
-
- sg_set_page(&src_sg, src_page, extent_size,
- extent_offset * extent_size);
- sg_set_page(&dst_sg, dst_page, extent_size,
- extent_offset * extent_size);
+ sg_set_folio(&src_sg, folio, extent_size,
+ extent_offset * extent_size);
+ if (dst) {
+ sg_init_one(&dst_sg, dst + extent_offset * extent_size,
+ extent_size);
+ dst_sgp = &dst_sg;
+ }

- rc = crypt_scatterlist(crypt_stat, &dst_sg, &src_sg, extent_size,
+ rc = crypt_scatterlist(crypt_stat, dst_sgp, &src_sg, extent_size,
extent_iv, op);
if (rc < 0) {
printk(KERN_ERR "%s: Error attempting to crypt page with "
@@ -321,7 +321,7 @@ static int crypt_extent(struct ecryptfs_crypt_stat *crypt_stat,
* ecryptfs_encrypt_page
* @folio: Folio mapped from the eCryptfs inode for the file; contains
* decrypted content that needs to be encrypted (to a temporary
- * page; not in place) and written out to the lower file
+ * buffer; not in place) and written out to the lower file
*
* Encrypt an eCryptfs page. This is done on a per-extent basis. Note
* that eCryptfs pages may straddle the lower pages -- for instance,
@@ -338,7 +338,6 @@ int ecryptfs_encrypt_page(struct folio *folio)
struct inode *ecryptfs_inode;
struct ecryptfs_crypt_stat *crypt_stat;
char *enc_extent_virt;
- struct page *enc_extent_page = NULL;
loff_t extent_offset;
loff_t lower_offset;
int rc = 0;
@@ -347,8 +346,8 @@ int ecryptfs_encrypt_page(struct folio *folio)
crypt_stat =
&(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED));
- enc_extent_page = alloc_page(GFP_USER);
- if (!enc_extent_page) {
+ enc_extent_virt = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!enc_extent_virt) {
rc = -ENOMEM;
ecryptfs_printk(KERN_ERR, "Error allocating memory for "
"encrypted extent\n");
@@ -358,9 +357,8 @@ int ecryptfs_encrypt_page(struct folio *folio)
for (extent_offset = 0;
extent_offset < (PAGE_SIZE / crypt_stat->extent_size);
extent_offset++) {
- rc = crypt_extent(crypt_stat, enc_extent_page,
- folio_page(folio, 0), folio->index,
- extent_offset, ENCRYPT);
+ rc = crypt_extent(crypt_stat, folio, enc_extent_virt,
+ folio->index, extent_offset, ENCRYPT);
if (rc) {
printk(KERN_ERR "%s: Error encrypting extent; "
"rc = [%d]\n", __func__, rc);
@@ -369,10 +367,8 @@ int ecryptfs_encrypt_page(struct folio *folio)
}

lower_offset = lower_offset_for_page(crypt_stat, folio);
- enc_extent_virt = kmap_local_page(enc_extent_page);
rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt, lower_offset,
PAGE_SIZE);
- kunmap_local(enc_extent_virt);
if (rc < 0) {
ecryptfs_printk(KERN_ERR,
"Error attempting to write lower page; rc = [%d]\n",
@@ -381,9 +377,7 @@ int ecryptfs_encrypt_page(struct folio *folio)
}
rc = 0;
out:
- if (enc_extent_page) {
- __free_page(enc_extent_page);
- }
+ kfree(enc_extent_virt);
return rc;
}

@@ -432,8 +426,7 @@ int ecryptfs_decrypt_page(struct folio *folio)
for (extent_offset = 0;
extent_offset < (PAGE_SIZE / crypt_stat->extent_size);
extent_offset++) {
- struct page *page = folio_page(folio, 0);
- rc = crypt_extent(crypt_stat, page, page, folio->index,
+ rc = crypt_extent(crypt_stat, folio, NULL, folio->index,
extent_offset, DECRYPT);
if (rc) {
printk(KERN_ERR "%s: Error decrypting extent; "

--
2.39.5