Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48c1e44a authored by Al Viro's avatar Al Viro
Browse files

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



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 02bd9799
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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,
+8 −40
Original line number Diff line number Diff line
@@ -142,19 +142,10 @@ ecryptfs_do_create(struct inode *directory_inode,
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;
}
+2 −3
Original line number Diff line number Diff line
@@ -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;