@ -141,21 +141,9 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
return rc ;
}
/**
* ecryptfs_interpose
* @ lower_dentry : Existing dentry in the lower filesystem
* @ dentry : ecryptfs ' dentry
* @ sb : ecryptfs ' s super_block
* @ flags : flags to govern behavior of interpose procedure
*
* Interposes upper and lower dentries .
*
* Returns zero on success ; non - zero otherwise
*/
int ecryptfs_interpose ( struct dentry * lower_dentry , struct dentry * dentry ,
struct super_block * sb , u32 flags )
static inode * ecryptfs_get_inode ( struct inode * lower_inode ,
struct super_block * sb )
{
struct inode * lower_inode ;
struct inode * inode ;
int rc = 0 ;
@ -189,17 +177,38 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
if ( special_file ( lower_inode - > i_mode ) )
init_special_inode ( inode , lower_inode - > i_mode ,
lower_inode - > i_rdev ) ;
d_set_d_op ( dentry , & ecryptfs_dops ) ;
fsstack_copy_attr_all ( inode , lower_inode ) ;
/* This size will be overwritten for real files w/ headers and
* other metadata */
fsstack_copy_inode_size ( inode , lower_inode ) ;
return inode ;
out :
return ERR_PTR ( rc ) ;
}
/**
* ecryptfs_interpose
* @ lower_dentry : Existing dentry in the lower filesystem
* @ dentry : ecryptfs ' dentry
* @ sb : ecryptfs ' s super_block
* @ flags : flags to govern behavior of interpose procedure
*
* Interposes upper and lower dentries .
*
* Returns zero on success ; non - zero otherwise
*/
int ecryptfs_interpose ( struct dentry * lower_dentry , struct dentry * dentry ,
struct super_block * sb , u32 flags )
{
struct inode * lower_inode = lower_dentry - > d_inode ;
struct inode * inode = ecryptfs_get_inode ( lower_inode , sb ) ;
if ( IS_ERR ( inode )
return PTR_ERR ( inode ) ;
if ( flags & ECRYPTFS_INTERPOSE_FLAG_D_ADD )
d_add ( dentry , inode ) ;
else
d_instantiate ( dentry , inode ) ;
out :
return rc ;
return 0 ;
}
enum { ecryptfs_opt_sig , ecryptfs_opt_ecryptfs_sig ,
@ -491,60 +500,12 @@ out:
struct kmem_cache * ecryptfs_sb_info_cache ;
static struct file_system_type ecryptfs_fs_type ;
/**
* ecryptfs_read_super
* @ sb : The ecryptfs super block
* @ dev_name : The path to mount over
*
* Read the super block of the lower filesystem , and use
* ecryptfs_interpose to create our initial inode and super block
* struct .
*/
static int ecryptfs_read_super ( struct super_block * sb , const char * dev_name )
{
struct path path ;
int rc ;
rc = kern_path ( dev_name , LOOKUP_FOLLOW | LOOKUP_DIRECTORY , & path ) ;
if ( rc ) {
ecryptfs_printk ( KERN_WARNING , " path_lookup() failed \n " ) ;
goto out ;
}
if ( path . dentry - > d_sb - > s_type = = & ecryptfs_fs_type ) {
rc = - EINVAL ;
printk ( KERN_ERR " Mount on filesystem of type "
" eCryptfs explicitly disallowed due to "
" known incompatibilities \n " ) ;
goto out_free ;
}
ecryptfs_set_superblock_lower ( sb , path . dentry - > d_sb ) ;
sb - > s_maxbytes = path . dentry - > d_sb - > s_maxbytes ;
sb - > s_blocksize = path . dentry - > d_sb - > s_blocksize ;
ecryptfs_set_dentry_lower ( sb - > s_root , path . dentry ) ;
ecryptfs_set_dentry_lower_mnt ( sb - > s_root , path . mnt ) ;
rc = ecryptfs_interpose ( path . dentry , sb - > s_root , sb , 0 ) ;
if ( rc )
goto out_free ;
rc = 0 ;
goto out ;
out_free :
path_put ( & path ) ;
out :
return rc ;
}
/**
* ecryptfs_get_sb
* @ fs_type
* @ flags
* @ dev_name : The path to mount over
* @ raw_data : The options passed into the kernel
*
* The whole ecryptfs_get_sb process is broken into 3 functions :
* ecryptfs_parse_options ( ) : handle options passed to ecryptfs , if any
* ecryptfs_read_super ( ) : this accesses the lower filesystem and uses
* ecryptfs_interpose to perform most of the linking
* ecryptfs_interpose ( ) : links the lower filesystem into ecryptfs ( inode . c )
*/
static struct dentry * ecryptfs_mount ( struct file_system_type * fs_type , int flags ,
const char * dev_name , void * raw_data )
@ -553,6 +514,8 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
struct ecryptfs_sb_info * sbi ;
struct ecryptfs_dentry_info * root_info ;
const char * err = " Getting sb failed " ;
struct inode * inode ;
struct path path ;
int rc ;
sbi = kmem_cache_zalloc ( ecryptfs_sb_info_cache , GFP_KERNEL ) ;
@ -575,10 +538,8 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
s - > s_flags = flags ;
rc = bdi_setup_and_register ( & sbi - > bdi , " ecryptfs " , BDI_CAP_MAP_COPY ) ;
if ( rc ) {
deactivate_locked_super ( s ) ;
goto out ;
}
if ( rc )
goto out1 ;
ecryptfs_set_superblock_private ( s , sbi ) ;
s - > s_bdi = & sbi - > bdi ;
@ -586,34 +547,54 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
/* ->kill_sb() will take care of sbi after that point */
sbi = NULL ;
s - > s_op = & ecryptfs_sops ;
s - > s_d_op = & ecryptfs_dops ;
rc = - ENOMEM ;
s - > s_root = d_alloc ( NULL , & ( const struct qstr ) {
. hash = 0 , . name = " / " , . len = 1 } ) ;
err = " Reading sb failed " ;
rc = kern_path ( dev_name , LOOKUP_FOLLOW | LOOKUP_DIRECTORY , & path ) ;
if ( rc ) {
ecryptfs_printk ( KERN_WARNING , " kern_path() failed \n " ) ;
goto out1 ;
}
if ( path . dentry - > d_sb - > s_type = = & ecryptfs_fs_type ) {
rc = - EINVAL ;
printk ( KERN_ERR " Mount on filesystem of type "
" eCryptfs explicitly disallowed due to "
" known incompatibilities \n " ) ;
goto out_free ;
}
ecryptfs_set_superblock_lower ( s , path . dentry - > d_sb ) ;
s - > s_maxbytes = path . dentry - > d_sb - > s_maxbytes ;
s - > s_blocksize = path . dentry - > d_sb - > s_blocksize ;
inode = ecryptfs_get_inode ( path . dentry - > d_inode , s ) ;
rc = PTR_ERR ( inode ) ;
if ( IS_ERR ( inode ) )
goto out_free ;
s - > s_root = d_alloc_root ( inode ) ;
if ( ! s - > s_root ) {
deactivate_locked_super ( s ) ;
goto out ;
iput ( inode ) ;
rc = - ENOMEM ;
goto out_free ;
}
d_set_d_op ( s - > s_root , & ecryptfs_dops ) ;
s - > s_root - > d_sb = s ;
s - > s_root - > d_parent = s - > s_root ;
rc = - ENOMEM ;
root_info = kmem_cache_zalloc ( ecryptfs_dentry_info_cache , GFP_KERNEL ) ;
if ( ! root_info ) {
deactivate_locked_super ( s ) ;
goto out ;
}
if ( ! root_info )
goto out_free ;
/* ->kill_sb() will take care of root_info */
ecryptfs_set_dentry_private ( s - > s_root , root_info ) ;
ecryptfs_set_dentry_lower ( s - > s_root , path . dentry ) ;
ecryptfs_set_dentry_lower_mnt ( s - > s_root , path . mnt ) ;
s - > s_flags | = MS_ACTIVE ;
rc = ecryptfs_read_super ( s , dev_name ) ;
if ( rc ) {
deactivate_locked_super ( s ) ;
err = " Reading sb failed " ;
goto out ;
}
return dget ( s - > s_root ) ;
out_free :
path_put ( & path ) ;
out1 :
deactivate_locked_super ( s ) ;
out :
if ( sbi ) {
ecryptfs_destroy_mount_crypt_stat ( & sbi - > mount_crypt_stat ) ;