vfs-6.13.ecryptfs

-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCZzcmVQAKCRCRxhvAZXjc
 ogE8AP9fT1T0rkYHT2ym2ulnQ2oARqO5VOnGmzYiTs2oHAfn4wD9GwH1nkMvlNTY
 l7zalIg2AIdN6qvTATSoD3sN+fJXXgU=
 =RNSE
 -----END PGP SIGNATURE-----

Merge tag 'vfs-6.13.ecryptfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull ecryptfs updates from Christian Brauner:
 "The folio project is about to remove page->index. This contains the
  work required for ecryptfs"

* tag 'vfs-6.13.ecryptfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  ecryptfs: Pass the folio index to crypt_extent()
  ecryptfs: Convert lower_offset_for_page() to take a folio
  ecryptfs: Convert ecryptfs_decrypt_page() to take a folio
  ecryptfs: Convert ecryptfs_encrypt_page() to take a folio
  ecryptfs: Convert ecryptfs_write_lower_page_segment() to take a folio
  ecryptfs: Convert ecryptfs_write() to use a folio
  ecryptfs: Convert ecryptfs_read_lower_page_segment() to take a folio
  ecryptfs: Convert ecryptfs_copy_up_encrypted_with_header() to take a folio
  ecryptfs: Use a folio throughout ecryptfs_read_folio()
  ecryptfs: Convert ecryptfs_writepage() to ecryptfs_writepages()
This commit is contained in:
Linus Torvalds 2024-11-18 11:44:06 -08:00
commit 23acd17754
4 changed files with 104 additions and 124 deletions

View File

