提交 48c1e44a 编写于 作者: A Al Viro

switch ecryptfs_write() to struct inode *, kill on-stack fake files

Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 02bd9799
...@@ -731,8 +731,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, ...@@ -731,8 +731,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
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 page *page_for_lower,
size_t offset_in_page, size_t size); size_t offset_in_page, size_t size);
int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, int ecryptfs_write(struct inode *inode, char *data, loff_t offset, size_t size);
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 page *page_for_ecryptfs,
......
...@@ -142,19 +142,10 @@ ecryptfs_do_create(struct inode *directory_inode, ...@@ -142,19 +142,10 @@ ecryptfs_do_create(struct inode *directory_inode,
static int grow_file(struct dentry *ecryptfs_dentry) static int grow_file(struct dentry *ecryptfs_dentry)
{ {
struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
struct file fake_file;
struct ecryptfs_file_info tmp_file_info;
char zero_virt[] = { 0x00 }; char zero_virt[] = { 0x00 };
int rc = 0; int rc = 0;
memset(&fake_file, 0, sizeof(fake_file)); rc = ecryptfs_write(ecryptfs_inode, zero_virt, 0, 1);
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);
i_size_write(ecryptfs_inode, 0); i_size_write(ecryptfs_inode, 0);
rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |=
...@@ -784,8 +775,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, ...@@ -784,8 +775,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
{ {
int rc = 0; int rc = 0;
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
struct dentry *lower_dentry;
struct file fake_ecryptfs_file;
struct ecryptfs_crypt_stat *crypt_stat; struct ecryptfs_crypt_stat *crypt_stat;
loff_t i_size = i_size_read(inode); loff_t i_size = i_size_read(inode);
loff_t lower_size_before_truncate; loff_t lower_size_before_truncate;
...@@ -796,23 +785,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, ...@@ -796,23 +785,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
goto out; goto out;
} }
crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; 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 */ /* Switch on growing or shrinking file */
if (ia->ia_size > i_size) { if (ia->ia_size > i_size) {
char zero[] = { 0x00 }; char zero[] = { 0x00 };
...@@ -822,7 +794,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, ...@@ -822,7 +794,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
* this triggers code that will fill in 0's throughout * this triggers code that will fill in 0's throughout
* the intermediate portion of the previous end of the * the intermediate portion of the previous end of the
* file and the new and of the file */ * 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); (ia->ia_size - 1), 1);
} else { /* ia->ia_size < i_size_read(inode) */ } else { /* ia->ia_size < i_size_read(inode) */
/* We're chopping off all the pages down to the page /* 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, ...@@ -835,10 +807,10 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
rc = vmtruncate(inode, ia->ia_size); rc = vmtruncate(inode, ia->ia_size);
if (rc) if (rc)
goto out_free; goto out;
lower_ia->ia_size = ia->ia_size; lower_ia->ia_size = ia->ia_size;
lower_ia->ia_valid |= ATTR_SIZE; lower_ia->ia_valid |= ATTR_SIZE;
goto out_free; goto out;
} }
if (num_zeros) { if (num_zeros) {
char *zeros_virt; char *zeros_virt;
...@@ -846,16 +818,16 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, ...@@ -846,16 +818,16 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
zeros_virt = kzalloc(num_zeros, GFP_KERNEL); zeros_virt = kzalloc(num_zeros, GFP_KERNEL);
if (!zeros_virt) { if (!zeros_virt) {
rc = -ENOMEM; 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); ia->ia_size, num_zeros);
kfree(zeros_virt); kfree(zeros_virt);
if (rc) { if (rc) {
printk(KERN_ERR "Error attempting to zero out " printk(KERN_ERR "Error attempting to zero out "
"the remainder of the end page on " "the remainder of the end page on "
"reducing truncate; rc = [%d]\n", rc); "reducing truncate; rc = [%d]\n", rc);
goto out_free; goto out;
} }
} }
vmtruncate(inode, ia->ia_size); vmtruncate(inode, ia->ia_size);
...@@ -864,7 +836,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, ...@@ -864,7 +836,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
printk(KERN_ERR "Problem with " printk(KERN_ERR "Problem with "
"ecryptfs_write_inode_size_to_metadata; " "ecryptfs_write_inode_size_to_metadata; "
"rc = [%d]\n", rc); "rc = [%d]\n", rc);
goto out_free; goto out;
} }
/* We are reducing the size of the ecryptfs file, and need to /* We are reducing the size of the ecryptfs file, and need to
* know if we need to reduce the size of the lower file. */ * 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, ...@@ -878,10 +850,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
} else } else
lower_ia->ia_valid &= ~ATTR_SIZE; 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: out:
return rc; return rc;
} }
......
...@@ -93,7 +93,7 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, ...@@ -93,7 +93,7 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
/** /**
* ecryptfs_write * 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 * @data: Virtual address where data to write is located
* @offset: Offset in the eCryptfs file at which to begin writing the * @offset: Offset in the eCryptfs file at which to begin writing the
* data from @data * data from @data
...@@ -109,12 +109,11 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, ...@@ -109,12 +109,11 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
* *
* Returns zero on success; non-zero otherwise * 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) size_t size)
{ {
struct page *ecryptfs_page; struct page *ecryptfs_page;
struct ecryptfs_crypt_stat *crypt_stat; struct ecryptfs_crypt_stat *crypt_stat;
struct inode *ecryptfs_inode = ecryptfs_file->f_dentry->d_inode;
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);
loff_t data_offset = 0; loff_t data_offset = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册