Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'work.ecryptfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull exryptfs updates from Al Viro:
"The interesting part here is (ecryptfs) lock_parent() fixes - its
treatment of ->d_parent had been very wrong.

The rest is trivial cleanups"

* 'work.ecryptfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
ecryptfs: ecryptfs_dentry_info->crypt_stat is never used
ecryptfs: get rid of unused accessors
ecryptfs: saner API for lock_parent()
ecryptfs: get rid of pointless dget/dput in ->symlink() and ->link()

+75 -105
+1 -16
fs/ecryptfs/ecryptfs_kernel.h
··· 262 262 * vfsmount too. */ 263 263 struct ecryptfs_dentry_info { 264 264 struct path lower_path; 265 - union { 266 - struct ecryptfs_crypt_stat *crypt_stat; 267 - struct rcu_head rcu; 268 - }; 265 + struct rcu_head rcu; 269 266 }; 270 267 271 268 /** ··· 493 496 ((struct ecryptfs_sb_info *)sb->s_fs_info)->wsi_sb = lower_sb; 494 497 } 495 498 496 - static inline struct ecryptfs_dentry_info * 497 - ecryptfs_dentry_to_private(struct dentry *dentry) 498 - { 499 - return (struct ecryptfs_dentry_info *)dentry->d_fsdata; 500 - } 501 - 502 499 static inline void 503 500 ecryptfs_set_dentry_private(struct dentry *dentry, 504 501 struct ecryptfs_dentry_info *dentry_info) ··· 504 513 ecryptfs_dentry_to_lower(struct dentry *dentry) 505 514 { 506 515 return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.dentry; 507 - } 508 - 509 - static inline struct vfsmount * 510 - ecryptfs_dentry_to_lower_mnt(struct dentry *dentry) 511 - { 512 - return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.mnt; 513 516 } 514 517 515 518 static inline struct path *
+74 -89
fs/ecryptfs/inode.c
··· 22 22 #include <asm/unaligned.h> 23 23 #include "ecryptfs_kernel.h" 24 24 25 - static struct dentry *lock_parent(struct dentry *dentry) 25 + static int lock_parent(struct dentry *dentry, 26 + struct dentry **lower_dentry, 27 + struct inode **lower_dir) 26 28 { 27 - struct dentry *dir; 29 + struct dentry *lower_dir_dentry; 28 30 29 - dir = dget_parent(dentry); 30 - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); 31 - return dir; 32 - } 31 + lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); 32 + *lower_dir = d_inode(lower_dir_dentry); 33 + *lower_dentry = ecryptfs_dentry_to_lower(dentry); 33 34 34 - static void unlock_dir(struct dentry *dir) 35 - { 36 - inode_unlock(d_inode(dir)); 37 - dput(dir); 35 + inode_lock_nested(*lower_dir, I_MUTEX_PARENT); 36 + return (*lower_dentry)->d_parent == lower_dir_dentry ? 0 : -EINVAL; 38 37 } 39 38 40 39 static int ecryptfs_inode_test(struct inode *inode, void *lower_inode) ··· 127 128 static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, 128 129 struct inode *inode) 129 130 { 130 - struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); 131 - struct dentry *lower_dir_dentry; 132 - struct inode *lower_dir_inode; 131 + struct dentry *lower_dentry; 132 + struct inode *lower_dir; 133 133 int rc; 134 134 135 - lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); 136 - lower_dir_inode = d_inode(lower_dir_dentry); 137 - inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT); 135 + rc = lock_parent(dentry, &lower_dentry, &lower_dir); 138 136 dget(lower_dentry); // don't even try to make the lower negative 139 - if (lower_dentry->d_parent != lower_dir_dentry) 140 - rc = -EINVAL; 141 - else if (d_unhashed(lower_dentry)) 142 - rc = -EINVAL; 143 - else 144 - rc = vfs_unlink(&init_user_ns, lower_dir_inode, lower_dentry, 145 - NULL); 137 + if (!rc) { 138 + if (d_unhashed(lower_dentry)) 139 + rc = -EINVAL; 140 + else 141 + rc = vfs_unlink(&init_user_ns, lower_dir, lower_dentry, 142 + NULL); 143 + } 146 144 if (rc) { 147 145 printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); 148 146 goto out_unlock; 149 147 } 150 - fsstack_copy_attr_times(dir, lower_dir_inode); 148 + fsstack_copy_attr_times(dir, lower_dir); 151 149 set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink); 152 150 inode->i_ctime = dir->i_ctime; 153 151 out_unlock: 154 152 dput(lower_dentry); 155 - inode_unlock(lower_dir_inode); 153 + inode_unlock(lower_dir); 156 154 if (!rc) 157 155 d_drop(dentry); 158 156 return rc; ··· 173 177 { 174 178 int rc; 175 179 struct dentry *lower_dentry; 176 - struct dentry *lower_dir_dentry; 180 + struct inode *lower_dir; 177 181 struct inode *inode; 178 182 179 - lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); 180 - lower_dir_dentry = lock_parent(lower_dentry); 181 - rc = vfs_create(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry, 182 - mode, true); 183 + rc = lock_parent(ecryptfs_dentry, &lower_dentry, &lower_dir); 184 + if (!rc) 185 + rc = vfs_create(&init_user_ns, lower_dir, 186 + lower_dentry, mode, true); 183 187 if (rc) { 184 188 printk(KERN_ERR "%s: Failure to create dentry in lower fs; " 185 189 "rc = [%d]\n", __func__, rc); ··· 189 193 inode = __ecryptfs_get_inode(d_inode(lower_dentry), 190 194 directory_inode->i_sb); 191 195 if (IS_ERR(inode)) { 192 - vfs_unlink(&init_user_ns, d_inode(lower_dir_dentry), 193 - lower_dentry, NULL); 196 + vfs_unlink(&init_user_ns, lower_dir, lower_dentry, NULL); 194 197 goto out_lock; 195 198 } 196 - fsstack_copy_attr_times(directory_inode, d_inode(lower_dir_dentry)); 197 - fsstack_copy_inode_size(directory_inode, d_inode(lower_dir_dentry)); 199 + fsstack_copy_attr_times(directory_inode, lower_dir); 200 + fsstack_copy_inode_size(directory_inode, lower_dir); 198 201 out_lock: 199 - unlock_dir(lower_dir_dentry); 202 + inode_unlock(lower_dir); 200 203 return inode; 201 204 } 202 205 ··· 426 431 { 427 432 struct dentry *lower_old_dentry; 428 433 struct dentry *lower_new_dentry; 429 - struct dentry *lower_dir_dentry; 434 + struct inode *lower_dir; 430 435 u64 file_size_save; 431 436 int rc; 432 437 433 438 file_size_save = i_size_read(d_inode(old_dentry)); 434 439 lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); 435 - lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); 436 - dget(lower_old_dentry); 437 - dget(lower_new_dentry); 438 - lower_dir_dentry = lock_parent(lower_new_dentry); 439 - rc = vfs_link(lower_old_dentry, &init_user_ns, 440 - d_inode(lower_dir_dentry), lower_new_dentry, NULL); 440 + rc = lock_parent(new_dentry, &lower_new_dentry, &lower_dir); 441 + if (!rc) 442 + rc = vfs_link(lower_old_dentry, &init_user_ns, lower_dir, 443 + lower_new_dentry, NULL); 441 444 if (rc || d_really_is_negative(lower_new_dentry)) 442 445 goto out_lock; 443 446 rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb); 444 447 if (rc) 445 448 goto out_lock; 446 - fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); 447 - fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); 449 + fsstack_copy_attr_times(dir, lower_dir); 450 + fsstack_copy_inode_size(dir, lower_dir); 448 451 set_nlink(d_inode(old_dentry), 449 452 ecryptfs_inode_to_lower(d_inode(old_dentry))->i_nlink); 450 453 i_size_write(d_inode(new_dentry), file_size_save); 451 454 out_lock: 452 - unlock_dir(lower_dir_dentry); 453 - dput(lower_new_dentry); 454 - dput(lower_old_dentry); 455 + inode_unlock(lower_dir); 455 456 return rc; 456 457 } 457 458 ··· 462 471 { 463 472 int rc; 464 473 struct dentry *lower_dentry; 465 - struct dentry *lower_dir_dentry; 474 + struct inode *lower_dir; 466 475 char *encoded_symname; 467 476 size_t encoded_symlen; 468 477 struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; 469 478 470 - lower_dentry = ecryptfs_dentry_to_lower(dentry); 471 - dget(lower_dentry); 472 - lower_dir_dentry = lock_parent(lower_dentry); 479 + rc = lock_parent(dentry, &lower_dentry, &lower_dir); 480 + if (rc) 481 + goto out_lock; 473 482 mount_crypt_stat = &ecryptfs_superblock_to_private( 474 483 dir->i_sb)->mount_crypt_stat; 475 484 rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname, ··· 478 487 strlen(symname)); 479 488 if (rc) 480 489 goto out_lock; 481 - rc = vfs_symlink(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry, 490 + rc = vfs_symlink(&init_user_ns, lower_dir, lower_dentry, 482 491 encoded_symname); 483 492 kfree(encoded_symname); 484 493 if (rc || d_really_is_negative(lower_dentry)) ··· 486 495 rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); 487 496 if (rc) 488 497 goto out_lock; 489 - fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); 490 - fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); 498 + fsstack_copy_attr_times(dir, lower_dir); 499 + fsstack_copy_inode_size(dir, lower_dir); 491 500 out_lock: 492 - unlock_dir(lower_dir_dentry); 493 - dput(lower_dentry); 501 + inode_unlock(lower_dir); 494 502 if (d_really_is_negative(dentry)) 495 503 d_drop(dentry); 496 504 return rc; ··· 500 510 { 501 511 int rc; 502 512 struct dentry *lower_dentry; 503 - struct dentry *lower_dir_dentry; 513 + struct inode *lower_dir; 504 514 505 - lower_dentry = ecryptfs_dentry_to_lower(dentry); 506 - lower_dir_dentry = lock_parent(lower_dentry); 507 - rc = vfs_mkdir(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry, 508 - mode); 515 + rc = lock_parent(dentry, &lower_dentry, &lower_dir); 516 + if (!rc) 517 + rc = vfs_mkdir(&init_user_ns, lower_dir, 518 + lower_dentry, mode); 509 519 if (rc || d_really_is_negative(lower_dentry)) 510 520 goto out; 511 521 rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); 512 522 if (rc) 513 523 goto out; 514 - fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); 515 - fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); 516 - set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink); 524 + fsstack_copy_attr_times(dir, lower_dir); 525 + fsstack_copy_inode_size(dir, lower_dir); 526 + set_nlink(dir, lower_dir->i_nlink); 517 527 out: 518 - unlock_dir(lower_dir_dentry); 528 + inode_unlock(lower_dir); 519 529 if (d_really_is_negative(dentry)) 520 530 d_drop(dentry); 521 531 return rc; ··· 524 534 static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) 525 535 { 526 536 struct dentry *lower_dentry; 527 - struct dentry *lower_dir_dentry; 528 - struct inode *lower_dir_inode; 537 + struct inode *lower_dir; 529 538 int rc; 530 539 531 - lower_dentry = ecryptfs_dentry_to_lower(dentry); 532 - lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); 533 - lower_dir_inode = d_inode(lower_dir_dentry); 534 - 535 - inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT); 540 + rc = lock_parent(dentry, &lower_dentry, &lower_dir); 536 541 dget(lower_dentry); // don't even try to make the lower negative 537 - if (lower_dentry->d_parent != lower_dir_dentry) 538 - rc = -EINVAL; 539 - else if (d_unhashed(lower_dentry)) 540 - rc = -EINVAL; 541 - else 542 - rc = vfs_rmdir(&init_user_ns, lower_dir_inode, lower_dentry); 542 + if (!rc) { 543 + if (d_unhashed(lower_dentry)) 544 + rc = -EINVAL; 545 + else 546 + rc = vfs_rmdir(&init_user_ns, lower_dir, lower_dentry); 547 + } 543 548 if (!rc) { 544 549 clear_nlink(d_inode(dentry)); 545 - fsstack_copy_attr_times(dir, lower_dir_inode); 546 - set_nlink(dir, lower_dir_inode->i_nlink); 550 + fsstack_copy_attr_times(dir, lower_dir); 551 + set_nlink(dir, lower_dir->i_nlink); 547 552 } 548 553 dput(lower_dentry); 549 - inode_unlock(lower_dir_inode); 554 + inode_unlock(lower_dir); 550 555 if (!rc) 551 556 d_drop(dentry); 552 557 return rc; ··· 553 568 { 554 569 int rc; 555 570 struct dentry *lower_dentry; 556 - struct dentry *lower_dir_dentry; 571 + struct inode *lower_dir; 557 572 558 - lower_dentry = ecryptfs_dentry_to_lower(dentry); 559 - lower_dir_dentry = lock_parent(lower_dentry); 560 - rc = vfs_mknod(&init_user_ns, d_inode(lower_dir_dentry), lower_dentry, 561 - mode, dev); 573 + rc = lock_parent(dentry, &lower_dentry, &lower_dir); 574 + if (!rc) 575 + rc = vfs_mknod(&init_user_ns, lower_dir, 576 + lower_dentry, mode, dev); 562 577 if (rc || d_really_is_negative(lower_dentry)) 563 578 goto out; 564 579 rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); 565 580 if (rc) 566 581 goto out; 567 - fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); 568 - fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry)); 582 + fsstack_copy_attr_times(dir, lower_dir); 583 + fsstack_copy_inode_size(dir, lower_dir); 569 584 out: 570 - unlock_dir(lower_dir_dentry); 585 + inode_unlock(lower_dir); 571 586 if (d_really_is_negative(dentry)) 572 587 d_drop(dentry); 573 588 return rc;