Skip to content

Commit

Permalink
[PATCH] eCryptfs: Consolidate lower dentry_open's
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michael Halcrow authored and Linus Torvalds committed Oct 31, 2006
1 parent 8bba066 commit 7ff1d74
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 42 deletions.
24 changes: 12 additions & 12 deletions fs/ecryptfs/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions fs/ecryptfs/ecryptfs_kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
44 changes: 36 additions & 8 deletions fs/ecryptfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down
33 changes: 11 additions & 22 deletions fs/ecryptfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 7ff1d74

Please sign in to comment.