diff options
Diffstat (limited to 'fs/ecryptfs/main.c')
-rw-r--r-- | fs/ecryptfs/main.c | 65 |
1 files changed, 56 insertions, 9 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 4f4d0474bee9..b591e6772f1b 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -156,16 +156,42 @@ int ecryptfs_get_lower_file(struct dentry *dentry, struct inode *inode) void ecryptfs_put_lower_file(struct inode *inode) { + int ret = 0; struct ecryptfs_inode_info *inode_info; + bool clear_cache_needed = false; inode_info = ecryptfs_inode_to_private(inode); if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, &inode_info->lower_file_mutex)) { + + if (get_events() && get_events()->is_hw_crypt_cb && + get_events()->is_hw_crypt_cb()) + clear_cache_needed = true; + + if (clear_cache_needed) { + ret = vfs_fsync(inode_info->lower_file, false); + + if (ret) + pr_err("failed to sync file ret = %d.\n", ret); + } + filemap_write_and_wait(inode->i_mapping); fput(inode_info->lower_file); inode_info->lower_file = NULL; mutex_unlock(&inode_info->lower_file_mutex); + + if (clear_cache_needed) { + truncate_inode_pages_fill_zero(inode->i_mapping, 0); + truncate_inode_pages_fill_zero( + ecryptfs_inode_to_lower(inode)->i_mapping, 0); + } + + if (get_events() && get_events()->release_cb) + get_events()->release_cb( + ecryptfs_inode_to_lower(inode)); } + + } enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, @@ -280,6 +306,7 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, char *cipher_key_bytes_src; char *fn_cipher_key_bytes_src; u8 cipher_code; + unsigned char final[2*ECRYPTFS_MAX_CIPHER_NAME_SIZE+1]; *check_ruid = 0; @@ -309,12 +336,14 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, case ecryptfs_opt_ecryptfs_cipher: cipher_name_src = args[0].from; cipher_name_dst = - mount_crypt_stat-> - global_default_cipher_name; - strncpy(cipher_name_dst, cipher_name_src, - ECRYPTFS_MAX_CIPHER_NAME_SIZE); - cipher_name_dst[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; + mount_crypt_stat->global_default_cipher_name; + + ecryptfs_parse_full_cipher(cipher_name_src, + mount_crypt_stat->global_default_cipher_name, + mount_crypt_stat->global_default_cipher_mode); + cipher_name_set = 1; + break; case ecryptfs_opt_ecryptfs_key_bytes: cipher_key_bytes_src = args[0].from; @@ -411,24 +440,35 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, strcpy(mount_crypt_stat->global_default_cipher_name, ECRYPTFS_DEFAULT_CIPHER); } + if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) && !fn_cipher_name_set) strcpy(mount_crypt_stat->global_default_fn_cipher_name, mount_crypt_stat->global_default_cipher_name); + if (!cipher_key_bytes_set) mount_crypt_stat->global_default_cipher_key_size = 0; + if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) && !fn_cipher_key_bytes_set) mount_crypt_stat->global_default_fn_cipher_key_bytes = mount_crypt_stat->global_default_cipher_key_size; cipher_code = ecryptfs_code_for_cipher_string( - mount_crypt_stat->global_default_cipher_name, + ecryptfs_get_full_cipher( + mount_crypt_stat->global_default_cipher_name, + mount_crypt_stat->global_default_cipher_mode, + final, sizeof(final)), mount_crypt_stat->global_default_cipher_key_size); if (!cipher_code) { - ecryptfs_printk(KERN_ERR, - "eCryptfs doesn't support cipher: %s", - mount_crypt_stat->global_default_cipher_name); + ecryptfs_printk( + KERN_ERR, + "eCryptfs doesn't support cipher: %s and key size %zu", + ecryptfs_get_full_cipher( + mount_crypt_stat->global_default_cipher_name, + mount_crypt_stat->global_default_cipher_mode, + final, sizeof(final)), + mount_crypt_stat->global_default_cipher_key_size); rc = -EINVAL; goto out; } @@ -488,6 +528,7 @@ static struct file_system_type ecryptfs_fs_type; * @dev_name: The path to mount over * @raw_data: The options passed into the kernel */ + static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data) { @@ -557,6 +598,11 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags ecryptfs_set_superblock_lower(s, path.dentry->d_sb); + + if (get_events() && get_events()->is_hw_crypt_cb && + get_events()->is_hw_crypt_cb()) + drop_pagecache_sb(ecryptfs_superblock_to_lower(s), 0); + /** * Set the POSIX ACL flag based on whether they're enabled in the lower * mount. @@ -895,6 +941,7 @@ static void __exit ecryptfs_exit(void) do_sysfs_unregistration(); unregister_filesystem(&ecryptfs_fs_type); ecryptfs_free_kmem_caches(); + ecryptfs_free_events(); } MODULE_AUTHOR("Michael A. Halcrow <mhalcrow@us.ibm.com>"); |