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

[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
...@@ -1191,28 +1191,28 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code) ...@@ -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, int ecryptfs_read_header_region(char *data, struct dentry *dentry,
struct vfsmount *mnt) struct vfsmount *mnt)
{ {
struct file *file; struct file *lower_file;
mm_segment_t oldfs; mm_segment_t oldfs;
int rc; int rc;
mnt = mntget(mnt); if ((rc = ecryptfs_open_lower_file(&lower_file, dentry, mnt,
file = dentry_open(dentry, mnt, O_RDONLY); O_RDONLY))) {
if (IS_ERR(file)) { printk(KERN_ERR
ecryptfs_printk(KERN_DEBUG, "Error opening file to " "Error opening lower_file to read header region\n");
"read header region\n");
mntput(mnt);
rc = PTR_ERR(file);
goto out; goto out;
} }
file->f_pos = 0; lower_file->f_pos = 0;
oldfs = get_fs(); oldfs = get_fs();
set_fs(get_ds()); set_fs(get_ds());
/* For releases 0.1 and 0.2, all of the header information /* For releases 0.1 and 0.2, all of the header information
* fits in the first data extent-sized region. */ * fits in the first data extent-sized region. */
rc = file->f_op->read(file, (char __user *)data, rc = lower_file->f_op->read(lower_file, (char __user *)data,
ECRYPTFS_DEFAULT_EXTENT_SIZE, &file->f_pos); ECRYPTFS_DEFAULT_EXTENT_SIZE, &lower_file->f_pos);
set_fs(oldfs); 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; rc = 0;
out: out:
return rc; return rc;
......
...@@ -482,5 +482,9 @@ ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, ...@@ -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_test(struct inode *inode, void *candidate_lower_inode);
int ecryptfs_inode_set(struct inode *inode, void *lower_inode); int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
void ecryptfs_init_inode(struct inode *inode, struct inode *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 */ #endif /* #ifndef ECRYPTFS_KERNEL_H */
...@@ -198,6 +198,33 @@ static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir) ...@@ -198,6 +198,33 @@ static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir)
struct kmem_cache *ecryptfs_file_info_cache; 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 * ecryptfs_open
* @inode: inode speciying file to open * @inode: inode speciying file to open
...@@ -244,19 +271,15 @@ static int ecryptfs_open(struct inode *inode, struct file *file) ...@@ -244,19 +271,15 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
} }
mutex_unlock(&crypt_stat->cs_mutex); 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; lower_flags = file->f_flags;
if ((lower_flags & O_ACCMODE) == O_WRONLY) if ((lower_flags & O_ACCMODE) == O_WRONLY)
lower_flags = (lower_flags & O_ACCMODE) | O_RDWR; lower_flags = (lower_flags & O_ACCMODE) | O_RDWR;
if (file->f_flags & O_APPEND) if (file->f_flags & O_APPEND)
lower_flags &= ~O_APPEND; lower_flags &= ~O_APPEND;
lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
mntget(lower_mnt);
/* Corresponding fput() in ecryptfs_release() */ /* Corresponding fput() in ecryptfs_release() */
lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags); if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
if (IS_ERR(lower_file)) { lower_flags))) {
rc = PTR_ERR(lower_file);
ecryptfs_printk(KERN_ERR, "Error opening lower file\n"); ecryptfs_printk(KERN_ERR, "Error opening lower file\n");
goto out_puts; goto out_puts;
} }
...@@ -341,11 +364,16 @@ static int ecryptfs_release(struct inode *inode, struct file *file) ...@@ -341,11 +364,16 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
struct file *lower_file = ecryptfs_file_to_lower(file); struct file *lower_file = ecryptfs_file_to_lower(file);
struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file); struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file);
struct inode *lower_inode = ecryptfs_inode_to_lower(inode); 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; inode->i_blocks = lower_inode->i_blocks;
kmem_cache_free(ecryptfs_file_info_cache, file_info); kmem_cache_free(ecryptfs_file_info_cache, file_info);
return 0; out:
return rc;
} }
static int static int
......
...@@ -231,7 +231,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) ...@@ -231,7 +231,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
int lower_flags; int lower_flags;
struct ecryptfs_crypt_stat *crypt_stat; struct ecryptfs_crypt_stat *crypt_stat;
struct dentry *lower_dentry; struct dentry *lower_dentry;
struct dentry *tlower_dentry = NULL;
struct file *lower_file; struct file *lower_file;
struct inode *inode, *lower_inode; struct inode *inode, *lower_inode;
struct vfsmount *lower_mnt; struct vfsmount *lower_mnt;
...@@ -241,30 +240,19 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) ...@@ -241,30 +240,19 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
lower_dentry->d_name.name); lower_dentry->d_name.name);
inode = ecryptfs_dentry->d_inode; inode = ecryptfs_dentry->d_inode;
crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; 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; lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR;
#if BITS_PER_LONG != 32 #if BITS_PER_LONG != 32
lower_flags |= O_LARGEFILE; lower_flags |= O_LARGEFILE;
#endif #endif
lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
mntget(lower_mnt);
/* Corresponding fput() at end of this function */ /* Corresponding fput() at end of this function */
lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags); if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
if (IS_ERR(lower_file)) { lower_flags))) {
rc = PTR_ERR(lower_file);
ecryptfs_printk(KERN_ERR, ecryptfs_printk(KERN_ERR,
"Error opening dentry; rc = [%i]\n", rc); "Error opening dentry; rc = [%i]\n", rc);
goto out; goto out;
} }
/* fput(lower_file) should handle the puts if we do this */ lower_inode = lower_dentry->d_inode;
lower_file->f_dentry = tlower_dentry;
lower_file->f_vfsmnt = lower_mnt;
lower_inode = tlower_dentry->d_inode;
if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
...@@ -285,7 +273,8 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) ...@@ -285,7 +273,8 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
} }
rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode); rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode);
out_fput: out_fput:
fput(lower_file); if ((rc = ecryptfs_close_lower_file(lower_file)))
printk(KERN_ERR "Error closing lower_file\n");
out: out:
return rc; return rc;
} }
...@@ -832,12 +821,11 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) ...@@ -832,12 +821,11 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
} }
lower_dentry = ecryptfs_dentry_to_lower(dentry); lower_dentry = ecryptfs_dentry_to_lower(dentry);
/* This dget & mntget is released through fput at out_fput: */ /* This dget & mntget is released through fput at out_fput: */
dget(lower_dentry);
lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
mntget(lower_mnt); if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR); O_RDWR))) {
if (unlikely(IS_ERR(lower_file))) { ecryptfs_printk(KERN_ERR,
rc = PTR_ERR(lower_file); "Error opening dentry; rc = [%i]\n", rc);
goto out_free; goto out_free;
} }
ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file); ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file);
...@@ -879,7 +867,8 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) ...@@ -879,7 +867,8 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
= CURRENT_TIME; = CURRENT_TIME;
mark_inode_dirty_sync(inode); mark_inode_dirty_sync(inode);
out_fput: out_fput:
fput(lower_file); if ((rc = ecryptfs_close_lower_file(lower_file)))
printk(KERN_ERR "Error closing lower_file\n");
out_free: out_free:
if (ecryptfs_file_to_private(&fake_ecryptfs_file)) if (ecryptfs_file_to_private(&fake_ecryptfs_file))
kmem_cache_free(ecryptfs_file_info_cache, kmem_cache_free(ecryptfs_file_info_cache,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment