mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
Merge patch series "Convert ecryptfs to use folios"
Matthew Wilcox (Oracle) <willy@infradead.org> says: The next step in the folio project is to remove page->index. This patchset does that for ecryptfs. As an unloved filesystem, I haven't made any effort to support large folios; this is just "keep it working". I have only compile tested this, but since it's a straightforward conversion I'm not expecting any problems beyond my fat fingers. * patches from https://lore.kernel.org/r/20241025190822.1319162-1-willy@infradead.org: 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() Link: https://lore.kernel.org/r/20241025190822.1319162-1-willy@infradead.org Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
commit
b4201b51d9
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user