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 c8550c9f9cd2..a92ef05eff8f 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
| @@ -198,6 +198,33 @@ retry: | |||
| 198 | 198 | ||
| 199 | struct kmem_cache *ecryptfs_file_info_cache; | 199 | struct kmem_cache *ecryptfs_file_info_cache; |
| 200 | 200 | ||
| 201 | int ecryptfs_open_lower_file(struct file **lower_file, | ||
| 202 | struct dentry *lower_dentry, | ||
| 203 | struct vfsmount *lower_mnt, int flags) | ||
| 204 | { | ||
| 205 | int rc = 0; | ||
| 206 | |||
| 207 | dget(lower_dentry); | ||
| 208 | mntget(lower_mnt); | ||
| 209 | *lower_file = dentry_open(lower_dentry, lower_mnt, flags); | ||
| 210 | if (IS_ERR(*lower_file)) { | ||
| 211 | printk(KERN_ERR "Error opening lower file for lower_dentry " | ||
| 212 | "[0x%p], lower_mnt [0x%p], and flags [0x%x]\n", | ||
| 213 | lower_dentry, lower_mnt, flags); | ||
| 214 | rc = PTR_ERR(*lower_file); | ||
| 215 | *lower_file = NULL; | ||
| 216 | goto out; | ||
| 217 | } | ||
| 218 | out: | ||
| 219 | return rc; | ||
| 220 | } | ||
| 221 | |||
| 222 | int ecryptfs_close_lower_file(struct file *lower_file) | ||
| 223 | { | ||
| 224 | fput(lower_file); | ||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 201 | /** | 228 | /** |
| 202 | * ecryptfs_open | 229 | * ecryptfs_open |
| 203 | * @inode: inode speciying file to open | 230 | * @inode: inode speciying file to open |
| @@ -244,19 +271,15 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
| 244 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | 271 | ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); |
| 245 | } | 272 | } |
| 246 | mutex_unlock(&crypt_stat->cs_mutex); | 273 | mutex_unlock(&crypt_stat->cs_mutex); |
| 247 | /* This mntget & dget is undone via fput when the file is released */ | ||
| 248 | dget(lower_dentry); | ||
| 249 | lower_flags = file->f_flags; | 274 | lower_flags = file->f_flags; |
| 250 | if ((lower_flags & O_ACCMODE) == O_WRONLY) | 275 | if ((lower_flags & O_ACCMODE) == O_WRONLY) |
| 251 | lower_flags = (lower_flags & O_ACCMODE) | O_RDWR; | 276 | lower_flags = (lower_flags & O_ACCMODE) | O_RDWR; |
| 252 | if (file->f_flags & O_APPEND) | 277 | if (file->f_flags & O_APPEND) |
| 253 | lower_flags &= ~O_APPEND; | 278 | lower_flags &= ~O_APPEND; |
| 254 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | 279 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); |
| 255 | mntget(lower_mnt); | ||
| 256 | /* Corresponding fput() in ecryptfs_release() */ | 280 | /* Corresponding fput() in ecryptfs_release() */ |
| 257 | lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags); | 281 | if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, |
| 258 | if (IS_ERR(lower_file)) { | 282 | lower_flags))) { |
| 259 | rc = PTR_ERR(lower_file); | ||
| 260 | ecryptfs_printk(KERN_ERR, "Error opening lower file\n"); | 283 | ecryptfs_printk(KERN_ERR, "Error opening lower file\n"); |
| 261 | goto out_puts; | 284 | goto out_puts; |
| 262 | } | 285 | } |
| @@ -341,11 +364,16 @@ static int ecryptfs_release(struct inode *inode, struct file *file) | |||
| 341 | struct file *lower_file = ecryptfs_file_to_lower(file); | 364 | struct file *lower_file = ecryptfs_file_to_lower(file); |
| 342 | struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file); | 365 | struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file); |
| 343 | struct inode *lower_inode = ecryptfs_inode_to_lower(inode); | 366 | struct inode *lower_inode = ecryptfs_inode_to_lower(inode); |
| 367 | int rc; | ||
| 344 | 368 | ||
| 345 | fput(lower_file); | 369 | if ((rc = ecryptfs_close_lower_file(lower_file))) { |
| 370 | printk(KERN_ERR "Error closing lower_file\n"); | ||
| 371 | goto out; | ||
| 372 | } | ||
| 346 | inode->i_blocks = lower_inode->i_blocks; | 373 | inode->i_blocks = lower_inode->i_blocks; |
| 347 | kmem_cache_free(ecryptfs_file_info_cache, file_info); | 374 | kmem_cache_free(ecryptfs_file_info_cache, file_info); |
| 348 | return 0; | 375 | out: |
| 376 | return rc; | ||
| 349 | } | 377 | } |
| 350 | 378 | ||
| 351 | static int | 379 | static int |
