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

Commit 7ff1d74f authored by Michael Halcrow's avatar Michael Halcrow Committed by Linus Torvalds
Browse files

[PATCH] eCryptfs: Consolidate lower dentry_open's



Opens on lower dentry objects happen in several places in eCryptfs, and they
all involve the same steps (dget, mntget, dentry_open).  This patch
consolidates the lower open events into a single function call.

Signed-off-by: default avatarMichael Halcrow <mhalcrow@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8bba066f
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -1191,28 +1191,28 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code)
int ecryptfs_read_header_region(char *data, struct dentry *dentry,
				struct vfsmount *mnt)
{
	struct file *file;
	struct file *lower_file;
	mm_segment_t oldfs;
	int rc;

	mnt = mntget(mnt);
	file = dentry_open(dentry, mnt, O_RDONLY);
	if (IS_ERR(file)) {
		ecryptfs_printk(KERN_DEBUG, "Error opening file to "
				"read header region\n");
		mntput(mnt);
		rc = PTR_ERR(file);
	if ((rc = ecryptfs_open_lower_file(&lower_file, dentry, mnt,
					   O_RDONLY))) {
		printk(KERN_ERR
		       "Error opening lower_file to read header region\n");
		goto out;
	}
	file->f_pos = 0;
	lower_file->f_pos = 0;
	oldfs = get_fs();
	set_fs(get_ds());
	/* For releases 0.1 and 0.2, all of the header information
	 * fits in the first data extent-sized region. */
	rc = file->f_op->read(file, (char __user *)data,
			      ECRYPTFS_DEFAULT_EXTENT_SIZE, &file->f_pos);
	rc = lower_file->f_op->read(lower_file, (char __user *)data,
			      ECRYPTFS_DEFAULT_EXTENT_SIZE, &lower_file->f_pos);
	set_fs(oldfs);
	fput(file);
	if ((rc = ecryptfs_close_lower_file(lower_file))) {
		printk(KERN_ERR "Error closing lower_file\n");
		goto out;
	}
	rc = 0;
out:
	return rc;
+4 −0
Original line number Diff line number Diff line
@@ -482,5 +482,9 @@ ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode);
int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode);
int ecryptfs_open_lower_file(struct file **lower_file,
			     struct dentry *lower_dentry,
			     struct vfsmount *lower_mnt, int flags);
int ecryptfs_close_lower_file(struct file *lower_file);

#endif /* #ifndef ECRYPTFS_KERNEL_H */
+36 −8
Original line number Diff line number Diff line
@@ -198,6 +198,33 @@ static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir)

struct kmem_cache *ecryptfs_file_info_cache;

int ecryptfs_open_lower_file(struct file **lower_file,
			     struct dentry *lower_dentry,
			     struct vfsmount *lower_mnt, int flags)
{
	int rc = 0;

	dget(lower_dentry);
	mntget(lower_mnt);
	*lower_file = dentry_open(lower_dentry, lower_mnt, flags);
	if (IS_ERR(*lower_file)) {
		printk(KERN_ERR "Error opening lower file for lower_dentry "
		       "[0x%p], lower_mnt [0x%p], and flags [0x%x]\n",
		       lower_dentry, lower_mnt, flags);
		rc = PTR_ERR(*lower_file);
		*lower_file = NULL;
		goto out;
	}
out:
	return rc;
}

int ecryptfs_close_lower_file(struct file *lower_file)
{
	fput(lower_file);
	return 0;
}

/**
 * ecryptfs_open
 * @inode: inode speciying file to open
@@ -244,19 +271,15 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
		ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
	}
	mutex_unlock(&crypt_stat->cs_mutex);
	/* This mntget & dget is undone via fput when the file is released */
	dget(lower_dentry);
	lower_flags = file->f_flags;
	if ((lower_flags & O_ACCMODE) == O_WRONLY)
		lower_flags = (lower_flags & O_ACCMODE) | O_RDWR;
	if (file->f_flags & O_APPEND)
		lower_flags &= ~O_APPEND;
	lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
	mntget(lower_mnt);
	/* Corresponding fput() in ecryptfs_release() */
	lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags);
	if (IS_ERR(lower_file)) {
		rc = PTR_ERR(lower_file);
	if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
					   lower_flags))) {
		ecryptfs_printk(KERN_ERR, "Error opening lower file\n");
		goto out_puts;
	}
@@ -341,11 +364,16 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
	struct file *lower_file = ecryptfs_file_to_lower(file);
	struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file);
	struct inode *lower_inode = ecryptfs_inode_to_lower(inode);
	int rc;

	fput(lower_file);
	if ((rc = ecryptfs_close_lower_file(lower_file))) {
		printk(KERN_ERR "Error closing lower_file\n");
		goto out;
	}
	inode->i_blocks = lower_inode->i_blocks;
	kmem_cache_free(ecryptfs_file_info_cache, file_info);
	return 0;
out:
	return rc;
}

static int
+11 −22
Original line number Diff line number Diff line
@@ -231,7 +231,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
	int lower_flags;
	struct ecryptfs_crypt_stat *crypt_stat;
	struct dentry *lower_dentry;
	struct dentry *tlower_dentry = NULL;
	struct file *lower_file;
	struct inode *inode, *lower_inode;
	struct vfsmount *lower_mnt;
@@ -241,30 +240,19 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
			lower_dentry->d_name.name);
	inode = ecryptfs_dentry->d_inode;
	crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
	tlower_dentry = dget(lower_dentry);
	if (!tlower_dentry) {
		rc = -ENOMEM;
		ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry\n");
		goto out;
	}
	lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR;
#if BITS_PER_LONG != 32
	lower_flags |= O_LARGEFILE;
#endif
	lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
	mntget(lower_mnt);
	/* Corresponding fput() at end of this function */
	lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags);
	if (IS_ERR(lower_file)) {
		rc = PTR_ERR(lower_file);
	if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
					   lower_flags))) {
		ecryptfs_printk(KERN_ERR,
				"Error opening dentry; rc = [%i]\n", rc);
		goto out;
	}
	/* fput(lower_file) should handle the puts if we do this */
	lower_file->f_dentry = tlower_dentry;
	lower_file->f_vfsmnt = lower_mnt;
	lower_inode = tlower_dentry->d_inode;
	lower_inode = lower_dentry->d_inode;
	if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
		ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
		ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
@@ -285,7 +273,8 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
	}
	rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode);
out_fput:
	fput(lower_file);
	if ((rc = ecryptfs_close_lower_file(lower_file)))
		printk(KERN_ERR "Error closing lower_file\n");
out:
	return rc;
}
@@ -832,12 +821,11 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
	}
	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	/* This dget & mntget is released through fput at out_fput: */
	dget(lower_dentry);
	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
	mntget(lower_mnt);
	lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR);
	if (unlikely(IS_ERR(lower_file))) {
		rc = PTR_ERR(lower_file);
	if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
					   O_RDWR))) {
		ecryptfs_printk(KERN_ERR,
				"Error opening dentry; rc = [%i]\n", rc);
		goto out_free;
	}
	ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file);
@@ -879,7 +867,8 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
		= CURRENT_TIME;
	mark_inode_dirty_sync(inode);
out_fput:
	fput(lower_file);
	if ((rc = ecryptfs_close_lower_file(lower_file)))
		printk(KERN_ERR "Error closing lower_file\n");
out_free:
	if (ecryptfs_file_to_private(&fake_ecryptfs_file))
		kmem_cache_free(ecryptfs_file_info_cache,