mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-01 06:33:07 +00:00
[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: Michael Halcrow <mhalcrow@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
8bba066f4e
commit
7ff1d74f56
4 changed files with 63 additions and 42 deletions
|
@ -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,
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
= 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,
|
||||||
|
|
Loading…
Reference in a new issue