2006-10-04 13:16:22 +04:00
/**
* eCryptfs : Linux filesystem encryption layer
*
* Copyright ( C ) 1997 - 2003 Erez Zadok
* Copyright ( C ) 2001 - 2003 Stony Brook University
* Copyright ( C ) 2004 - 2006 International Business Machines Corp .
* Author ( s ) : Michael A . Halcrow < mahalcro @ us . ibm . com >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation ; either version 2 of the
* License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA
* 02111 - 1307 , USA .
*/
# include <linux/dcache.h>
# include <linux/namei.h>
2006-10-31 09:07:20 +03:00
# include <linux/mount.h>
2006-12-08 13:36:31 +03:00
# include <linux/fs_stack.h>
2006-10-04 13:16:22 +04:00
# include "ecryptfs_kernel.h"
/**
* ecryptfs_d_revalidate - revalidate an ecryptfs dentry
* @ dentry : The ecryptfs dentry
* @ nd : The associated nameidata
*
* Called when the VFS needs to revalidate a dentry . This
* is called whenever a name lookup finds a dentry in the
* dcache . Most filesystems leave this as NULL , because all their
* dentries in the dcache are valid .
*
* Returns 1 if valid , 0 otherwise .
*
*/
static int ecryptfs_d_revalidate ( struct dentry * dentry , struct nameidata * nd )
{
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 ;
if ( ! lower_dentry - > d_op | | ! lower_dentry - > d_op - > d_revalidate )
goto out ;
2008-02-15 06:34:32 +03:00
dentry_save = nd - > path . dentry ;
vfsmount_save = nd - > path . mnt ;
nd - > path . dentry = lower_dentry ;
nd - > path . mnt = lower_mnt ;
2006-10-04 13:16:22 +04:00
rc = lower_dentry - > d_op - > d_revalidate ( lower_dentry , nd ) ;
2008-02-15 06:34:32 +03:00
nd - > path . dentry = dentry_save ;
nd - > path . mnt = vfsmount_save ;
2006-11-16 12:19:30 +03:00
if ( dentry - > d_inode ) {
struct inode * lower_inode =
ecryptfs_inode_to_lower ( dentry - > d_inode ) ;
2006-12-08 13:36:31 +03:00
fsstack_copy_attr_all ( dentry - > d_inode , lower_inode , NULL ) ;
2006-11-16 12:19:30 +03:00
}
2006-10-04 13:16:22 +04:00
out :
return rc ;
}
struct kmem_cache * ecryptfs_dentry_info_cache ;
/**
* ecryptfs_d_release
* @ dentry : The ecryptfs dentry
*
* Called when a dentry is really deallocated .
*/
static void ecryptfs_d_release ( struct dentry * dentry )
{
2007-03-17 00:38:22 +03:00
if ( ecryptfs_dentry_to_private ( dentry ) ) {
if ( ecryptfs_dentry_to_lower ( dentry ) ) {
mntput ( ecryptfs_dentry_to_lower_mnt ( dentry ) ) ;
dput ( ecryptfs_dentry_to_lower ( dentry ) ) ;
}
2006-10-04 13:16:22 +04:00
kmem_cache_free ( ecryptfs_dentry_info_cache ,
ecryptfs_dentry_to_private ( dentry ) ) ;
2006-10-31 09:07:20 +03:00
}
2006-10-04 13:16:22 +04:00
return ;
}
struct dentry_operations ecryptfs_dops = {
. d_revalidate = ecryptfs_d_revalidate ,
. d_release = ecryptfs_d_release ,
} ;