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

ecryptfs: get rid of pointless mount references in ecryptfs dentries

->lower_path.mnt has the same value for all dentries on given ecryptfs
instance and if somebody goes for mountpoint-crossing variant where that
would not be true, we can deal with that when it happens (and _not_
with duplicating these reference into each dentry).

As it is, we are better off just sticking a reference into ecryptfs-private
part of superblock and keeping it pinned until ->kill_sb().

That way we can stick a reference to underlying dentry right into ->d_fsdata
of ecryptfs one, getting rid of indirection through struct ecryptfs_dentry_info,
along with the entire struct ecryptfs_dentry_info machinery.

[kudos to Dan Carpenter for spotting a bug in ecryptfs_get_tree() part]

Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro fc812c40 75db7fd9

+30 -69
+1 -13
fs/ecryptfs/dentry.c
··· 59 59 return rc; 60 60 } 61 61 62 - struct kmem_cache *ecryptfs_dentry_info_cache; 63 - 64 - static void ecryptfs_dentry_free_rcu(struct rcu_head *head) 65 - { 66 - kmem_cache_free(ecryptfs_dentry_info_cache, 67 - container_of(head, struct ecryptfs_dentry_info, rcu)); 68 - } 69 - 70 62 /** 71 63 * ecryptfs_d_release 72 64 * @dentry: The ecryptfs dentry ··· 67 75 */ 68 76 static void ecryptfs_d_release(struct dentry *dentry) 69 77 { 70 - struct ecryptfs_dentry_info *p = dentry->d_fsdata; 71 - if (p) { 72 - path_put(&p->lower_path); 73 - call_rcu(&p->rcu, ecryptfs_dentry_free_rcu); 74 - } 78 + dput(dentry->d_fsdata); 75 79 } 76 80 77 81 const struct dentry_operations ecryptfs_dops = {
+11 -16
fs/ecryptfs/ecryptfs_kernel.h
··· 258 258 struct ecryptfs_crypt_stat crypt_stat; 259 259 }; 260 260 261 - /* dentry private data. Each dentry must keep track of a lower 262 - * vfsmount too. */ 263 - struct ecryptfs_dentry_info { 264 - struct path lower_path; 265 - struct rcu_head rcu; 266 - }; 267 - 268 261 /** 269 262 * ecryptfs_global_auth_tok - A key used to encrypt all new files under the mountpoint 270 263 * @flags: Status flags ··· 341 348 /* superblock private data. */ 342 349 struct ecryptfs_sb_info { 343 350 struct super_block *wsi_sb; 351 + struct vfsmount *lower_mnt; 344 352 struct ecryptfs_mount_crypt_stat mount_crypt_stat; 345 353 }; 346 354 ··· 488 494 } 489 495 490 496 static inline void 491 - ecryptfs_set_dentry_private(struct dentry *dentry, 492 - struct ecryptfs_dentry_info *dentry_info) 497 + ecryptfs_set_dentry_lower(struct dentry *dentry, 498 + struct dentry *lower_dentry) 493 499 { 494 - dentry->d_fsdata = dentry_info; 500 + dentry->d_fsdata = lower_dentry; 495 501 } 496 502 497 503 static inline struct dentry * 498 504 ecryptfs_dentry_to_lower(struct dentry *dentry) 499 505 { 500 - return ((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path.dentry; 506 + return dentry->d_fsdata; 501 507 } 502 508 503 - static inline const struct path * 504 - ecryptfs_dentry_to_lower_path(struct dentry *dentry) 509 + static inline struct path 510 + ecryptfs_lower_path(struct dentry *dentry) 505 511 { 506 - return &((struct ecryptfs_dentry_info *)dentry->d_fsdata)->lower_path; 512 + return (struct path){ 513 + .mnt = ecryptfs_superblock_to_private(dentry->d_sb)->lower_mnt, 514 + .dentry = ecryptfs_dentry_to_lower(dentry) 515 + }; 507 516 } 508 517 509 518 #define ecryptfs_printk(type, fmt, arg...) \ ··· 529 532 530 533 extern struct kmem_cache *ecryptfs_auth_tok_list_item_cache; 531 534 extern struct kmem_cache *ecryptfs_file_info_cache; 532 - extern struct kmem_cache *ecryptfs_dentry_info_cache; 533 535 extern struct kmem_cache *ecryptfs_inode_info_cache; 534 536 extern struct kmem_cache *ecryptfs_sb_info_cache; 535 537 extern struct kmem_cache *ecryptfs_header_cache; ··· 553 557 size_t *encoded_name_size, 554 558 struct ecryptfs_mount_crypt_stat *mount_crypt_stat, 555 559 const char *name, size_t name_size); 556 - struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry); 557 560 void ecryptfs_dump_hex(char *data, int bytes); 558 561 int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg, 559 562 int sg_size);
+7 -8
fs/ecryptfs/file.c
··· 33 33 struct iov_iter *to) 34 34 { 35 35 ssize_t rc; 36 - const struct path *path; 37 36 struct file *file = iocb->ki_filp; 38 37 39 38 rc = generic_file_read_iter(iocb, to); 40 39 if (rc >= 0) { 41 - path = ecryptfs_dentry_to_lower_path(file->f_path.dentry); 42 - touch_atime(path); 40 + struct path path = ecryptfs_lower_path(file->f_path.dentry); 41 + touch_atime(&path); 43 42 } 44 43 return rc; 45 44 } ··· 58 59 size_t len, unsigned int flags) 59 60 { 60 61 ssize_t rc; 61 - const struct path *path; 62 62 63 63 rc = filemap_splice_read(in, ppos, pipe, len, flags); 64 64 if (rc >= 0) { 65 - path = ecryptfs_dentry_to_lower_path(in->f_path.dentry); 66 - touch_atime(path); 65 + struct path path = ecryptfs_lower_path(in->f_path.dentry); 66 + touch_atime(&path); 67 67 } 68 68 return rc; 69 69 } ··· 281 283 * ecryptfs_lookup() */ 282 284 struct ecryptfs_file_info *file_info; 283 285 struct file *lower_file; 286 + struct path path; 284 287 285 288 /* Released in ecryptfs_release or end of function if failure */ 286 289 file_info = kmem_cache_zalloc(ecryptfs_file_info_cache, GFP_KERNEL); ··· 291 292 "Error attempting to allocate memory\n"); 292 293 return -ENOMEM; 293 294 } 294 - lower_file = dentry_open(ecryptfs_dentry_to_lower_path(ecryptfs_dentry), 295 - file->f_flags, current_cred()); 295 + path = ecryptfs_lower_path(ecryptfs_dentry); 296 + lower_file = dentry_open(&path, file->f_flags, current_cred()); 296 297 if (IS_ERR(lower_file)) { 297 298 printk(KERN_ERR "%s: Error attempting to initialize " 298 299 "the lower file for the dentry with name "
+5 -14
fs/ecryptfs/inode.c
··· 327 327 static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry, 328 328 struct dentry *lower_dentry) 329 329 { 330 - const struct path *path = ecryptfs_dentry_to_lower_path(dentry->d_parent); 330 + struct dentry *lower_parent = ecryptfs_dentry_to_lower(dentry->d_parent); 331 331 struct inode *inode, *lower_inode; 332 - struct ecryptfs_dentry_info *dentry_info; 333 332 int rc = 0; 334 333 335 - dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL); 336 - if (!dentry_info) { 337 - dput(lower_dentry); 338 - return ERR_PTR(-ENOMEM); 339 - } 340 - 341 334 fsstack_copy_attr_atime(d_inode(dentry->d_parent), 342 - d_inode(path->dentry)); 335 + d_inode(lower_parent)); 343 336 BUG_ON(!d_count(lower_dentry)); 344 337 345 - ecryptfs_set_dentry_private(dentry, dentry_info); 346 - dentry_info->lower_path.mnt = mntget(path->mnt); 347 - dentry_info->lower_path.dentry = lower_dentry; 338 + ecryptfs_set_dentry_lower(dentry, lower_dentry); 348 339 349 340 /* 350 341 * negative dentry can go positive under us here - its parent is not ··· 1013 1022 { 1014 1023 struct dentry *dentry = path->dentry; 1015 1024 struct kstat lower_stat; 1025 + struct path lower_path = ecryptfs_lower_path(dentry); 1016 1026 int rc; 1017 1027 1018 - rc = vfs_getattr_nosec(ecryptfs_dentry_to_lower_path(dentry), 1019 - &lower_stat, request_mask, flags); 1028 + rc = vfs_getattr_nosec(&lower_path, &lower_stat, request_mask, flags); 1020 1029 if (!rc) { 1021 1030 fsstack_copy_attr_all(d_inode(dentry), 1022 1031 ecryptfs_inode_to_lower(d_inode(dentry)));
+6 -18
fs/ecryptfs/main.c
··· 106 106 struct file **lower_file) 107 107 { 108 108 const struct cred *cred = current_cred(); 109 - const struct path *path = ecryptfs_dentry_to_lower_path(dentry); 109 + struct path path = ecryptfs_lower_path(dentry); 110 110 int rc; 111 111 112 - rc = ecryptfs_privileged_open(lower_file, path->dentry, path->mnt, 113 - cred); 112 + rc = ecryptfs_privileged_open(lower_file, path.dentry, path.mnt, cred); 114 113 if (rc) { 115 114 printk(KERN_ERR "Error opening lower file " 116 115 "for lower_dentry [0x%p] and lower_mnt [0x%p]; " 117 - "rc = [%d]\n", path->dentry, path->mnt, rc); 116 + "rc = [%d]\n", path.dentry, path.mnt, rc); 118 117 (*lower_file) = NULL; 119 118 } 120 119 return rc; ··· 436 437 struct ecryptfs_fs_context *ctx = fc->fs_private; 437 438 struct ecryptfs_sb_info *sbi = fc->s_fs_info; 438 439 struct ecryptfs_mount_crypt_stat *mount_crypt_stat; 439 - struct ecryptfs_dentry_info *root_info; 440 440 const char *err = "Getting sb failed"; 441 441 struct inode *inode; 442 442 struct path path; ··· 541 543 goto out_free; 542 544 } 543 545 544 - rc = -ENOMEM; 545 - root_info = kmem_cache_zalloc(ecryptfs_dentry_info_cache, GFP_KERNEL); 546 - if (!root_info) 547 - goto out_free; 548 - 549 - /* ->kill_sb() will take care of root_info */ 550 - ecryptfs_set_dentry_private(s->s_root, root_info); 551 - root_info->lower_path = path; 546 + ecryptfs_set_dentry_lower(s->s_root, path.dentry); 547 + ecryptfs_superblock_to_private(s)->lower_mnt = path.mnt; 552 548 553 549 s->s_flags |= SB_ACTIVE; 554 550 fc->root = dget(s->s_root); ··· 572 580 kill_anon_super(sb); 573 581 if (!sb_info) 574 582 return; 583 + mntput(sb_info->lower_mnt); 575 584 ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); 576 585 kmem_cache_free(ecryptfs_sb_info_cache, sb_info); 577 586 } ··· 659 666 .cache = &ecryptfs_file_info_cache, 660 667 .name = "ecryptfs_file_cache", 661 668 .size = sizeof(struct ecryptfs_file_info), 662 - }, 663 - { 664 - .cache = &ecryptfs_dentry_info_cache, 665 - .name = "ecryptfs_dentry_info_cache", 666 - .size = sizeof(struct ecryptfs_dentry_info), 667 669 }, 668 670 { 669 671 .cache = &ecryptfs_inode_info_cache,