diff options
Diffstat (limited to 'fs/ecryptfs/dentry.c')
| -rw-r--r-- | fs/ecryptfs/dentry.c | 44 | 
1 files changed, 20 insertions, 24 deletions
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index 906e803f7f7..4000f6b3a75 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c @@ -32,7 +32,7 @@  /**   * ecryptfs_d_revalidate - revalidate an ecryptfs dentry   * @dentry: The ecryptfs dentry - * @nd: The associated nameidata + * @flags: lookup flags   *   * Called when the VFS needs to revalidate a dentry. This   * is called whenever a name lookup finds a dentry in the @@ -42,35 +42,35 @@   * Returns 1 if valid, 0 otherwise.   *   */ -static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) +static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags)  {  	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); -	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); -	struct dentry *dentry_save; -	struct vfsmount *vfsmount_save; -	int rc = 1; +	int rc; -	if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate) -		goto out; -	dentry_save = nd->path.dentry; -	vfsmount_save = nd->path.mnt; -	nd->path.dentry = lower_dentry; -	nd->path.mnt = lower_mnt; -	rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); -	nd->path.dentry = dentry_save; -	nd->path.mnt = vfsmount_save; +	if (!(lower_dentry->d_flags & DCACHE_OP_REVALIDATE)) +		return 1; + +	if (flags & LOOKUP_RCU) +		return -ECHILD; + +	rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags);  	if (dentry->d_inode) {  		struct inode *lower_inode =  			ecryptfs_inode_to_lower(dentry->d_inode);  		fsstack_copy_attr_all(dentry->d_inode, lower_inode);  	} -out:  	return rc;  }  struct kmem_cache *ecryptfs_dentry_info_cache; +static void ecryptfs_dentry_free_rcu(struct rcu_head *head) +{ +	kmem_cache_free(ecryptfs_dentry_info_cache, +		container_of(head, struct ecryptfs_dentry_info, rcu)); +} +  /**   * ecryptfs_d_release   * @dentry: The ecryptfs dentry @@ -79,15 +79,11 @@ struct kmem_cache *ecryptfs_dentry_info_cache;   */  static void ecryptfs_d_release(struct dentry *dentry)  { -	if (ecryptfs_dentry_to_private(dentry)) { -		if (ecryptfs_dentry_to_lower(dentry)) { -			dput(ecryptfs_dentry_to_lower(dentry)); -			mntput(ecryptfs_dentry_to_lower_mnt(dentry)); -		} -		kmem_cache_free(ecryptfs_dentry_info_cache, -				ecryptfs_dentry_to_private(dentry)); +	struct ecryptfs_dentry_info *p = dentry->d_fsdata; +	if (p) { +		path_put(&p->lower_path); +		call_rcu(&p->rcu, ecryptfs_dentry_free_rcu);  	} -	return;  }  const struct dentry_operations ecryptfs_dops = {  | 
