diff options
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r-- | fs/ecryptfs/inode.c | 100 |
1 files changed, 35 insertions, 65 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index efdd2b7b62d7..dfcc68484f47 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -231,7 +231,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
231 | int lower_flags; | 231 | int lower_flags; |
232 | struct ecryptfs_crypt_stat *crypt_stat; | 232 | struct ecryptfs_crypt_stat *crypt_stat; |
233 | struct dentry *lower_dentry; | 233 | struct dentry *lower_dentry; |
234 | struct dentry *tlower_dentry = NULL; | ||
235 | struct file *lower_file; | 234 | struct file *lower_file; |
236 | struct inode *inode, *lower_inode; | 235 | struct inode *inode, *lower_inode; |
237 | struct vfsmount *lower_mnt; | 236 | struct vfsmount *lower_mnt; |
@@ -241,30 +240,19 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
241 | lower_dentry->d_name.name); | 240 | lower_dentry->d_name.name); |
242 | inode = ecryptfs_dentry->d_inode; | 241 | inode = ecryptfs_dentry->d_inode; |
243 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | 242 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; |
244 | tlower_dentry = dget(lower_dentry); | ||
245 | if (!tlower_dentry) { | ||
246 | rc = -ENOMEM; | ||
247 | ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry\n"); | ||
248 | goto out; | ||
249 | } | ||
250 | lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR; | 243 | lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR; |
251 | #if BITS_PER_LONG != 32 | 244 | #if BITS_PER_LONG != 32 |
252 | lower_flags |= O_LARGEFILE; | 245 | lower_flags |= O_LARGEFILE; |
253 | #endif | 246 | #endif |
254 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | 247 | lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); |
255 | mntget(lower_mnt); | ||
256 | /* Corresponding fput() at end of this function */ | 248 | /* Corresponding fput() at end of this function */ |
257 | lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags); | 249 | if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, |
258 | if (IS_ERR(lower_file)) { | 250 | lower_flags))) { |
259 | rc = PTR_ERR(lower_file); | ||
260 | ecryptfs_printk(KERN_ERR, | 251 | ecryptfs_printk(KERN_ERR, |
261 | "Error opening dentry; rc = [%i]\n", rc); | 252 | "Error opening dentry; rc = [%i]\n", rc); |
262 | goto out; | 253 | goto out; |
263 | } | 254 | } |
264 | /* fput(lower_file) should handle the puts if we do this */ | 255 | lower_inode = lower_dentry->d_inode; |
265 | lower_file->f_dentry = tlower_dentry; | ||
266 | lower_file->f_vfsmnt = lower_mnt; | ||
267 | lower_inode = tlower_dentry->d_inode; | ||
268 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | 256 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { |
269 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); | 257 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); |
270 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); | 258 | ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED); |
@@ -285,7 +273,8 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
285 | } | 273 | } |
286 | rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode); | 274 | rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode); |
287 | out_fput: | 275 | out_fput: |
288 | fput(lower_file); | 276 | if ((rc = ecryptfs_close_lower_file(lower_file))) |
277 | printk(KERN_ERR "Error closing lower_file\n"); | ||
289 | out: | 278 | out: |
290 | return rc; | 279 | return rc; |
291 | } | 280 | } |
@@ -336,7 +325,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
336 | struct dentry *lower_dir_dentry; | 325 | struct dentry *lower_dir_dentry; |
337 | struct dentry *lower_dentry; | 326 | struct dentry *lower_dentry; |
338 | struct vfsmount *lower_mnt; | 327 | struct vfsmount *lower_mnt; |
339 | struct dentry *tlower_dentry = NULL; | ||
340 | char *encoded_name; | 328 | char *encoded_name; |
341 | unsigned int encoded_namelen; | 329 | unsigned int encoded_namelen; |
342 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | 330 | struct ecryptfs_crypt_stat *crypt_stat = NULL; |
@@ -347,27 +335,32 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
347 | lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); | 335 | lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); |
348 | dentry->d_op = &ecryptfs_dops; | 336 | dentry->d_op = &ecryptfs_dops; |
349 | if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, ".")) | 337 | if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, ".")) |
350 | || (dentry->d_name.len == 2 && !strcmp(dentry->d_name.name, ".."))) | 338 | || (dentry->d_name.len == 2 |
351 | goto out_drop; | 339 | && !strcmp(dentry->d_name.name, ".."))) { |
340 | d_drop(dentry); | ||
341 | goto out; | ||
342 | } | ||
352 | encoded_namelen = ecryptfs_encode_filename(crypt_stat, | 343 | encoded_namelen = ecryptfs_encode_filename(crypt_stat, |
353 | dentry->d_name.name, | 344 | dentry->d_name.name, |
354 | dentry->d_name.len, | 345 | dentry->d_name.len, |
355 | &encoded_name); | 346 | &encoded_name); |
356 | if (encoded_namelen < 0) { | 347 | if (encoded_namelen < 0) { |
357 | rc = encoded_namelen; | 348 | rc = encoded_namelen; |
358 | goto out_drop; | 349 | d_drop(dentry); |
350 | goto out; | ||
359 | } | 351 | } |
360 | ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen " | 352 | ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen " |
361 | "= [%d]\n", encoded_name, encoded_namelen); | 353 | "= [%d]\n", encoded_name, encoded_namelen); |
362 | lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry, | 354 | lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry, |
363 | encoded_namelen - 1); | 355 | encoded_namelen - 1); |
364 | kfree(encoded_name); | 356 | kfree(encoded_name); |
365 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); | ||
366 | if (IS_ERR(lower_dentry)) { | 357 | if (IS_ERR(lower_dentry)) { |
367 | ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n"); | 358 | ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n"); |
368 | rc = PTR_ERR(lower_dentry); | 359 | rc = PTR_ERR(lower_dentry); |
369 | goto out_drop; | 360 | d_drop(dentry); |
361 | goto out; | ||
370 | } | 362 | } |
363 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); | ||
371 | ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->" | 364 | ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->" |
372 | "d_name.name = [%s]\n", lower_dentry, | 365 | "d_name.name = [%s]\n", lower_dentry, |
373 | lower_dentry->d_name.name); | 366 | lower_dentry->d_name.name); |
@@ -408,12 +401,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
408 | "as we *think* we are about to unlink\n"); | 401 | "as we *think* we are about to unlink\n"); |
409 | goto out; | 402 | goto out; |
410 | } | 403 | } |
411 | tlower_dentry = dget(lower_dentry); | ||
412 | if (!tlower_dentry || IS_ERR(tlower_dentry)) { | ||
413 | rc = -ENOMEM; | ||
414 | ecryptfs_printk(KERN_ERR, "Cannot dget lower_dentry\n"); | ||
415 | goto out_dput; | ||
416 | } | ||
417 | /* Released in this function */ | 404 | /* Released in this function */ |
418 | page_virt = | 405 | page_virt = |
419 | (char *)kmem_cache_alloc(ecryptfs_header_cache_2, | 406 | (char *)kmem_cache_alloc(ecryptfs_header_cache_2, |
@@ -425,7 +412,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
425 | goto out_dput; | 412 | goto out_dput; |
426 | } | 413 | } |
427 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 414 | memset(page_virt, 0, PAGE_CACHE_SIZE); |
428 | rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd->mnt); | 415 | rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt); |
429 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 416 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
430 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) | 417 | if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED)) |
431 | ecryptfs_set_default_sizes(crypt_stat); | 418 | ecryptfs_set_default_sizes(crypt_stat); |
@@ -448,9 +435,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
448 | 435 | ||
449 | out_dput: | 436 | out_dput: |
450 | dput(lower_dentry); | 437 | dput(lower_dentry); |
451 | if (tlower_dentry) | ||
452 | dput(tlower_dentry); | ||
453 | out_drop: | ||
454 | d_drop(dentry); | 438 | d_drop(dentry); |
455 | out: | 439 | out: |
456 | return ERR_PTR(rc); | 440 | return ERR_PTR(rc); |
@@ -486,8 +470,9 @@ out_lock: | |||
486 | unlock_dir(lower_dir_dentry); | 470 | unlock_dir(lower_dir_dentry); |
487 | dput(lower_new_dentry); | 471 | dput(lower_new_dentry); |
488 | dput(lower_old_dentry); | 472 | dput(lower_old_dentry); |
489 | if (!new_dentry->d_inode) | 473 | d_drop(lower_old_dentry); |
490 | d_drop(new_dentry); | 474 | d_drop(new_dentry); |
475 | d_drop(old_dentry); | ||
491 | return rc; | 476 | return rc; |
492 | } | 477 | } |
493 | 478 | ||
@@ -500,7 +485,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) | |||
500 | lock_parent(lower_dentry); | 485 | lock_parent(lower_dentry); |
501 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | 486 | rc = vfs_unlink(lower_dir_inode, lower_dentry); |
502 | if (rc) { | 487 | if (rc) { |
503 | ecryptfs_printk(KERN_ERR, "Error in vfs_unlink\n"); | 488 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); |
504 | goto out_unlock; | 489 | goto out_unlock; |
505 | } | 490 | } |
506 | ecryptfs_copy_attr_times(dir, lower_dir_inode); | 491 | ecryptfs_copy_attr_times(dir, lower_dir_inode); |
@@ -576,41 +561,24 @@ out: | |||
576 | 561 | ||
577 | static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) | 562 | static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) |
578 | { | 563 | { |
579 | int rc = 0; | ||
580 | struct dentry *tdentry = NULL; | ||
581 | struct dentry *lower_dentry; | 564 | struct dentry *lower_dentry; |
582 | struct dentry *tlower_dentry = NULL; | ||
583 | struct dentry *lower_dir_dentry; | 565 | struct dentry *lower_dir_dentry; |
566 | int rc; | ||
584 | 567 | ||
585 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 568 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
586 | if (!(tdentry = dget(dentry))) { | 569 | dget(dentry); |
587 | rc = -EINVAL; | ||
588 | ecryptfs_printk(KERN_ERR, "Error dget'ing dentry [%p]\n", | ||
589 | dentry); | ||
590 | goto out; | ||
591 | } | ||
592 | lower_dir_dentry = lock_parent(lower_dentry); | 570 | lower_dir_dentry = lock_parent(lower_dentry); |
593 | if (!(tlower_dentry = dget(lower_dentry))) { | 571 | dget(lower_dentry); |
594 | rc = -EINVAL; | ||
595 | ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry " | ||
596 | "[%p]\n", lower_dentry); | ||
597 | goto out; | ||
598 | } | ||
599 | rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); | 572 | rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); |
600 | if (!rc) { | 573 | dput(lower_dentry); |
601 | d_delete(tlower_dentry); | 574 | if (!rc) |
602 | tlower_dentry = NULL; | 575 | d_delete(lower_dentry); |
603 | } | ||
604 | ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode); | 576 | ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode); |
605 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; | 577 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; |
606 | unlock_dir(lower_dir_dentry); | 578 | unlock_dir(lower_dir_dentry); |
607 | if (!rc) | 579 | if (!rc) |
608 | d_drop(dentry); | 580 | d_drop(dentry); |
609 | out: | 581 | dput(dentry); |
610 | if (tdentry) | ||
611 | dput(tdentry); | ||
612 | if (tlower_dentry) | ||
613 | dput(tlower_dentry); | ||
614 | return rc; | 582 | return rc; |
615 | } | 583 | } |
616 | 584 | ||
@@ -663,6 +631,8 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
663 | ecryptfs_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); | 631 | ecryptfs_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); |
664 | out_lock: | 632 | out_lock: |
665 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); | 633 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
634 | dput(lower_new_dentry->d_parent); | ||
635 | dput(lower_old_dentry->d_parent); | ||
666 | dput(lower_new_dentry); | 636 | dput(lower_new_dentry); |
667 | dput(lower_old_dentry); | 637 | dput(lower_old_dentry); |
668 | return rc; | 638 | return rc; |
@@ -832,12 +802,11 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
832 | } | 802 | } |
833 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 803 | lower_dentry = ecryptfs_dentry_to_lower(dentry); |
834 | /* This dget & mntget is released through fput at out_fput: */ | 804 | /* This dget & mntget is released through fput at out_fput: */ |
835 | dget(lower_dentry); | ||
836 | lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | 805 | lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); |
837 | mntget(lower_mnt); | 806 | if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, |
838 | lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR); | 807 | O_RDWR))) { |
839 | if (unlikely(IS_ERR(lower_file))) { | 808 | ecryptfs_printk(KERN_ERR, |
840 | rc = PTR_ERR(lower_file); | 809 | "Error opening dentry; rc = [%i]\n", rc); |
841 | goto out_free; | 810 | goto out_free; |
842 | } | 811 | } |
843 | ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file); | 812 | ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file); |
@@ -879,7 +848,8 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
879 | = CURRENT_TIME; | 848 | = CURRENT_TIME; |
880 | mark_inode_dirty_sync(inode); | 849 | mark_inode_dirty_sync(inode); |
881 | out_fput: | 850 | out_fput: |
882 | fput(lower_file); | 851 | if ((rc = ecryptfs_close_lower_file(lower_file))) |
852 | printk(KERN_ERR "Error closing lower_file\n"); | ||
883 | out_free: | 853 | out_free: |
884 | if (ecryptfs_file_to_private(&fake_ecryptfs_file)) | 854 | if (ecryptfs_file_to_private(&fake_ecryptfs_file)) |
885 | kmem_cache_free(ecryptfs_file_info_cache, | 855 | kmem_cache_free(ecryptfs_file_info_cache, |