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 >
* Michael C . Thompson < mcthomps @ 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/fs.h>
# include <linux/mount.h>
# include <linux/key.h>
# include <linux/seq_file.h>
push BKL down into ->put_super
Move BKL into ->put_super from the only caller. A couple of
filesystems had trivial enough ->put_super (only kfree and NULLing of
s_fs_info + stuff in there) to not get any locking: coda, cramfs, efs,
hugetlbfs, omfs, qnx4, shmem, all others got the full treatment. Most
of them probably don't need it, but I'd rather sort that out individually.
Preferably after all the other BKL pushdowns in that area.
[AV: original used to move lock_super() down as well; these changes are
removed since we don't do lock_super() at all in generic_shutdown_super()
now]
[AV: fuse, btrfs and xfs are known to need no damn BKL, exempt]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2009-05-05 17:40:36 +04:00
# include <linux/smp_lock.h>
2007-10-16 12:28:09 +04:00
# include <linux/file.h>
2006-10-04 13:16:22 +04:00
# include <linux/crypto.h>
# include "ecryptfs_kernel.h"
struct kmem_cache * ecryptfs_inode_info_cache ;
/**
* ecryptfs_alloc_inode - allocate an ecryptfs inode
* @ sb : Pointer to the ecryptfs super block
*
* Called to bring an inode into existence .
*
* Only handle allocation , setting up structures should be done in
* ecryptfs_read_inode . This is because the kernel , between now and
* then , will 0 out the private data pointer .
*
* Returns a pointer to a newly allocated inode , NULL otherwise
*/
static struct inode * ecryptfs_alloc_inode ( struct super_block * sb )
{
2007-10-16 12:28:12 +04:00
struct ecryptfs_inode_info * inode_info ;
2006-10-04 13:16:22 +04:00
struct inode * inode = NULL ;
2007-10-16 12:28:12 +04:00
inode_info = kmem_cache_alloc ( ecryptfs_inode_info_cache , GFP_KERNEL ) ;
if ( unlikely ( ! inode_info ) )
2006-10-04 13:16:22 +04:00
goto out ;
2007-10-16 12:28:12 +04:00
ecryptfs_init_crypt_stat ( & inode_info - > crypt_stat ) ;
mutex_init ( & inode_info - > lower_file_mutex ) ;
inode_info - > lower_file = NULL ;
inode = & inode_info - > vfs_inode ;
2006-10-04 13:16:22 +04:00
out :
return inode ;
}
/**
* ecryptfs_destroy_inode
* @ inode : The ecryptfs inode
*
2007-10-16 12:28:09 +04:00
* This is used during the final destruction of the inode . All
* allocation of memory related to the inode , including allocated
* memory in the crypt_stat struct , will be released here . This
* function also fput ( ) ' s the persistent file for the lower inode .
2006-10-04 13:16:22 +04:00
* There should be no chance that this deallocation will be missed .
*/
static void ecryptfs_destroy_inode ( struct inode * inode )
{
struct ecryptfs_inode_info * inode_info ;
inode_info = ecryptfs_inode_to_private ( inode ) ;
2007-10-16 12:28:09 +04:00
mutex_lock ( & inode_info - > lower_file_mutex ) ;
if ( inode_info - > lower_file ) {
struct dentry * lower_dentry =
inode_info - > lower_file - > f_dentry ;
BUG_ON ( ! lower_dentry ) ;
if ( lower_dentry - > d_inode ) {
fput ( inode_info - > lower_file ) ;
inode_info - > lower_file = NULL ;
d_drop ( lower_dentry ) ;
}
}
mutex_unlock ( & inode_info - > lower_file_mutex ) ;
2007-10-16 12:28:01 +04:00
ecryptfs_destroy_crypt_stat ( & inode_info - > crypt_stat ) ;
2006-10-04 13:16:22 +04:00
kmem_cache_free ( ecryptfs_inode_info_cache , inode_info ) ;
}
/**
* ecryptfs_init_inode
* @ inode : The ecryptfs inode
*
* Set up the ecryptfs inode .
*/
void ecryptfs_init_inode ( struct inode * inode , struct inode * lower_inode )
{
ecryptfs_set_inode_lower ( inode , lower_inode ) ;
inode - > i_ino = lower_inode - > i_ino ;
inode - > i_version + + ;
inode - > i_op = & ecryptfs_main_iops ;
inode - > i_fop = & ecryptfs_main_fops ;
inode - > i_mapping - > a_ops = & ecryptfs_aops ;
}
/**
* ecryptfs_put_super
* @ sb : Pointer to the ecryptfs super block
*
* Final actions when unmounting a file system .
* This will handle deallocation and release of our private data .
*/
static void ecryptfs_put_super ( struct super_block * sb )
{
struct ecryptfs_sb_info * sb_info = ecryptfs_superblock_to_private ( sb ) ;
push BKL down into ->put_super
Move BKL into ->put_super from the only caller. A couple of
filesystems had trivial enough ->put_super (only kfree and NULLing of
s_fs_info + stuff in there) to not get any locking: coda, cramfs, efs,
hugetlbfs, omfs, qnx4, shmem, all others got the full treatment. Most
of them probably don't need it, but I'd rather sort that out individually.
Preferably after all the other BKL pushdowns in that area.
[AV: original used to move lock_super() down as well; these changes are
removed since we don't do lock_super() at all in generic_shutdown_super()
now]
[AV: fuse, btrfs and xfs are known to need no damn BKL, exempt]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2009-05-05 17:40:36 +04:00
lock_kernel ( ) ;
2007-10-16 12:28:01 +04:00
ecryptfs_destroy_mount_crypt_stat ( & sb_info - > mount_crypt_stat ) ;
2006-10-04 13:16:22 +04:00
kmem_cache_free ( ecryptfs_sb_info_cache , sb_info ) ;
ecryptfs_set_superblock_private ( sb , NULL ) ;
push BKL down into ->put_super
Move BKL into ->put_super from the only caller. A couple of
filesystems had trivial enough ->put_super (only kfree and NULLing of
s_fs_info + stuff in there) to not get any locking: coda, cramfs, efs,
hugetlbfs, omfs, qnx4, shmem, all others got the full treatment. Most
of them probably don't need it, but I'd rather sort that out individually.
Preferably after all the other BKL pushdowns in that area.
[AV: original used to move lock_super() down as well; these changes are
removed since we don't do lock_super() at all in generic_shutdown_super()
now]
[AV: fuse, btrfs and xfs are known to need no damn BKL, exempt]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2009-05-05 17:40:36 +04:00
unlock_kernel ( ) ;
2006-10-04 13:16:22 +04:00
}
/**
* ecryptfs_statfs
* @ sb : The ecryptfs super block
* @ buf : The struct kstatfs to fill in with stats
*
* Get the filesystem statistics . Currently , we let this pass right through
* to the lower filesystem and take no action ourselves .
*/
static int ecryptfs_statfs ( struct dentry * dentry , struct kstatfs * buf )
{
return vfs_statfs ( ecryptfs_dentry_to_lower ( dentry ) , buf ) ;
}
/**
* ecryptfs_clear_inode
* @ inode - The ecryptfs inode
*
* Called by iput ( ) when the inode reference count reached zero
* and the inode is not hashed anywhere . Used to clear anything
* that needs to be , before the inode is completely destroyed and put
* on the inode free list . We use this to drop out reference to the
* lower inode .
*/
static void ecryptfs_clear_inode ( struct inode * inode )
{
iput ( ecryptfs_inode_to_lower ( inode ) ) ;
}
/**
* ecryptfs_show_options
*
2008-02-06 12:38:34 +03:00
* Prints the mount options for a given superblock .
* Returns zero ; does not fail .
2006-10-04 13:16:22 +04:00
*/
static int ecryptfs_show_options ( struct seq_file * m , struct vfsmount * mnt )
{
struct super_block * sb = mnt - > mnt_sb ;
2008-02-06 12:38:34 +03:00
struct ecryptfs_mount_crypt_stat * mount_crypt_stat =
& ecryptfs_superblock_to_private ( sb ) - > mount_crypt_stat ;
struct ecryptfs_global_auth_tok * walker ;
mutex_lock ( & mount_crypt_stat - > global_auth_tok_list_mutex ) ;
list_for_each_entry ( walker ,
& mount_crypt_stat - > global_auth_tok_list ,
mount_crypt_stat_list ) {
2009-03-16 20:35:12 +03:00
if ( walker - > flags & ECRYPTFS_AUTH_TOK_FNEK )
seq_printf ( m , " ,ecryptfs_fnek_sig=%s " , walker - > sig ) ;
else
seq_printf ( m , " ,ecryptfs_sig=%s " , walker - > sig ) ;
2006-10-04 13:16:22 +04:00
}
2008-02-06 12:38:34 +03:00
mutex_unlock ( & mount_crypt_stat - > global_auth_tok_list_mutex ) ;
seq_printf ( m , " ,ecryptfs_cipher=%s " ,
mount_crypt_stat - > global_default_cipher_name ) ;
if ( mount_crypt_stat - > global_default_cipher_key_size )
seq_printf ( m , " ,ecryptfs_key_bytes=%zd " ,
mount_crypt_stat - > global_default_cipher_key_size ) ;
if ( mount_crypt_stat - > flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED )
seq_printf ( m , " ,ecryptfs_passthrough " ) ;
if ( mount_crypt_stat - > flags & ECRYPTFS_XATTR_METADATA_ENABLED )
seq_printf ( m , " ,ecryptfs_xattr_metadata " ) ;
if ( mount_crypt_stat - > flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED )
seq_printf ( m , " ,ecryptfs_encrypted_view " ) ;
2009-04-22 13:08:46 +04:00
if ( mount_crypt_stat - > flags & ECRYPTFS_UNLINK_SIGS )
seq_printf ( m , " ,ecryptfs_unlink_sigs " ) ;
2008-02-06 12:38:34 +03:00
return 0 ;
2006-10-04 13:16:22 +04:00
}
2007-02-12 11:55:41 +03:00
const struct super_operations ecryptfs_sops = {
2006-10-04 13:16:22 +04:00
. alloc_inode = ecryptfs_alloc_inode ,
. destroy_inode = ecryptfs_destroy_inode ,
. drop_inode = generic_delete_inode ,
. put_super = ecryptfs_put_super ,
. statfs = ecryptfs_statfs ,
. remount_fs = NULL ,
. clear_inode = ecryptfs_clear_inode ,
. show_options = ecryptfs_show_options
} ;