mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
switch ecryptfs_write() to struct inode *, kill on-stack fake files
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
02bd97997a
commit
48c1e44ace
@ -731,8 +731,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
|
||||
int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
|
||||
struct page *page_for_lower,
|
||||
size_t offset_in_page, size_t size);
|
||||
int ecryptfs_write(struct file *ecryptfs_file, 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,
|
||||
struct inode *ecryptfs_inode);
|
||||
int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
|
||||
|
@ -142,19 +142,10 @@ out:
|
||||
static int grow_file(struct dentry *ecryptfs_dentry)
|
||||
{
|
||||
struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
|
||||
struct file fake_file;
|
||||
struct ecryptfs_file_info tmp_file_info;
|
||||
char zero_virt[] = { 0x00 };
|
||||
int rc = 0;
|
||||
|
||||
memset(&fake_file, 0, sizeof(fake_file));
|
||||
fake_file.f_path.dentry = ecryptfs_dentry;
|
||||
memset(&tmp_file_info, 0, sizeof(tmp_file_info));
|
||||
ecryptfs_set_file_private(&fake_file, &tmp_file_info);
|
||||
ecryptfs_set_file_lower(
|
||||
&fake_file,
|
||||
ecryptfs_inode_to_private(ecryptfs_inode)->lower_file);
|
||||
rc = ecryptfs_write(&fake_file, zero_virt, 0, 1);
|
||||
rc = ecryptfs_write(ecryptfs_inode, zero_virt, 0, 1);
|
||||
i_size_write(ecryptfs_inode, 0);
|
||||
rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
|
||||
ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |=
|
||||
@ -784,8 +775,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
|
||||
{
|
||||
int rc = 0;
|
||||
struct inode *inode = dentry->d_inode;
|
||||
struct dentry *lower_dentry;
|
||||
struct file fake_ecryptfs_file;
|
||||
struct ecryptfs_crypt_stat *crypt_stat;
|
||||
loff_t i_size = i_size_read(inode);
|
||||
loff_t lower_size_before_truncate;
|
||||
@ -796,23 +785,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
|
||||
goto out;
|
||||
}
|
||||
crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
|
||||
/* Set up a fake ecryptfs file, this is used to interface with
|
||||
* the file in the underlying filesystem so that the
|
||||
* truncation has an effect there as well. */
|
||||
memset(&fake_ecryptfs_file, 0, sizeof(fake_ecryptfs_file));
|
||||
fake_ecryptfs_file.f_path.dentry = dentry;
|
||||
/* Released at out_free: label */
|
||||
ecryptfs_set_file_private(&fake_ecryptfs_file,
|
||||
kmem_cache_alloc(ecryptfs_file_info_cache,
|
||||
GFP_KERNEL));
|
||||
if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
lower_dentry = ecryptfs_dentry_to_lower(dentry);
|
||||
ecryptfs_set_file_lower(
|
||||
&fake_ecryptfs_file,
|
||||
ecryptfs_inode_to_private(dentry->d_inode)->lower_file);
|
||||
/* Switch on growing or shrinking file */
|
||||
if (ia->ia_size > i_size) {
|
||||
char zero[] = { 0x00 };
|
||||
@ -822,7 +794,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
|
||||
* this triggers code that will fill in 0's throughout
|
||||
* the intermediate portion of the previous end of the
|
||||
* file and the new and of the file */
|
||||
rc = ecryptfs_write(&fake_ecryptfs_file, zero,
|
||||
rc = ecryptfs_write(inode, zero,
|
||||
(ia->ia_size - 1), 1);
|
||||
} else { /* ia->ia_size < i_size_read(inode) */
|
||||
/* We're chopping off all the pages down to the page
|
||||
@ -835,10 +807,10 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
|
||||
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
|
||||
rc = vmtruncate(inode, ia->ia_size);
|
||||
if (rc)
|
||||
goto out_free;
|
||||
goto out;
|
||||
lower_ia->ia_size = ia->ia_size;
|
||||
lower_ia->ia_valid |= ATTR_SIZE;
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
if (num_zeros) {
|
||||
char *zeros_virt;
|
||||
@ -846,16 +818,16 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
|
||||
zeros_virt = kzalloc(num_zeros, GFP_KERNEL);
|
||||
if (!zeros_virt) {
|
||||
rc = -ENOMEM;
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt,
|
||||
rc = ecryptfs_write(inode, zeros_virt,
|
||||
ia->ia_size, num_zeros);
|
||||
kfree(zeros_virt);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "Error attempting to zero out "
|
||||
"the remainder of the end page on "
|
||||
"reducing truncate; rc = [%d]\n", rc);
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
vmtruncate(inode, ia->ia_size);
|
||||
@ -864,7 +836,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
|
||||
printk(KERN_ERR "Problem with "
|
||||
"ecryptfs_write_inode_size_to_metadata; "
|
||||
"rc = [%d]\n", rc);
|
||||
goto out_free;
|
||||
goto out;
|
||||
}
|
||||
/* We are reducing the size of the ecryptfs file, and need to
|
||||
* know if we need to reduce the size of the lower file. */
|
||||
@ -878,10 +850,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
|
||||
} else
|
||||
lower_ia->ia_valid &= ~ATTR_SIZE;
|
||||
}
|
||||
out_free:
|
||||
if (ecryptfs_file_to_private(&fake_ecryptfs_file))
|
||||
kmem_cache_free(ecryptfs_file_info_cache,
|
||||
ecryptfs_file_to_private(&fake_ecryptfs_file));
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
|
||||
|
||||
/**
|
||||
* ecryptfs_write
|
||||
* @ecryptfs_file: The eCryptfs file into which to write
|
||||
* @ecryptfs_inode: The eCryptfs file into which to write
|
||||
* @data: Virtual address where data to write is located
|
||||
* @offset: Offset in the eCryptfs file at which to begin writing the
|
||||
* data from @data
|
||||
@ -109,12 +109,11 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
|
||||
*
|
||||
* Returns zero on success; non-zero otherwise
|
||||
*/
|
||||
int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
|
||||
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;
|
||||
struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode;
|
||||
char *ecryptfs_page_virt;
|
||||
loff_t ecryptfs_file_size = i_size_read(ecryptfs_inode);
|
||||
loff_t data_offset = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user