diff options
Diffstat (limited to 'fs/ecryptfs/file.c')
-rw-r--r-- | fs/ecryptfs/file.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index c8550c9f9cd..a92ef05eff8 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -198,6 +198,33 @@ retry: 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 |