diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 827278525fd9..69536cacdea8 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -328,10 +328,10 @@ out: * Convert an eCryptfs page index into a lower byte offset */ 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) + - ((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 * @dst_page: The page to write the result into * @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 * @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, struct page *dst_page, struct page *src_page, + pgoff_t page_index, unsigned long extent_offset, int op) { - pgoff_t page_index = op == ENCRYPT ? src_page->index : dst_page->index; loff_t extent_base; char extent_iv[ECRYPTFS_MAX_IV_BYTES]; struct scatterlist src_sg, dst_sg; @@ -392,7 +393,7 @@ out: /** * 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 * page; not in place) and written out to the lower file * @@ -406,7 +407,7 @@ out: * * 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 ecryptfs_crypt_stat *crypt_stat; @@ -416,7 +417,7 @@ int ecryptfs_encrypt_page(struct page *page) loff_t lower_offset; int rc = 0; - ecryptfs_inode = page->mapping->host; + ecryptfs_inode = folio->mapping->host; crypt_stat = &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)); @@ -431,8 +432,9 @@ int ecryptfs_encrypt_page(struct page *page) for (extent_offset = 0; extent_offset < (PAGE_SIZE / crypt_stat->extent_size); extent_offset++) { - rc = crypt_extent(crypt_stat, enc_extent_page, page, - extent_offset, ENCRYPT); + rc = crypt_extent(crypt_stat, enc_extent_page, + folio_page(folio, 0), folio->index, + extent_offset, ENCRYPT); if (rc) { printk(KERN_ERR "%s: Error encrypting extent; " "rc = [%d]\n", __func__, rc); @@ -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); rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt, lower_offset, PAGE_SIZE); @@ -461,7 +463,7 @@ out: /** * 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 * page * @@ -475,7 +477,7 @@ out: * * 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 ecryptfs_crypt_stat *crypt_stat; @@ -484,13 +486,13 @@ int ecryptfs_decrypt_page(struct page *page) loff_t lower_offset; int rc = 0; - ecryptfs_inode = page->mapping->host; + ecryptfs_inode = folio->mapping->host; crypt_stat = &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)); - lower_offset = lower_offset_for_page(crypt_stat, page); - page_virt = kmap_local_page(page); + lower_offset = lower_offset_for_page(crypt_stat, folio); + page_virt = kmap_local_folio(folio, 0); rc = ecryptfs_read_lower(page_virt, lower_offset, PAGE_SIZE, ecryptfs_inode); kunmap_local(page_virt); @@ -504,8 +506,9 @@ int ecryptfs_decrypt_page(struct page *page) for (extent_offset = 0; extent_offset < (PAGE_SIZE / crypt_stat->extent_size); extent_offset++) { - rc = crypt_extent(crypt_stat, page, page, - extent_offset, DECRYPT); + struct page *page = folio_page(folio, 0); + rc = crypt_extent(crypt_stat, page, page, folio->index, + extent_offset, DECRYPT); if (rc) { printk(KERN_ERR "%s: Error decrypting extent; " "rc = [%d]\n", __func__, rc); diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index c586c5db18b5..1f562e75d0e4 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -569,8 +569,8 @@ void ecryptfs_destroy_mount_crypt_stat( struct ecryptfs_mount_crypt_stat *mount_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_encrypt_page(struct page *page); -int ecryptfs_decrypt_page(struct page *page); +int ecryptfs_encrypt_page(struct folio *folio); +int ecryptfs_decrypt_page(struct folio *folio); int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry, struct inode *ecryptfs_inode); 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, loff_t offset, size_t size); 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); 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, 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, size_t offset_in_page, size_t size, 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, size_t *length_size); int ecryptfs_write_packet_length(char *dest, size_t size, diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index ceda5555971a..60f0ac8744b5 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -23,47 +23,29 @@ #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 * the lower filesystem. In OpenPGP-compatible mode, we operate on * 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); - if (rc) { - ecryptfs_printk(KERN_WARNING, "Error encrypting " - "page (upper index [0x%.16lx])\n", page->index); - ClearPageUptodate(page); - goto out; + while ((folio = writeback_iter(mapping, wbc, folio, &error))) { + error = ecryptfs_encrypt_page(folio); + if (error) { + ecryptfs_printk(KERN_WARNING, + "Error encrypting folio (index [0x%.16lx])\n", + folio->index); + folio_clear_uptodate(folio); + mapping_set_error(mapping, error); + } + folio_unlock(folio); } - SetPageUptodate(page); -out: - unlock_page(page); - return rc; + + return error; } 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 - * @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 * the header. This is locked. * @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. */ 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) { loff_t extent_num_in_page = 0; @@ -115,9 +97,9 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, int rc = 0; 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) - + extent_num_in_page); + + extent_num_in_page; size_t num_header_extents_at_front = (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 */ char *page_virt; - page_virt = kmap_local_page(page); + page_virt = kmap_local_folio(folio, 0); memset(page_virt, 0, PAGE_SIZE); /* TODO: Support more than one header extent */ if (view_extent_num == 0) { size_t written; rc = ecryptfs_read_xattr_region( - page_virt, page->mapping->host); + page_virt, folio->mapping->host); strip_xattr_flag(page_virt + 16, crypt_stat); ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); } kunmap_local(page_virt); - flush_dcache_page(page); + flush_dcache_folio(folio); if (rc) { printk(KERN_ERR "%s: Error reading xattr " "region; rc = [%d]\n", __func__, rc); @@ -152,9 +134,9 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, - crypt_stat->metadata_size); rc = ecryptfs_read_lower_page_segment( - page, (lower_offset >> PAGE_SHIFT), + folio, (lower_offset >> PAGE_SHIFT), (lower_offset & ~PAGE_MASK), - crypt_stat->extent_size, page->mapping->host); + crypt_stat->extent_size, folio->mapping->host); if (rc) { printk(KERN_ERR "%s: Error attempting to read " "extent at offset [%lld] in the lower " @@ -180,55 +162,50 @@ out: */ 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 = - &ecryptfs_inode_to_private(page->mapping->host)->crypt_stat; - int rc = 0; + &ecryptfs_inode_to_private(inode)->crypt_stat; + int err = 0; if (!crypt_stat || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { - rc = ecryptfs_read_lower_page_segment(page, page->index, 0, - PAGE_SIZE, - page->mapping->host); + err = ecryptfs_read_lower_page_segment(folio, folio->index, 0, + folio_size(folio), inode); } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { - rc = ecryptfs_copy_up_encrypted_with_header(page, - crypt_stat); - if (rc) { + err = ecryptfs_copy_up_encrypted_with_header(folio, + crypt_stat); + if (err) { printk(KERN_ERR "%s: Error attempting to copy " "the encrypted content from the lower " "file whilst inserting the metadata " - "from the xattr into the header; rc = " - "[%d]\n", __func__, rc); + "from the xattr into the header; err = " + "[%d]\n", __func__, err); goto out; } } else { - rc = ecryptfs_read_lower_page_segment( - page, page->index, 0, PAGE_SIZE, - page->mapping->host); - if (rc) { - printk(KERN_ERR "Error reading page; rc = " - "[%d]\n", rc); + err = ecryptfs_read_lower_page_segment(folio, + folio->index, 0, folio_size(folio), + inode); + if (err) { + printk(KERN_ERR "Error reading page; err = " + "[%d]\n", err); goto out; } } } else { - rc = ecryptfs_decrypt_page(page); - if (rc) { + err = ecryptfs_decrypt_page(folio); + if (err) { ecryptfs_printk(KERN_ERR, "Error decrypting page; " - "rc = [%d]\n", rc); + "err = [%d]\n", err); goto out; } } out: - if (rc) - ClearPageUptodate(page); - else - SetPageUptodate(page); - ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16lx]\n", - page->index); - unlock_page(page); - return rc; + ecryptfs_printk(KERN_DEBUG, "Unlocking folio with index = [0x%.16lx]\n", + folio->index); + folio_end_read(folio, err == 0); + return err; } /* @@ -285,7 +262,7 @@ static int ecryptfs_write_begin(struct file *file, if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { rc = ecryptfs_read_lower_page_segment( - &folio->page, index, 0, PAGE_SIZE, mapping->host); + folio, index, 0, PAGE_SIZE, mapping->host); if (rc) { printk(KERN_ERR "%s: Error attempting to read " "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) { if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { rc = ecryptfs_copy_up_encrypted_with_header( - &folio->page, crypt_stat); + folio, crypt_stat); if (rc) { printk(KERN_ERR "%s: Error attempting " "to copy the encrypted content " @@ -311,7 +288,7 @@ static int ecryptfs_write_begin(struct file *file, folio_mark_uptodate(folio); } else { rc = ecryptfs_read_lower_page_segment( - &folio->page, index, 0, PAGE_SIZE, + folio, index, 0, PAGE_SIZE, mapping->host); if (rc) { 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_mark_uptodate(folio); } else if (len < PAGE_SIZE) { - rc = ecryptfs_decrypt_page(&folio->page); + rc = ecryptfs_decrypt_page(folio); if (rc) { printk(KERN_ERR "%s: Error decrypting " "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); if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, - &folio->page, 0, to); + folio, 0, to); if (!rc) { rc = copied; 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); goto out; } - rc = ecryptfs_encrypt_page(&folio->page); + rc = ecryptfs_encrypt_page(folio); if (rc) { ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " "index [0x%.16lx])\n", index); @@ -548,9 +525,10 @@ const struct address_space_operations ecryptfs_aops = { .dirty_folio = block_dirty_folio, .invalidate_folio = block_invalidate_folio, #endif - .writepage = ecryptfs_writepage, + .writepages = ecryptfs_writepages, .read_folio = ecryptfs_read_folio, .write_begin = ecryptfs_write_begin, .write_end = ecryptfs_write_end, + .migrate_folio = filemap_migrate_folio, .bmap = ecryptfs_bmap, }; diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 3458f153a588..b3b451c2b941 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c @@ -41,30 +41,29 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, /** * ecryptfs_write_lower_page_segment * @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 - * @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 - * @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 * * 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 - * 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 */ 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) { char *virt; loff_t offset; int rc; - offset = ((((loff_t)page_for_lower->index) << PAGE_SHIFT) - + offset_in_page); - virt = kmap_local_page(page_for_lower); + offset = (loff_t)folio_for_lower->index * PAGE_SIZE + offset_in_page; + virt = kmap_local_folio(folio_for_lower, 0); rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size); if (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, size_t size) { - struct page *ecryptfs_page; struct ecryptfs_crypt_stat *crypt_stat; char *ecryptfs_page_virt; 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 pos = offset; while (pos < (offset + size)) { + struct folio *ecryptfs_folio; pgoff_t ecryptfs_page_idx = (pos >> PAGE_SHIFT); size_t start_offset_in_page = (pos & ~PAGE_MASK); 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) num_bytes = total_remaining_zeros; } - ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_inode, - ecryptfs_page_idx); - if (IS_ERR(ecryptfs_page)) { - rc = PTR_ERR(ecryptfs_page); + ecryptfs_folio = read_mapping_folio(ecryptfs_inode->i_mapping, + ecryptfs_page_idx, NULL); + if (IS_ERR(ecryptfs_folio)) { + rc = PTR_ERR(ecryptfs_folio); printk(KERN_ERR "%s: Error getting page at " "index [%ld] from eCryptfs inode " "mapping; rc = [%d]\n", __func__, ecryptfs_page_idx, rc); 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 @@ -164,17 +164,17 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, data_offset += num_bytes; } kunmap_local(ecryptfs_page_virt); - flush_dcache_page(ecryptfs_page); - SetPageUptodate(ecryptfs_page); - unlock_page(ecryptfs_page); + flush_dcache_folio(ecryptfs_folio); + folio_mark_uptodate(ecryptfs_folio); + folio_unlock(ecryptfs_folio); if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) - rc = ecryptfs_encrypt_page(ecryptfs_page); + rc = ecryptfs_encrypt_page(ecryptfs_folio); else rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, - ecryptfs_page, + ecryptfs_folio, start_offset_in_page, data_offset); - put_page(ecryptfs_page); + folio_put(ecryptfs_folio); if (rc) { printk(KERN_ERR "%s: Error encrypting " "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 - * @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 * @page_index: Page index in @page_for_ecryptfs from which to start * writing @@ -243,7 +243,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size, * * 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, size_t offset_in_page, size_t size, struct inode *ecryptfs_inode) @@ -252,12 +252,12 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, loff_t offset; int rc; - offset = ((((loff_t)page_index) << PAGE_SHIFT) + offset_in_page); - virt = kmap_local_page(page_for_ecryptfs); + offset = (loff_t)page_index * PAGE_SIZE + offset_in_page; + virt = kmap_local_folio(folio_for_ecryptfs, 0); rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode); if (rc > 0) rc = 0; kunmap_local(virt); - flush_dcache_page(page_for_ecryptfs); + flush_dcache_folio(folio_for_ecryptfs); return rc; }