18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/** 38c2ecf20Sopenharmony_ci * eCryptfs: Linux filesystem encryption layer 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 1997-2003 Erez Zadok 68c2ecf20Sopenharmony_ci * Copyright (C) 2001-2003 Stony Brook University 78c2ecf20Sopenharmony_ci * Copyright (C) 2004-2006 International Business Machines Corp. 88c2ecf20Sopenharmony_ci * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/dcache.h> 128c2ecf20Sopenharmony_ci#include <linux/namei.h> 138c2ecf20Sopenharmony_ci#include <linux/mount.h> 148c2ecf20Sopenharmony_ci#include <linux/fs_stack.h> 158c2ecf20Sopenharmony_ci#include <linux/slab.h> 168c2ecf20Sopenharmony_ci#include "ecryptfs_kernel.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/** 198c2ecf20Sopenharmony_ci * ecryptfs_d_revalidate - revalidate an ecryptfs dentry 208c2ecf20Sopenharmony_ci * @dentry: The ecryptfs dentry 218c2ecf20Sopenharmony_ci * @flags: lookup flags 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * Called when the VFS needs to revalidate a dentry. This 248c2ecf20Sopenharmony_ci * is called whenever a name lookup finds a dentry in the 258c2ecf20Sopenharmony_ci * dcache. Most filesystems leave this as NULL, because all their 268c2ecf20Sopenharmony_ci * dentries in the dcache are valid. 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * Returns 1 if valid, 0 otherwise. 298c2ecf20Sopenharmony_ci * 308c2ecf20Sopenharmony_ci */ 318c2ecf20Sopenharmony_cistatic int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags) 328c2ecf20Sopenharmony_ci{ 338c2ecf20Sopenharmony_ci struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); 348c2ecf20Sopenharmony_ci int rc = 1; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci if (flags & LOOKUP_RCU) 378c2ecf20Sopenharmony_ci return -ECHILD; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci if (lower_dentry->d_flags & DCACHE_OP_REVALIDATE) 408c2ecf20Sopenharmony_ci rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci if (d_really_is_positive(dentry)) { 438c2ecf20Sopenharmony_ci struct inode *inode = d_inode(dentry); 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci fsstack_copy_attr_all(inode, ecryptfs_inode_to_lower(inode)); 468c2ecf20Sopenharmony_ci if (!inode->i_nlink) 478c2ecf20Sopenharmony_ci return 0; 488c2ecf20Sopenharmony_ci } 498c2ecf20Sopenharmony_ci return rc; 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistruct kmem_cache *ecryptfs_dentry_info_cache; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic void ecryptfs_dentry_free_rcu(struct rcu_head *head) 558c2ecf20Sopenharmony_ci{ 568c2ecf20Sopenharmony_ci kmem_cache_free(ecryptfs_dentry_info_cache, 578c2ecf20Sopenharmony_ci container_of(head, struct ecryptfs_dentry_info, rcu)); 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci/** 618c2ecf20Sopenharmony_ci * ecryptfs_d_release 628c2ecf20Sopenharmony_ci * @dentry: The ecryptfs dentry 638c2ecf20Sopenharmony_ci * 648c2ecf20Sopenharmony_ci * Called when a dentry is really deallocated. 658c2ecf20Sopenharmony_ci */ 668c2ecf20Sopenharmony_cistatic void ecryptfs_d_release(struct dentry *dentry) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci struct ecryptfs_dentry_info *p = dentry->d_fsdata; 698c2ecf20Sopenharmony_ci if (p) { 708c2ecf20Sopenharmony_ci path_put(&p->lower_path); 718c2ecf20Sopenharmony_ci call_rcu(&p->rcu, ecryptfs_dentry_free_rcu); 728c2ecf20Sopenharmony_ci } 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ciconst struct dentry_operations ecryptfs_dops = { 768c2ecf20Sopenharmony_ci .d_revalidate = ecryptfs_d_revalidate, 778c2ecf20Sopenharmony_ci .d_release = ecryptfs_d_release, 788c2ecf20Sopenharmony_ci}; 79