@ -328,10 +328,10 @@ out:
* Convert an eCryptfs page index into a lower byte offset * Convert an eCryptfs page index into a lower byte offset
*/ */
static loff_t lower_offset_for_page(struct ecryptfs_crypt_stat *crypt_stat, static loff_t lower_offset_for_page(struct ecryptfs_crypt_stat *crypt_stat,
struct page *page) struct folio *folio)
{ {
return ecryptfs_lower_header_size(crypt_stat) + return ecryptfs_lower_header_size(crypt_stat) +
((loff_t)page->index << PAGE_SHIFT); (loff_t)folio->index * PAGE_SIZE;
} }
/** /**
@ -340,6 +340,7 @@ static loff_t lower_offset_for_page(struct ecryptfs_crypt_stat *crypt_stat,
* encryption operation * encryption operation
* @dst_page: The page to write the result into * @dst_page: The page to write the result into
* @src_page: The page to read from * @src_page: The page to read from
* @page_index: The offset in the file (in units of PAGE_SIZE)
* @extent_offset: Page extent offset for use in generating IV * @extent_offset: Page extent offset for use in generating IV
* @op: ENCRYPT or DECRYPT to indicate the desired operation * @op: ENCRYPT or DECRYPT to indicate the desired operation
* *
@ -350,9 +351,9 @@ static loff_t lower_offset_for_page(struct ecryptfs_crypt_stat *crypt_stat,
static int crypt_extent(struct ecryptfs_crypt_stat *crypt_stat, static int crypt_extent(struct ecryptfs_crypt_stat *crypt_stat,
struct page *dst_page, struct page *dst_page,
struct page *src_page, struct page *src_page,
pgoff_t page_index,
unsigned long extent_offset, int op) unsigned long extent_offset, int op)
{ {
pgoff_t page_index = op == ENCRYPT ? src_page->index : dst_page->index;
loff_t extent_base; loff_t extent_base;
char extent_iv[ECRYPTFS_MAX_IV_BYTES]; char extent_iv[ECRYPTFS_MAX_IV_BYTES];
struct scatterlist src_sg, dst_sg; struct scatterlist src_sg, dst_sg;
@ -392,7 +393,7 @@ out:
/** /**
* ecryptfs_encrypt_page * ecryptfs_encrypt_page
* @page: Page mapped from the eCryptfs inode for the file; contains * @folio: Folio mapped from the eCryptfs inode for the file; contains
* decrypted content that needs to be encrypted (to a temporary * decrypted content that needs to be encrypted (to a temporary
* page; not in place) and written out to the lower file * page; not in place) and written out to the lower file
* *
@ -406,7 +407,7 @@ out:
* *
* Returns zero on success; negative on error * Returns zero on success; negative on error
*/ */
int ecryptfs_encrypt_page(struct page *page) int ecryptfs_encrypt_page(struct folio *folio)
{ {
struct inode *ecryptfs_inode; struct inode *ecryptfs_inode;
struct ecryptfs_crypt_stat *crypt_stat; struct ecryptfs_crypt_stat *crypt_stat;
@ -416,7 +417,7 @@ int ecryptfs_encrypt_page(struct page *page)
loff_t lower_offset; loff_t lower_offset;
int rc = 0; int rc = 0;
ecryptfs_inode = page->mapping->host; ecryptfs_inode = folio->mapping->host;
crypt_stat = crypt_stat =
&(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)); BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED));
@ -431,7 +432,8 @@ int ecryptfs_encrypt_page(struct page *page)
for (extent_offset = 0; for (extent_offset = 0;
extent_offset < (PAGE_SIZE / crypt_stat->extent_size); extent_offset < (PAGE_SIZE / crypt_stat->extent_size);
extent_offset++) { extent_offset++) {
rc = crypt_extent(crypt_stat, enc_extent_page, page, rc = crypt_extent(crypt_stat, enc_extent_page,
folio_page(folio, 0), folio->index,
extent_offset, ENCRYPT); extent_offset, ENCRYPT);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error encrypting extent; " printk(KERN_ERR "%s: Error encrypting extent; "
@ -440,7 +442,7 @@ int ecryptfs_encrypt_page(struct page *page)
} }
} }
lower_offset = lower_offset_for_page(crypt_stat, page); lower_offset = lower_offset_for_page(crypt_stat, folio);
enc_extent_virt = kmap_local_page(enc_extent_page); enc_extent_virt = kmap_local_page(enc_extent_page);
rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt, lower_offset, rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt, lower_offset,
PAGE_SIZE); PAGE_SIZE);
@ -461,7 +463,7 @@ out:
/** /**
* ecryptfs_decrypt_page * ecryptfs_decrypt_page
* @page: Page mapped from the eCryptfs inode for the file; data read * @folio: Folio mapped from the eCryptfs inode for the file; data read
* and decrypted from the lower file will be written into this * and decrypted from the lower file will be written into this
* page * page
* *
@ -475,7 +477,7 @@ out:
* *
* Returns zero on success; negative on error * Returns zero on success; negative on error
*/ */
int ecryptfs_decrypt_page(struct page *page) int ecryptfs_decrypt_page(struct folio *folio)
{ {
struct inode *ecryptfs_inode; struct inode *ecryptfs_inode;
struct ecryptfs_crypt_stat *crypt_stat; struct ecryptfs_crypt_stat *crypt_stat;
@ -484,13 +486,13 @@ int ecryptfs_decrypt_page(struct page *page)
loff_t lower_offset; loff_t lower_offset;
int rc = 0; int rc = 0;
ecryptfs_inode = page->mapping->host; ecryptfs_inode = folio->mapping->host;
crypt_stat = crypt_stat =
&(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)); BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED));
lower_offset = lower_offset_for_page(crypt_stat, page); lower_offset = lower_offset_for_page(crypt_stat, folio);
page_virt = kmap_local_page(page); page_virt = kmap_local_folio(folio, 0);
rc = ecryptfs_read_lower(page_virt, lower_offset, PAGE_SIZE, rc = ecryptfs_read_lower(page_virt, lower_offset, PAGE_SIZE,
ecryptfs_inode); ecryptfs_inode);
kunmap_local(page_virt); kunmap_local(page_virt);
@ -504,7 +506,8 @@ int ecryptfs_decrypt_page(struct page *page)
for (extent_offset = 0; for (extent_offset = 0;
extent_offset < (PAGE_SIZE / crypt_stat->extent_size); extent_offset < (PAGE_SIZE / crypt_stat->extent_size);
extent_offset++) { extent_offset++) {
rc = crypt_extent(crypt_stat, page, page, struct page *page = folio_page(folio, 0);
rc = crypt_extent(crypt_stat, page, page, folio->index,
extent_offset, DECRYPT); extent_offset, DECRYPT);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error decrypting extent; " printk(KERN_ERR "%s: Error decrypting extent; "

View File

@ -569,8 +569,8 @@ void ecryptfs_destroy_mount_crypt_stat(
struct ecryptfs_mount_crypt_stat *mount_crypt_stat); struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat); int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode); int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode);
int ecryptfs_encrypt_page(struct page *page); int ecryptfs_encrypt_page(struct folio *folio);
int ecryptfs_decrypt_page(struct page *page); int ecryptfs_decrypt_page(struct folio *folio);
int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry, int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
struct inode *ecryptfs_inode); struct inode *ecryptfs_inode);
int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
@ -653,16 +653,15 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
loff_t offset, size_t size); loff_t offset, size_t size);
int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
struct page *page_for_lower, struct folio *folio_for_lower,
size_t offset_in_page, size_t size); size_t offset_in_page, size_t size);
int ecryptfs_write(struct inode *inode, char *data, loff_t offset, size_t size); int ecryptfs_write(struct inode *inode, char *data, loff_t offset, size_t size);
int ecryptfs_read_lower(char *data, loff_t offset, size_t size, int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
struct inode *ecryptfs_inode); struct inode *ecryptfs_inode);
int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, int ecryptfs_read_lower_page_segment(struct folio *folio_for_ecryptfs,
pgoff_t page_index, pgoff_t page_index,
size_t offset_in_page, size_t size, size_t offset_in_page, size_t size,
struct inode *ecryptfs_inode); struct inode *ecryptfs_inode);
struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index);
int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
size_t *length_size); size_t *length_size);
int ecryptfs_write_packet_length(char *dest, size_t size, int ecryptfs_write_packet_length(char *dest, size_t size,

View File

@ -23,47 +23,29 @@
#include "ecryptfs_kernel.h" #include "ecryptfs_kernel.h"
/* /*
* ecryptfs_get_locked_page
*
* Get one page from cache or lower f/s, return error otherwise.
*
* Returns locked and up-to-date page (if ok), with increased
* refcnt.
*/
struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index)
{
struct page *page = read_mapping_page(inode->i_mapping, index, NULL);
if (!IS_ERR(page))
lock_page(page);
return page;
}
/**
* ecryptfs_writepage
* @page: Page that is locked before this call is made
* @wbc: Write-back control structure
*
* Returns zero on success; non-zero otherwise
*
* This is where we encrypt the data and pass the encrypted data to * This is where we encrypt the data and pass the encrypted data to
* the lower filesystem. In OpenPGP-compatible mode, we operate on * the lower filesystem. In OpenPGP-compatible mode, we operate on
* entire underlying packets. * entire underlying packets.
*/ */
static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) static int ecryptfs_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{ {
int rc; struct folio *folio = NULL;
int error;
rc = ecryptfs_encrypt_page(page); while ((folio = writeback_iter(mapping, wbc, folio, &error))) {
if (rc) { error = ecryptfs_encrypt_page(folio);
ecryptfs_printk(KERN_WARNING, "Error encrypting " if (error) {
"page (upper index [0x%.16lx])\n", page->index); ecryptfs_printk(KERN_WARNING,
ClearPageUptodate(page); "Error encrypting folio (index [0x%.16lx])\n",
goto out; folio->index);
folio_clear_uptodate(folio);
mapping_set_error(mapping, error);
} }
SetPageUptodate(page); folio_unlock(folio);
out: }
unlock_page(page);
return rc; return error;
} }
static void strip_xattr_flag(char *page_virt, static void strip_xattr_flag(char *page_virt,
@ -97,7 +79,7 @@ static void strip_xattr_flag(char *page_virt,
/** /**
* ecryptfs_copy_up_encrypted_with_header * ecryptfs_copy_up_encrypted_with_header
* @page: Sort of a ``virtual'' representation of the encrypted lower * @folio: Sort of a ``virtual'' representation of the encrypted lower
* file. The actual lower file does not have the metadata in * file. The actual lower file does not have the metadata in
* the header. This is locked. * the header. This is locked.
* @crypt_stat: The eCryptfs inode's cryptographic context * @crypt_stat: The eCryptfs inode's cryptographic context
@ -106,7 +88,7 @@ static void strip_xattr_flag(char *page_virt,
* seeing, with the header information inserted. * seeing, with the header information inserted.
*/ */
static int static int
ecryptfs_copy_up_encrypted_with_header(struct page *page, ecryptfs_copy_up_encrypted_with_header(struct folio *folio,
struct ecryptfs_crypt_stat *crypt_stat) struct ecryptfs_crypt_stat *crypt_stat)
{ {
loff_t extent_num_in_page = 0; loff_t extent_num_in_page = 0;
@ -115,9 +97,9 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
int rc = 0; int rc = 0;
while (extent_num_in_page < num_extents_per_page) { while (extent_num_in_page < num_extents_per_page) {
loff_t view_extent_num = ((((loff_t)page->index) loff_t view_extent_num = ((loff_t)folio->index
* num_extents_per_page) * num_extents_per_page)
+ extent_num_in_page); + extent_num_in_page;
size_t num_header_extents_at_front = size_t num_header_extents_at_front =
(crypt_stat->metadata_size / crypt_stat->extent_size); (crypt_stat->metadata_size / crypt_stat->extent_size);
@ -125,21 +107,21 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
/* This is a header extent */ /* This is a header extent */
char *page_virt; char *page_virt;
page_virt = kmap_local_page(page); page_virt = kmap_local_folio(folio, 0);
memset(page_virt, 0, PAGE_SIZE); memset(page_virt, 0, PAGE_SIZE);
/* TODO: Support more than one header extent */ /* TODO: Support more than one header extent */
if (view_extent_num == 0) { if (view_extent_num == 0) {
size_t written; size_t written;
rc = ecryptfs_read_xattr_region( rc = ecryptfs_read_xattr_region(
page_virt, page->mapping->host); page_virt, folio->mapping->host);
strip_xattr_flag(page_virt + 16, crypt_stat); strip_xattr_flag(page_virt + 16, crypt_stat);
ecryptfs_write_header_metadata(page_virt + 20, ecryptfs_write_header_metadata(page_virt + 20,
crypt_stat, crypt_stat,
&written); &written);
} }
kunmap_local(page_virt); kunmap_local(page_virt);
flush_dcache_page(page); flush_dcache_folio(folio);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error reading xattr " printk(KERN_ERR "%s: Error reading xattr "
"region; rc = [%d]\n", __func__, rc); "region; rc = [%d]\n", __func__, rc);
@ -152,9 +134,9 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
- crypt_stat->metadata_size); - crypt_stat->metadata_size);
rc = ecryptfs_read_lower_page_segment( rc = ecryptfs_read_lower_page_segment(
page, (lower_offset >> PAGE_SHIFT), folio, (lower_offset >> PAGE_SHIFT),
(lower_offset & ~PAGE_MASK), (lower_offset & ~PAGE_MASK),
crypt_stat->extent_size, page->mapping->host); crypt_stat->extent_size, folio->mapping->host);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error attempting to read " printk(KERN_ERR "%s: Error attempting to read "
"extent at offset [%lld] in the lower " "extent at offset [%lld] in the lower "
@ -180,55 +162,50 @@ out:
*/ */
static int ecryptfs_read_folio(struct file *file, struct folio *folio) static int ecryptfs_read_folio(struct file *file, struct folio *folio)
{ {
struct page *page = &folio->page; struct inode *inode = folio->mapping->host;
struct ecryptfs_crypt_stat *crypt_stat = struct ecryptfs_crypt_stat *crypt_stat =
&ecryptfs_inode_to_private(page->mapping->host)->crypt_stat; &ecryptfs_inode_to_private(inode)->crypt_stat;
int rc = 0; int err = 0;
if (!crypt_stat || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { if (!crypt_stat || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
rc = ecryptfs_read_lower_page_segment(page, page->index, 0, err = ecryptfs_read_lower_page_segment(folio, folio->index, 0,
PAGE_SIZE, folio_size(folio), inode);
page->mapping->host);
} else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
rc = ecryptfs_copy_up_encrypted_with_header(page, err = ecryptfs_copy_up_encrypted_with_header(folio,
crypt_stat); crypt_stat);
if (rc) { if (err) {
printk(KERN_ERR "%s: Error attempting to copy " printk(KERN_ERR "%s: Error attempting to copy "
"the encrypted content from the lower " "the encrypted content from the lower "
"file whilst inserting the metadata " "file whilst inserting the metadata "
"from the xattr into the header; rc = " "from the xattr into the header; err = "
"[%d]\n", __func__, rc); "[%d]\n", __func__, err);
goto out; goto out;
} }
} else { } else {
rc = ecryptfs_read_lower_page_segment( err = ecryptfs_read_lower_page_segment(folio,
page, page->index, 0, PAGE_SIZE, folio->index, 0, folio_size(folio),
page->mapping->host); inode);
if (rc) { if (err) {
printk(KERN_ERR "Error reading page; rc = " printk(KERN_ERR "Error reading page; err = "
"[%d]\n", rc); "[%d]\n", err);
goto out; goto out;
} }
} }
} else { } else {
rc = ecryptfs_decrypt_page(page); err = ecryptfs_decrypt_page(folio);
if (rc) { if (err) {
ecryptfs_printk(KERN_ERR, "Error decrypting page; " ecryptfs_printk(KERN_ERR, "Error decrypting page; "
"rc = [%d]\n", rc); "err = [%d]\n", err);
goto out; goto out;
} }
} }
out: out:
if (rc) ecryptfs_printk(KERN_DEBUG, "Unlocking folio with index = [0x%.16lx]\n",
ClearPageUptodate(page); folio->index);
else folio_end_read(folio, err == 0);
SetPageUptodate(page); return err;
ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16lx]\n",
page->index);
unlock_page(page);
return rc;
} }
/* /*
@ -285,7 +262,7 @@ static int ecryptfs_write_begin(struct file *file,
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
rc = ecryptfs_read_lower_page_segment( rc = ecryptfs_read_lower_page_segment(
&folio->page, index, 0, PAGE_SIZE, mapping->host); folio, index, 0, PAGE_SIZE, mapping->host);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error attempting to read " printk(KERN_ERR "%s: Error attempting to read "
"lower page segment; rc = [%d]\n", "lower page segment; rc = [%d]\n",
@ -297,7 +274,7 @@ static int ecryptfs_write_begin(struct file *file,
} else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
rc = ecryptfs_copy_up_encrypted_with_header( rc = ecryptfs_copy_up_encrypted_with_header(
&folio->page, crypt_stat); folio, crypt_stat);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error attempting " printk(KERN_ERR "%s: Error attempting "
"to copy the encrypted content " "to copy the encrypted content "
@ -311,7 +288,7 @@ static int ecryptfs_write_begin(struct file *file,
folio_mark_uptodate(folio); folio_mark_uptodate(folio);
} else { } else {
rc = ecryptfs_read_lower_page_segment( rc = ecryptfs_read_lower_page_segment(
&folio->page, index, 0, PAGE_SIZE, folio, index, 0, PAGE_SIZE,
mapping->host); mapping->host);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error reading " printk(KERN_ERR "%s: Error reading "
@ -328,7 +305,7 @@ static int ecryptfs_write_begin(struct file *file,
folio_zero_range(folio, 0, PAGE_SIZE); folio_zero_range(folio, 0, PAGE_SIZE);
folio_mark_uptodate(folio); folio_mark_uptodate(folio);
} else if (len < PAGE_SIZE) { } else if (len < PAGE_SIZE) {
rc = ecryptfs_decrypt_page(&folio->page); rc = ecryptfs_decrypt_page(folio);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error decrypting " printk(KERN_ERR "%s: Error decrypting "
"page at index [%ld]; " "page at index [%ld]; "
@ -477,7 +454,7 @@ static int ecryptfs_write_end(struct file *file,
"(page w/ index = [0x%.16lx], to = [%d])\n", index, to); "(page w/ index = [0x%.16lx], to = [%d])\n", index, to);
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, rc = ecryptfs_write_lower_page_segment(ecryptfs_inode,
&folio->page, 0, to); folio, 0, to);
if (!rc) { if (!rc) {
rc = copied; rc = copied;
fsstack_copy_inode_size(ecryptfs_inode, fsstack_copy_inode_size(ecryptfs_inode,
@ -499,7 +476,7 @@ static int ecryptfs_write_end(struct file *file,
"zeros in page with index = [0x%.16lx]\n", index); "zeros in page with index = [0x%.16lx]\n", index);
goto out; goto out;
} }
rc = ecryptfs_encrypt_page(&folio->page); rc = ecryptfs_encrypt_page(folio);
if (rc) { if (rc) {
ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
"index [0x%.16lx])\n", index); "index [0x%.16lx])\n", index);
@ -548,9 +525,10 @@ const struct address_space_operations ecryptfs_aops = {
.dirty_folio = block_dirty_folio, .dirty_folio = block_dirty_folio,
.invalidate_folio = block_invalidate_folio, .invalidate_folio = block_invalidate_folio,
#endif #endif
.writepage = ecryptfs_writepage, .writepages = ecryptfs_writepages,
.read_folio = ecryptfs_read_folio, .read_folio = ecryptfs_read_folio,
.write_begin = ecryptfs_write_begin, .write_begin = ecryptfs_write_begin,
.write_end = ecryptfs_write_end, .write_end = ecryptfs_write_end,
.migrate_folio = filemap_migrate_folio,
.bmap = ecryptfs_bmap, .bmap = ecryptfs_bmap,
}; };

View File

@ -41,30 +41,29 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
/** /**
* ecryptfs_write_lower_page_segment * ecryptfs_write_lower_page_segment
* @ecryptfs_inode: The eCryptfs inode * @ecryptfs_inode: The eCryptfs inode
* @page_for_lower: The page containing the data to be written to the * @folio_for_lower: The folio containing the data to be written to the
* lower file * lower file
* @offset_in_page: The offset in the @page_for_lower from which to * @offset_in_page: The offset in the @folio_for_lower from which to
* start writing the data * start writing the data
* @size: The amount of data from @page_for_lower to write to the * @size: The amount of data from @folio_for_lower to write to the
* lower file * lower file
* *
* Determines the byte offset in the file for the given page and * Determines the byte offset in the file for the given page and
* offset within the page, maps the page, and makes the call to write * offset within the page, maps the page, and makes the call to write
* the contents of @page_for_lower to the lower inode. * the contents of @folio_for_lower to the lower inode.
* *
* Returns zero on success; non-zero otherwise * Returns zero on success; non-zero otherwise
*/ */
int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
struct page *page_for_lower, struct folio *folio_for_lower,
size_t offset_in_page, size_t size) size_t offset_in_page, size_t size)
{ {
char *virt; char *virt;
loff_t offset; loff_t offset;
int rc; int rc;
offset = ((((loff_t)page_for_lower->index) << PAGE_SHIFT) offset = (loff_t)folio_for_lower->index * PAGE_SIZE + offset_in_page;
+ offset_in_page); virt = kmap_local_folio(folio_for_lower, 0);
virt = kmap_local_page(page_for_lower);
rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size); rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size);
if (rc > 0) if (rc > 0)
rc = 0; rc = 0;
@ -93,7 +92,6 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
size_t size) size_t size)
{ {
struct page *ecryptfs_page;
struct ecryptfs_crypt_stat *crypt_stat; struct ecryptfs_crypt_stat *crypt_stat;
char *ecryptfs_page_virt; char *ecryptfs_page_virt;
loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode); loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode);
@ -111,6 +109,7 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
else else
pos = offset; pos = offset;
while (pos < (offset + size)) { while (pos < (offset + size)) {
struct folio *ecryptfs_folio;
pgoff_t ecryptfs_page_idx = (pos >> PAGE_SHIFT); pgoff_t ecryptfs_page_idx = (pos >> PAGE_SHIFT);
size_t start_offset_in_page = (pos & ~PAGE_MASK); size_t start_offset_in_page = (pos & ~PAGE_MASK);
size_t num_bytes = (PAGE_SIZE - start_offset_in_page); size_t num_bytes = (PAGE_SIZE - start_offset_in_page);
@ -130,17 +129,18 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
if (num_bytes > total_remaining_zeros) if (num_bytes > total_remaining_zeros)
num_bytes = total_remaining_zeros; num_bytes = total_remaining_zeros;
} }
ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, ecryptfs_folio = read_mapping_folio(ecryptfs_inode->i_mapping,
ecryptfs_page_idx); ecryptfs_page_idx, NULL);
if (IS_ERR(ecryptfs_page)) { if (IS_ERR(ecryptfs_folio)) {
rc = PTR_ERR(ecryptfs_page); rc = PTR_ERR(ecryptfs_folio);
printk(KERN_ERR "%s: Error getting page at " printk(KERN_ERR "%s: Error getting page at "
"index [%ld] from eCryptfs inode " "index [%ld] from eCryptfs inode "
"mapping; rc = [%d]\n", __func__, "mapping; rc = [%d]\n", __func__,
ecryptfs_page_idx, rc); ecryptfs_page_idx, rc);
goto out; goto out;
} }
ecryptfs_page_virt = kmap_local_page(ecryptfs_page); folio_lock(ecryptfs_folio);
ecryptfs_page_virt = kmap_local_folio(ecryptfs_folio, 0);
/* /*
* pos: where we're now writing, offset: where the request was * pos: where we're now writing, offset: where the request was
@ -164,17 +164,17 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
data_offset += num_bytes; data_offset += num_bytes;
} }
kunmap_local(ecryptfs_page_virt); kunmap_local(ecryptfs_page_virt);
flush_dcache_page(ecryptfs_page); flush_dcache_folio(ecryptfs_folio);
SetPageUptodate(ecryptfs_page); folio_mark_uptodate(ecryptfs_folio);
unlock_page(ecryptfs_page); folio_unlock(ecryptfs_folio);
if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) if (crypt_stat->flags & ECRYPTFS_ENCRYPTED)
rc = ecryptfs_encrypt_page(ecryptfs_page); rc = ecryptfs_encrypt_page(ecryptfs_folio);
else else
rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, rc = ecryptfs_write_lower_page_segment(ecryptfs_inode,
ecryptfs_page, ecryptfs_folio,
start_offset_in_page, start_offset_in_page,
data_offset); data_offset);
put_page(ecryptfs_page); folio_put(ecryptfs_folio);
if (rc) { if (rc) {
printk(KERN_ERR "%s: Error encrypting " printk(KERN_ERR "%s: Error encrypting "
"page; rc = [%d]\n", __func__, rc); "page; rc = [%d]\n", __func__, rc);
@ -228,7 +228,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
/** /**
* ecryptfs_read_lower_page_segment * ecryptfs_read_lower_page_segment
* @page_for_ecryptfs: The page into which data for eCryptfs will be * @folio_for_ecryptfs: The folio into which data for eCryptfs will be
* written * written
* @page_index: Page index in @page_for_ecryptfs from which to start * @page_index: Page index in @page_for_ecryptfs from which to start
* writing * writing
@ -243,7 +243,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
* *
* Returns zero on success; non-zero otherwise * Returns zero on success; non-zero otherwise
*/ */
int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, int ecryptfs_read_lower_page_segment(struct folio *folio_for_ecryptfs,
pgoff_t page_index, pgoff_t page_index,
size_t offset_in_page, size_t size, size_t offset_in_page, size_t size,
struct inode *ecryptfs_inode) struct inode *ecryptfs_inode)
@ -252,12 +252,12 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
loff_t offset; loff_t offset;
int rc; int rc;
offset = ((((loff_t)page_index) << PAGE_SHIFT) + offset_in_page); offset = (loff_t)page_index * PAGE_SIZE + offset_in_page;
virt = kmap_local_page(page_for_ecryptfs); virt = kmap_local_folio(folio_for_ecryptfs, 0);
rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode); rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode);
if (rc > 0) if (rc > 0)
rc = 0; rc = 0;
kunmap_local(virt); kunmap_local(virt);
flush_dcache_page(page_for_ecryptfs); flush_dcache_folio(folio_for_ecryptfs);
return rc; return rc;
} }